[libjogl2-java] 32/58: Imported Upstream version 2.0-rc11
Tony Mancill
tmancill at moszumanska.debian.org
Thu Sep 4 03:59:16 UTC 2014
This is an automated email from the git hooks/post-receive script.
tmancill pushed a commit to branch master
in repository libjogl2-java.
commit bc4be11d7517566bebe32d569be839b38764a4c0
Author: tony mancill <tmancill at debian.org>
Date: Fri Aug 29 18:44:51 2014 -0700
Imported Upstream version 2.0-rc11
---
doc/TODO.txt | 24 +-
doc/deployment/JOGL-DEPLOYMENT.html | 123 +-
doc/userguide/index.html | 9 +-
etc/test.sh | 2 +-
jnlp-files/jogl-all-awt-cg.jnlp | 12 +-
jnlp-files/jogl-all-awt.jnlp | 6 +-
jnlp-files/jogl-all-mobile.jnlp | 6 +-
jnlp-files/jogl-all-noawt.jnlp | 6 +-
.../jogl-applet-runner-newt-gears-gl3-napplet.html | 107 ++
jnlp-files/jogl-test-applets.html | 3 +-
make/build-common.xml | 19 +-
make/build-jogl.xml | 37 +-
make/build-nativewindow.xml | 15 +-
make/build-newt.xml | 113 +-
make/build-test.xml | 8 +-
make/build.xml | 2 +-
make/config/jogl/cgl-macosx.cfg | 4 +
make/config/jogl/cglext.cfg | 4 +
make/config/jogl/egl.cfg | 6 +-
make/config/jogl/eglext.cfg | 4 +
make/config/jogl/gl-common.cfg | 69 +-
make/config/jogl/gl-gl4bc.cfg | 10 +
.../config/jogl/gl-impl-CustomJavaCode-common.java | 20 +
make/config/jogl/gl2_es2-common.cfg | 10 -
make/config/jogl/glx-CustomCCode.c | 60 +-
make/config/jogl/glx-CustomJavaCode.java | 56 +-
make/config/jogl/glx-x11.cfg | 6 +-
make/config/jogl/glxext.cfg | 4 +
make/config/jogl/wgl-win32.cfg | 6 +-
make/config/jogl/wglext.cfg | 4 +
make/config/nativewindow/x11-CustomJavaCode.java | 5 +
make/scripts/adb-install-all-armv6.sh | 4 +
make/scripts/adb-launch-main.sh | 6 +-
make/scripts/adb-reinstall-all-armv6.sh | 5 +
make/scripts/java-win32-dbg.bat | 19 +-
make/scripts/java-win32.bat | 13 +-
make/scripts/java-win64-dbg.bat | 12 +-
make/scripts/java-win64.bat | 4 +-
make/scripts/lstjars.sh | 24 +-
make/scripts/make.jogl.all.android-armv6-cross.sh | 92 ++
...cross.sh => make.jogl.all.linux-armv6-cross.sh} | 12 +-
...linux-armv7.sh => make.jogl.all.linux-armv6.sh} | 10 +-
...oss.sh => make.jogl.all.linux-armv6hf-cross.sh} | 14 +-
make/scripts/make.jogl.all.linux-armv6hf.sh | 27 +
make/scripts/make.jogl.all.win32.bat | 4 +-
make/scripts/make.jogl.all.win64.bat | 6 +-
make/scripts/targetcommand-awt.sh | 12 +-
...{targetcommand-awt.sh => targetcommand-loop.sh} | 40 +-
make/scripts/targetcommand-newt.sh | 21 +-
make/scripts/tests-armv6_armel.sh | 7 +
make/scripts/tests-armv6_armhf.sh | 7 +
make/scripts/tests-armv7l_eabi.sh | 7 -
make/scripts/tests-javaws-x64.bat | 2 +-
make/scripts/tests-linux-armv6.sh | 7 +
make/scripts/tests-linux-armv6hf.sh | 7 +
make/scripts/tests-linux-armv7.sh | 7 -
make/scripts/tests-linux-armv7hf.sh | 7 -
make/scripts/tests-x32.bat | 9 +-
make/scripts/tests-x64.bat | 50 +-
make/scripts/tests.sh | 140 ++-
make/stub_includes/opengl/GL/glxext.h | 10 +
make/stub_includes/opengl/macosx-window-system.h | 13 +-
make/stub_includes/x11/window-lib.c | 5 +-
make/versions.xml | 2 +-
.../com/jogamp/graph/curve/opengl/RenderState.java | 6 +-
src/jogl/classes/com/jogamp/opengl/FBObject.java | 1298 +++++++++++++-------
src/jogl/classes/com/jogamp/opengl/FloatUtil.java | 130 +-
.../jogamp}/opengl/GLAutoDrawableDelegate.java | 81 +-
.../classes/com/jogamp/opengl/GLExtensions.java | 3 +
.../com/jogamp/opengl/GLRendererQuirks.java | 144 +++
.../opengl/GenericGLCapabilitiesChooser.java} | 35 +-
.../classes/com/jogamp/opengl/JoglVersion.java | 17 +
.../com/jogamp/opengl/OffscreenAutoDrawable.java | 98 --
.../classes/com/jogamp/opengl/swt/GLCanvas.java | 75 +-
.../com/jogamp/opengl/util/GLArrayDataClient.java | 39 +-
.../jogamp/opengl/util/GLArrayDataEditable.java | 33 +-
.../com/jogamp/opengl/util/GLArrayDataWrapper.java | 14 +-
.../classes/com/jogamp/opengl/util/GLBuffers.java | 73 +-
.../com/jogamp/opengl/util/GLReadBufferUtil.java | 8 +-
.../com/jogamp/opengl/util/ImmModeSink.java | 1029 ++++++++++------
.../classes/com/jogamp/opengl/util/PMVMatrix.java | 732 ++++++++---
.../com/jogamp/opengl/util/glsl/ShaderCode.java | 30 +
.../com/jogamp/opengl/util/glsl/ShaderProgram.java | 37 +-
.../com/jogamp/opengl/util/glsl/ShaderState.java | 145 ++-
.../com/jogamp/opengl/util/glsl/ShaderUtil.java | 49 +-
.../opengl/util/glsl/fixedfunc/FixedFuncUtil.java | 46 +-
.../util/glsl/fixedfunc/ShaderSelectionMode.java | 27 +
.../com/jogamp/opengl/util/texture/Texture.java | 9 +-
.../opengl/util/texture/spi/LEDataInputStream.java | 2 +-
.../media/opengl/DefaultGLCapabilitiesChooser.java | 39 +-
.../classes/javax/media/opengl/GLArrayData.java | 6 +-
.../classes/javax/media/opengl/GLAutoDrawable.java | 38 +-
src/jogl/classes/javax/media/opengl/GLBase.java | 38 +
.../classes/javax/media/opengl/GLCapabilities.java | 125 +-
.../media/opengl/GLCapabilitiesImmutable.java | 79 +-
src/jogl/classes/javax/media/opengl/GLContext.java | 315 +++--
.../classes/javax/media/opengl/GLDrawable.java | 2 +-
.../javax/media/opengl/GLDrawableFactory.java | 271 +++-
.../classes/javax/media/opengl/GLFBODrawable.java | 175 +++
.../media/opengl/GLOffscreenAutoDrawable.java} | 71 +-
src/jogl/classes/javax/media/opengl/GLPbuffer.java | 6 +-
src/jogl/classes/javax/media/opengl/GLProfile.java | 167 +--
.../classes/javax/media/opengl/GLRunnable2.java} | 18 +-
.../classes/javax/media/opengl/GLUniformData.java | 36 +-
.../classes/javax/media/opengl/awt/GLCanvas.java | 183 +--
.../classes/javax/media/opengl/awt/GLJPanel.java | 15 +-
.../javax/media/opengl/fixedfunc/GLMatrixFunc.java | 175 ++-
.../media/opengl/fixedfunc/GLPointerFuncUtil.java | 15 +-
.../graph/curve/opengl/RegionRendererImpl01.java | 4 +-
.../graph/curve/opengl/TextRendererImpl01.java | 4 +-
.../jogamp/graph/curve/opengl/VBORegion2PES2.java | 18 +-
.../jogamp/graph/curve/opengl/VBORegionSPES2.java | 14 +-
.../opengl/shader/curverenderer01-es2-merged.vp | 4 +-
.../curve/opengl/shader/curverenderer01-es2.vp | 4 +-
.../opengl/shader/curverenderer01a-es2-merged.fp | 4 +-
.../curve/opengl/shader/curverenderer01b-es2.fp | 2 +-
.../curve/opengl/shader/curverenderer02a-es2.fp | 2 +-
.../curve/opengl/shader/curverenderer02b-es2.fp | 2 +-
.../classes/jogamp/graph/font/JavaFontLoader.java | 8 +-
.../jogamp/graph/font/UbuntuFontLoader.java | 14 +-
.../classes/jogamp/graph/geom/plane/Path2D.java | 2 +-
.../classes/jogamp/opengl/GLAutoDrawableBase.java | 96 +-
.../jogamp/opengl/GLBufferStateTracker.java | 14 +-
src/jogl/classes/jogamp/opengl/GLContextImpl.java | 301 +++--
.../jogamp/opengl/GLDrawableFactoryImpl.java | 175 +--
.../classes/jogamp/opengl/GLDrawableHelper.java | 196 ++-
src/jogl/classes/jogamp/opengl/GLDrawableImpl.java | 94 +-
.../classes/jogamp/opengl/GLFBODrawableImpl.java | 571 +++++++--
.../jogamp/opengl/GLGraphicsConfigurationUtil.java | 233 ++--
.../jogamp/opengl/GLOffscreenAutoDrawableImpl.java | 123 ++
src/jogl/classes/jogamp/opengl/GLPbufferImpl.java | 31 +-
.../classes/jogamp/opengl/GLVersionNumber.java | 26 +-
.../classes/jogamp/opengl/GLXExtensions.java} | 24 +-
src/jogl/classes/jogamp/opengl/ProjectFloat.java | 356 +++---
src/jogl/classes/jogamp/opengl/ThreadingImpl.java | 3 +-
src/jogl/classes/jogamp/opengl/egl/EGLContext.java | 67 +-
.../classes/jogamp/opengl/egl/EGLDisplayUtil.java | 157 ++-
.../classes/jogamp/opengl/egl/EGLDrawable.java | 142 +--
.../jogamp/opengl/egl/EGLDrawableFactory.java | 608 +++++----
.../opengl/egl/EGLDummyUpstreamSurfaceHook.java | 59 +
.../jogamp/opengl/egl/EGLExternalContext.java | 11 -
.../jogamp/opengl/egl/EGLGLCapabilities.java | 23 +-
.../opengl/egl/EGLGraphicsConfiguration.java | 233 ++--
.../egl/EGLGraphicsConfigurationFactory.java | 70 +-
.../jogamp/opengl/egl/EGLOnscreenContext.java | 11 -
.../jogamp/opengl/egl/EGLOnscreenDrawable.java | 4 +-
.../jogamp/opengl/egl/EGLPbufferContext.java | 10 -
.../jogamp/opengl/egl/EGLPbufferDrawable.java | 8 +-
.../jogamp/opengl/egl/EGLUpstreamSurfaceHook.java | 145 ++-
.../jogamp/opengl/egl/EGLWrappedSurface.java | 26 +
.../classes/jogamp/opengl/glu/GLUquadricImpl.java | 42 +-
.../jogamp/opengl/macosx/cgl/MacOSXCGLContext.java | 775 ++++++++----
.../opengl/macosx/cgl/MacOSXCGLDrawable.java | 48 +-
.../macosx/cgl/MacOSXCGLDrawableFactory.java | 134 +-
.../macosx/cgl/MacOSXCGLGraphicsConfiguration.java | 193 ++-
.../cgl/MacOSXCGLGraphicsConfigurationFactory.java | 30 +-
.../macosx/cgl/MacOSXExternalCGLContext.java | 7 +-
.../macosx/cgl/MacOSXOnscreenCGLContext.java | 19 +-
.../macosx/cgl/MacOSXOnscreenCGLDrawable.java | 4 +-
.../opengl/macosx/cgl/MacOSXPbufferCGLContext.java | 1 +
.../macosx/cgl/MacOSXPbufferCGLDrawable.java | 42 +-
.../classes/jogamp/opengl/shader/texture01_xxx.fp | 19 +
.../classes/jogamp/opengl}/shader/texture01_xxx.vp | 12 +-
.../classes/jogamp/opengl/util/GLArrayHandler.java | 21 +-
.../jogamp/opengl/util/GLArrayHandlerFlat.java | 4 +-
.../opengl/util/GLArrayHandlerInterleaved.java | 40 +-
.../jogamp/opengl/util/GLDataArrayHandler.java | 41 +-
.../jogamp/opengl/util/GLFixedArrayHandler.java | 41 +-
.../opengl/util/GLFixedArrayHandlerFlat.java | 36 +-
...ataArrayHandler.java => GLVBOArrayHandler.java} | 45 +-
.../jogamp/opengl/util/av/EGLMediaPlayerImpl.java | 6 +-
.../jogamp/opengl/util/av/GLMediaPlayerImpl.java | 13 +-
.../av/impl/FFMPEGDynamicLibraryBundleInfo.java | 17 +
.../opengl/util/av/impl/FFMPEGMediaPlayer.java | 16 +-
.../jogamp/opengl/util/glsl/GLSLArrayHandler.java | 28 +-
.../opengl/util/glsl/GLSLArrayHandlerFlat.java | 36 +-
.../util/glsl/GLSLArrayHandlerInterleaved.java | 40 +-
.../opengl/util/glsl/fixedfunc/FixedFuncHook.java | 210 +++-
.../util/glsl/fixedfunc/FixedFuncPipeline.java | 1234 +++++++++++++++----
.../util/glsl/fixedfunc/shaders/FixedFuncColor.fp | 28 +-
.../util/glsl/fixedfunc/shaders/FixedFuncColor.vp | 6 +
.../glsl/fixedfunc/shaders/FixedFuncColorLight.vp | 16 +-
.../fixedfunc/shaders/FixedFuncColorTexture.fp | 136 +-
.../util/glsl/fixedfunc/shaders/FixedFuncPoints.fp | 47 +
.../util/glsl/fixedfunc/shaders/FixedFuncPoints.vp | 40 +
.../util/glsl/fixedfunc/shaders/mgl_alphatest.fp | 33 +
.../util/glsl/fixedfunc/shaders/mgl_attribute.glsl | 28 +-
.../util/glsl/fixedfunc/shaders/mgl_const.glsl | 31 +-
.../util/glsl/fixedfunc/shaders/mgl_lightdef.glsl | 3 +
.../util/glsl/fixedfunc/shaders/mgl_settexcoord.vp | 6 +
.../util/glsl/fixedfunc/shaders/mgl_uniform.glsl | 43 +-
.../glsl/fixedfunc/shaders/mgl_uniform_light.glsl | 1 +
.../util/glsl/fixedfunc/shaders/mgl_varying.glsl | 2 +
.../opengl/util/pngj/chunks/PngChunkTIME.java | 2 +-
.../opengl/windows/wgl/WGLGLCapabilities.java | 47 +-
.../windows/wgl/WindowsExternalWGLContext.java | 4 +-
.../windows/wgl/WindowsExternalWGLDrawable.java | 4 +-
.../windows/wgl/WindowsPbufferWGLDrawable.java | 66 +-
.../opengl/windows/wgl/WindowsWGLContext.java | 14 +-
.../opengl/windows/wgl/WindowsWGLDrawable.java | 43 +-
.../windows/wgl/WindowsWGLDrawableFactory.java | 87 +-
.../wgl/WindowsWGLGraphicsConfiguration.java | 556 +++++----
.../WindowsWGLGraphicsConfigurationFactory.java | 164 ++-
.../classes/jogamp/opengl/x11/glx/GLXUtil.java | 81 +-
.../opengl/x11/glx/X11ExternalGLXContext.java | 29 +-
.../opengl/x11/glx/X11ExternalGLXDrawable.java | 33 +-
.../jogamp/opengl/x11/glx/X11GLXContext.java | 167 +--
.../jogamp/opengl/x11/glx/X11GLXDrawable.java | 7 +-
.../opengl/x11/glx/X11GLXDrawableFactory.java | 125 +-
.../x11/glx/X11GLXGraphicsConfiguration.java | 340 +++--
.../glx/X11GLXGraphicsConfigurationFactory.java | 154 +--
.../opengl/x11/glx/X11OnscreenGLXDrawable.java | 2 +-
.../opengl/x11/glx/X11PbufferGLXDrawable.java | 35 +-
.../macosx/MacOSXWindowSystemInterface-calayer.m | 840 +++++++++++++
.../macosx/MacOSXWindowSystemInterface-pbuffer.m | 494 --------
.../native/macosx/MacOSXWindowSystemInterface.m | 81 +-
.../DelegatedUpstreamSurfaceHookMutableSize.java | 39 +
...elegatedUpstreamSurfaceHookWithSurfaceSize.java | 54 +
.../UpstreamSurfaceHookMutableSize.java | 45 +
.../com/jogamp/nativewindow/awt/JAWTWindow.java | 99 +-
.../jogamp/nativewindow/egl/EGLGraphicsDevice.java | 19 +-
.../com/jogamp/nativewindow/swt/SWTAccessor.java | 38 +-
.../jogamp/nativewindow/x11/X11GraphicsDevice.java | 42 +-
.../jogamp/nativewindow/x11/X11GraphicsScreen.java | 16 +-
.../media/nativewindow/AbstractGraphicsDevice.java | 13 +-
.../javax/media/nativewindow/Capabilities.java | 182 +--
.../media/nativewindow/CapabilitiesImmutable.java | 35 +-
.../nativewindow/DefaultCapabilitiesChooser.java | 9 +-
.../media/nativewindow/DefaultGraphicsDevice.java | 24 +-
.../nativewindow/GraphicsConfigurationFactory.java | 2 +-
.../javax/media/nativewindow/NativeSurface.java | 5 +-
.../media/nativewindow/NativeWindowFactory.java | 345 +++---
.../media/nativewindow/OffscreenLayerSurface.java | 3 +
.../javax/media/nativewindow/ProxySurface.java | 266 +---
.../javax/media/nativewindow/ToolkitLock.java | 38 +-
.../{ToolkitLock.java => UpstreamSurfaceHook.java} | 34 +-
...JAWTToolkitLock.java => GlobalToolkitLock.java} | 72 +-
.../nativewindow/NativeWindowFactoryImpl.java | 15 +-
.../jogamp/nativewindow/NullToolkitLock.java | 26 +-
.../nativewindow/ProxySurfaceImpl.java} | 204 +--
...11ToolkitLock.java => ResourceToolkitLock.java} | 65 +-
.../nativewindow/SharedResourceToolkitLock.java | 148 +++
.../jogamp/nativewindow/ToolkitProperties.java | 47 +
.../jogamp/nativewindow/WrappedSurface.java | 53 +-
.../jogamp/nativewindow/jawt/JAWTJNILibLoader.java | 2 +-
.../classes/jogamp/nativewindow/jawt/JAWTUtil.java | 55 +-
.../nativewindow/jawt/macosx/MacOSXJAWTWindow.java | 84 +-
.../nativewindow/jawt/x11/X11JAWTWindow.java | 3 +-
.../macosx/OSXDummyUpstreamSurfaceHook.java | 56 +
.../jogamp/nativewindow/macosx/OSXUtil.java | 55 +-
.../windows/GDIDummyUpstreamSurfaceHook.java | 50 +
.../jogamp/nativewindow/windows/GDISurface.java | 34 +-
.../jogamp/nativewindow/windows/GDIUtil.java | 40 +-
.../x11/X11DummyUpstreamSurfaceHook.java | 70 ++
.../classes/jogamp/nativewindow/x11/X11Util.java | 365 +++---
.../awt/X11AWTGraphicsConfigurationFactory.java | 7 +-
src/nativewindow/native/macosx/OSXmisc.m | 189 ++-
src/nativewindow/native/x11/Xmisc.c | 148 ++-
src/newt/classes/com/jogamp/newt/Display.java | 49 +-
src/newt/classes/com/jogamp/newt/NewtFactory.java | 13 +-
src/newt/classes/com/jogamp/newt/Screen.java | 10 +-
src/newt/classes/com/jogamp/newt/Window.java | 8 +-
.../classes/com/jogamp/newt/awt/NewtCanvasAWT.java | 9 +
.../classes/com/jogamp/newt/event/InputEvent.java | 90 +-
.../classes/com/jogamp/newt/event/KeyEvent.java | 419 +++----
.../classes/com/jogamp/newt/event/MouseEvent.java | 23 +-
.../classes/com/jogamp/newt/event/NEWTEvent.java | 14 +-
.../classes/com/jogamp/newt/event/WindowEvent.java | 13 +-
.../com/jogamp/newt/event/WindowUpdateEvent.java | 11 +-
.../jogamp/newt/event/awt/AWTWindowAdapter.java | 28 +-
.../classes/com/jogamp/newt/opengl/GLWindow.java | 25 +-
.../classes/com/jogamp/newt/swt/NewtCanvasSWT.java | 20 +-
.../classes/com/jogamp/newt/swt/SWTEDTUtil.java | 217 +++-
src/newt/classes/com/jogamp/newt/util/EDTUtil.java | 40 +-
.../classes/com/jogamp/newt/util/MainThread.java | 6 +-
src/newt/classes/jogamp/newt/DefaultEDTUtil.java | 62 +-
src/newt/classes/jogamp/newt/DisplayImpl.java | 111 +-
src/newt/classes/jogamp/newt/OffscreenWindow.java | 31 +-
src/newt/classes/jogamp/newt/ScreenImpl.java | 74 +-
src/newt/classes/jogamp/newt/WindowImpl.java | 132 +-
.../{AndroidDisplay.java => DisplayDriver.java} | 6 +-
.../newt/driver/android/NewtBaseActivity.java | 25 +-
.../newt/driver/android/NewtVersionActivity.java | 2 +-
.../{AndroidScreen.java => ScreenDriver.java} | 6 +-
.../{AndroidWindow.java => WindowDriver.java} | 56 +-
.../classes/jogamp/newt/driver/awt/AWTCanvas.java | 29 +-
.../classes/jogamp/newt/driver/awt/AWTEDTUtil.java | 221 +++-
.../awt/{AWTDisplay.java => DisplayDriver.java} | 16 +-
.../awt/{AWTScreen.java => ScreenDriver.java} | 4 +-
.../awt/{AWTWindow.java => WindowDriver.java} | 90 +-
.../Display.java => bcm/egl/DisplayDriver.java} | 12 +-
.../egl/Screen.java => bcm/egl/ScreenDriver.java} | 8 +-
.../egl/Window.java => bcm/egl/WindowDriver.java} | 8 +-
.../vc/iv/DisplayDriver.java} | 36 +-
.../vc/iv/ScreenDriver.java} | 57 +-
.../KDWindow.java => bcm/vc/iv/WindowDriver.java} | 114 +-
.../intel/gdl/{Display.java => DisplayDriver.java} | 20 +-
.../intel/gdl/{Screen.java => ScreenDriver.java} | 7 +-
.../intel/gdl/{Window.java => WindowDriver.java} | 19 +-
.../kd/{KDDisplay.java => DisplayDriver.java} | 9 +-
.../driver/kd/{KDScreen.java => ScreenDriver.java} | 6 +-
.../driver/kd/{KDWindow.java => WindowDriver.java} | 8 +-
.../newt/driver/linux/LinuxMouseTracker.java | 221 ++++
.../macosx/{MacDisplay.java => DisplayDriver.java} | 11 +-
.../jogamp/newt/driver/macosx/MacKeyUtil.java | 172 +--
.../macosx/{MacScreen.java => ScreenDriver.java} | 6 +-
.../macosx/{MacWindow.java => WindowDriver.java} | 128 +-
.../{WindowsDisplay.java => DisplayDriver.java} | 9 +-
.../{WindowsScreen.java => ScreenDriver.java} | 6 +-
.../{WindowsWindow.java => WindowDriver.java} | 80 +-
.../x11/{X11Display.java => DisplayDriver.java} | 80 +-
.../x11/{X11Screen.java => ScreenDriver.java} | 41 +-
.../x11/{X11Window.java => WindowDriver.java} | 125 +-
src/newt/native/AndroidWindow.c | 18 +-
src/newt/native/InputEvent.h | 27 +-
src/newt/native/IntelGDL.c | 24 +-
src/newt/native/KDWindow.c | 20 +-
src/newt/native/MacWindow.m | 165 +--
src/newt/native/NewtMacWindow.h | 4 +
src/newt/native/NewtMacWindow.m | 73 +-
src/newt/native/WindowsWindow.c | 300 +++--
src/newt/native/X11Common.h | 7 +-
src/newt/native/X11Display.c | 176 +--
src/newt/native/{X11Display.c => X11Event.c} | 443 +------
src/newt/native/X11Event.h | 9 +
src/newt/native/X11Screen.c | 87 +-
.../native/{X11Screen.c => X11ScreenRandR11.c} | 288 +----
.../native/{X11Screen.c => X11ScreenRandR13.c} | 311 ++---
src/newt/native/X11Window.c | 54 +-
src/newt/native/XCBEvent.c | 314 +++++
src/newt/native/XCBEvent.h | 10 +
src/newt/native/{BroadcomEGL.c => bcm_egl.c} | 16 +-
src/newt/native/bcm_vc_iv.c | 219 ++++
src/newt/native/bcm_vc_iv.h | 187 +++
src/test-native/contextRetargetDrawable01.c | 154 +++
src/test-native/contextRetargetDrawable02.c | 382 ++++++
src/test-native/glExtensionsListGL2.c | 2 +
src/test-native/glExtensionsListGL3.c | 25 +-
src/test-native/make.sh | 2 +
.../test/android/MovieCubeActivityLauncher0.java | 2 +
.../opengl/test/android/MovieSimpleActivity0.java | 6 +-
.../opengl/test/android/MovieSimpleActivity1.java | 10 +-
.../test/android/NEWTGearsES2ActivityLauncher.java | 8 +-
.../android/NEWTGraphUI1pActivityLauncher.java | 22 +-
...urrentNEWT.java => InitConcurrentBaseNEWT.java} | 86 +-
...WT.java => TestFBOAutoDrawableDeadlockAWT.java} | 11 +-
.../jogl/acore/TestFBOAutoDrawableFactoryNEWT.java | 375 ++++++
.../test/junit/jogl/acore/TestFBODrawableNEWT.java | 272 ----
.../test/junit/jogl/acore/TestFBOMRTNEWT01.java | 25 +-
.../junit/jogl/acore/TestFBOMix2DemosES2NEWT.java | 2 +-
...FBOOffThreadSharedContextMix2DemosES2NEWT.java} | 216 ++--
... TestFBOOnThreadSharedContext1DemoES2NEWT.java} | 191 +--
.../jogl/acore/TestGLAutoDrawableDelegateNEWT.java | 152 ---
...estGLAutoDrawableDelegateOnOffscrnCapsNEWT.java | 385 ++++++
.../TestGLAutoDrawableFactoryOffscrnCapsNEWT.java | 306 +++++
...TestGLAutoDrawableGLCanvasOnOffscrnCapsAWT.java | 324 +++++
...estGLAutoDrawableGLWindowOnOffscrnCapsNEWT.java | 339 +++++
...LAutoDrawableNewtCanvasAWTOnOffscrnCapsAWT.java | 299 +++++
.../acore/TestGLContextDrawableSwitchNEWT.java | 44 +-
.../jogl/acore/TestGLExtensionQueryOffscreen.java | 19 +-
.../junit/jogl/acore/TestGLProfile00NEWT.java} | 30 +-
.../test/junit/jogl/acore/TestGPUMemSec01NEWT.java | 4 +-
.../acore/TestInitConcurrent01NEWT.java} | 78 +-
.../junit/jogl/acore/TestInitConcurrent02NEWT.java | 96 ++
.../jogl/acore/TestNEWTCloseX11DisplayBug565.java | 46 +-
.../acore/TestOffscreenLayer01GLCanvasAWT.java} | 94 +-
.../acore/TestOffscreenLayer02NewtCanvasAWT.java} | 111 +-
.../junit/jogl/acore/TestPBufferDeadlockAWT.java | 2 +
.../test/junit/jogl/acore/TestPMVMatrix01NEWT.java | 442 +++++++
.../test/junit/jogl/acore/TestPMVMatrix02NEWT.java | 109 ++
.../test/junit/jogl/acore/TestPointsNEWT.java | 156 +++
.../junit/jogl/acore/TestSharedContextListAWT.java | 20 +-
.../jogl/acore/TestSharedContextListNEWT.java | 20 +-
.../jogl/acore/TestSharedContextListNEWT2.java | 14 +-
.../jogl/acore/TestSharedContextNewtAWTBug523.java | 17 +-
.../jogl/acore/TestSharedContextVBOES1NEWT.java | 20 +-
.../jogl/acore/TestSharedContextVBOES2NEWT.java | 132 +-
.../jogl/acore/TestSharedContextVBOES2NEWT2.java | 168 ---
.../junit/jogl/acore/TestShutdownCompleteAWT.java | 4 +-
.../junit/jogl/acore/TestShutdownCompleteNEWT.java | 14 +-
.../junit/jogl/acore/TestShutdownSharedAWT.java | 124 --
.../junit/jogl/acore/TestShutdownSharedNEWT.java | 127 --
.../opengl/test/junit/jogl/awt/TestAWT01GLn.java | 60 +-
...ava => TestBug461FBOSupersamplingSwingAWT.java} | 12 +-
...=> TestBug461PBufferSupersamplingSwingAWT.java} | 6 +-
.../opengl/test/junit/jogl/awt/TestBug572AWT.java | 127 ++
.../opengl/test/junit/jogl/awt/TestBug611AWT.java | 81 ++
.../jogl/awt/TestJScrollPaneMixHwLw01AWT.java | 172 +++
.../junit/jogl/caps/TestBug605FlippedImageAWT.java | 185 +++
.../jogl/caps/TestBug605FlippedImageNEWT.java | 176 +++
.../junit/jogl/caps/TestMultisampleES1AWT.java | 2 +-
.../junit/jogl/caps/TestMultisampleES1NEWT.java | 2 +-
.../junit/jogl/caps/TestMultisampleES2NEWT.java | 2 +-
.../opengl/test/junit/jogl/demos/GearsObject.java | 14 +-
.../opengl/test/junit/jogl/demos/PointsDemo.java} | 32 +-
.../opengl/test/junit/jogl/demos/es1/GearsES1.java | 50 +-
.../test/junit/jogl/demos/es1/GearsObjectES1.java | 7 +-
.../junit/jogl/demos/es1/MultisampleDemoES1.java | 11 +-
.../test/junit/jogl/demos/es1/OneTriangle.java | 11 +-
.../test/junit/jogl/demos/es1/PointsDemoES1.java | 198 +++
.../test/junit/jogl/demos/es1/RedSquareES1.java | 65 +-
.../jogl/demos/es1/newt/TestGearsES1NEWT.java | 27 +-
.../jogl/demos/es1/newt/TestRedSquareES1NEWT.java | 27 +-
.../test/junit/jogl/demos/es2/FBOMix2DemosES2.java | 51 +-
.../opengl/test/junit/jogl/demos/es2/GearsES2.java | 33 +-
.../test/junit/jogl/demos/es2/GearsObjectES2.java | 17 +-
.../{FBOMix2DemosES2.java => Mix2TexturesES2.java} | 169 +--
.../junit/jogl/demos/es2/MultisampleDemoES2.java | 14 +-
.../es2/{RedSquareES2.java => PointsDemoES2.java} | 164 +--
.../test/junit/jogl/demos/es2/RedSquareES2.java | 31 +-
.../jogl/demos/es2/TextureDraw01ES2Listener.java | 17 +-
.../junit/jogl/demos/es2/awt/TestGearsES2AWT.java | 62 +-
.../jogl/demos/es2/newt/TestGearsES2NEWT.java | 52 +-
.../jogl/demos/es2/newt/TestRedSquareES2NEWT.java | 41 +-
.../junit/jogl/demos/es2/shader/PointsShader.fp | 47 +
.../junit/jogl/demos/es2/shader/PointsShader.vp | 47 +
.../junit/jogl/demos/es2/shader/RedSquareShader.fp | 19 +-
.../junit/jogl/demos/es2/shader/RedSquareShader.vp | 15 +-
.../jogl/demos/es2/shader/RedSquareShader2.fp | 22 +-
.../test/junit/jogl/demos/es2/shader/default.vp | 5 +
.../shader/elektronenmultiplizierer_development.fp | 12 +-
.../es2/shader/elektronenmultiplizierer_port.fp | 12 +-
.../test/junit/jogl/demos/es2/shader/gears.fp | 10 +-
.../test/junit/jogl/demos/es2/shader/gears.vp | 7 +-
.../junit/jogl/demos/es2/shader/mgl_default_xxx.fp | 10 +-
.../junit/jogl/demos/es2/shader/mgl_default_xxx.vp | 4 +
.../test/junit/jogl/demos/es2/shader/ruler.fp | 9 +-
.../junit/jogl/demos/es2/shader/texsequence_xxx.fp | 9 +-
.../junit/jogl/demos/es2/shader/texsequence_xxx.vp | 5 +
.../junit/jogl/demos/es2/shader/texture01_xxx.fp | 10 +-
.../junit/jogl/demos/es2/shader/texture01_xxx.vp | 5 +
.../junit/jogl/demos/es2/shader/texture02_xxx.fp | 14 +-
.../opengl/test/junit/jogl/demos/gl2/Gears.java | 13 +-
.../jogl/demos/gl2/awt/TestGLJPanelAWTBug450.java | 2 +-
.../demos/gl2/newt/TestGearsNewtAWTWrapper.java | 20 +-
.../junit/jogl/drawable/TestDrawable01NEWT.java | 183 ---
.../test/junit/jogl/glsl/GLSLMiscHelper.java | 8 +-
.../junit/jogl/glsl/TestGLSLShaderState01NEWT.java | 10 +-
.../junit/jogl/glsl/TestGLSLShaderState02NEWT.java | 28 +-
.../test/junit/jogl/glsl/TestRulerNEWT01.java | 8 +-
.../test/junit/jogl/offscreen/ReadBufferBase.java | 2 +-
.../test/junit/jogl/swt/TestNewtCanvasSWTGLn.java | 2 +-
.../junit/jogl/swt/TestSWTAccessor03AWTGLn.java | 137 ++-
.../junit/jogl/swt/TestSWTJOGLGLCanvas01GLn.java | 2 +-
.../junit/jogl/util/DemoGL2ES1ImmModeSink.java | 97 ++
.../test/junit/jogl/util/DemoGL2ES1Plain.java | 161 +++
.../jogl/util/DemoGL2ES1TextureImmModeSink.java | 142 +++
.../TestES1FixedFunctionPipelineNEWT.java} | 95 +-
.../junit/jogl/util/TestImmModeSinkES1NEWT.java | 140 +++
.../TestGLReadBufferUtilTextureIOWrite01AWT.java | 4 +-
.../TestGLReadBufferUtilTextureIOWrite01NEWT.java | 16 +-
.../TestGLReadBufferUtilTextureIOWrite02AWT.java | 2 +-
.../TestGLReadBufferUtilTextureIOWrite02NEWT.java | 2 +-
.../util/texture/TestPNGTextureFromFileAWT.java | 2 +-
.../util/texture/TestPNGTextureFromFileNEWT.java | 2 +-
.../test/junit/newt/TestFocus01SwingAWTRobot.java | 27 +-
.../test/junit/newt/TestFocus02SwingAWTRobot.java | 20 +-
.../junit/newt/TestNewtKeyCodeModifiersAWT.java | 275 +++++
...SwingAWTRobot.java => TestNewtKeyCodesAWT.java} | 222 ++--
.../junit/newt/TestNewtKeyEventAutoRepeatAWT.java | 320 +++++
...AWTRobot.java => TestNewtKeyEventOrderAWT.java} | 210 ++--
...=> TestNewtKeyPressReleaseUnmaskRepeatAWT.java} | 197 +--
.../test/junit/newt/TestRemoteGLWindows01NEWT.java | 1 -
.../test/junit/newt/TestRemoteWindow01NEWT.java | 2 +-
.../test/junit/newt/TestScreenMode00NEWT.java | 2 +-
.../test/junit/newt/TestScreenMode00bNEWT.java | 2 +-
.../test/junit/newt/TestScreenMode01NEWT.java | 50 +-
.../opengl/test/junit/newt/TestWindows01NEWT.java | 3 +-
.../parenting/NewtAWTReparentingKeyAdapter.java | 6 +-
.../TestParentingFocusTraversal01AWT.java | 5 +-
.../opengl/test/junit/util/AWTFocusAdapter.java | 11 +-
.../opengl/test/junit/util/AWTKeyAdapter.java | 65 +-
.../opengl/test/junit/util/AWTMouseAdapter.java | 43 +-
.../opengl/test/junit/util/AWTRobotUtil.java | 124 +-
.../test/junit/util/AWTWindowFocusAdapter.java | 11 +-
.../opengl/test/junit/util/EventCountAdapter.java | 9 +
.../test/junit/util/InputEventCountAdapter.java | 6 +
...CountAdapter.java => KeyEventCountAdapter.java} | 11 +-
.../jogamp/opengl/test/junit/util/MiscUtils.java | 48 +
.../opengl/test/junit/util/NEWTFocusAdapter.java | 11 +-
.../opengl/test/junit/util/NEWTGLContext.java | 4 +-
.../opengl/test/junit/util/NEWTKeyAdapter.java | 80 +-
.../jogamp/opengl/test/junit/util/NEWTKeyUtil.java | 185 +++
.../opengl/test/junit/util/NEWTMouseAdapter.java | 44 +-
.../jogamp/opengl/test/junit/util/UITestCase.java | 159 ++-
.../{MiscUtils.java => ValidateLockListener.java} | 67 +-
486 files changed, 25754 insertions(+), 12249 deletions(-)
diff --git a/doc/TODO.txt b/doc/TODO.txt
index d31466f..80eb7ba 100644
--- a/doc/TODO.txt
+++ b/doc/TODO.txt
@@ -1,9 +1,23 @@
-WIP:
+Version 2.0:
+
+- SIGG slides / video
+- ES3 / GL 4.3
+
+
++++
+
+NVIDIA Tegra: discard problem (still exist?):
+ OK:
+ GL_RENDERER: NVIDIA Tegra
+ GL_VERSION: OpenGL ES 2.0 14.01002
-- GLPbuffer -> GLOffscreenAutoDrawable
- - GLPbuffer GLDrawableFactory.createPbuffer() ->
- GLOffscreenAutoDrawable GLDrawableFactory.createOffsceenAutoDrawable()
- - Mark both deprecated!
++++
+
+TestSharedContextVBOES2NEWT crashes the NV driver sporadically.
+
+++
+
+WIP:
- Optimize/Fix NIO caching of glMapBuffer/glUnmapBuffer
- optimize the NIO caching, i.e. memory range, incr. reference count
diff --git a/doc/deployment/JOGL-DEPLOYMENT.html b/doc/deployment/JOGL-DEPLOYMENT.html
index abaa661..d4916a2 100644
--- a/doc/deployment/JOGL-DEPLOYMENT.html
+++ b/doc/deployment/JOGL-DEPLOYMENT.html
@@ -28,10 +28,61 @@
<div id="main">
<div id="text" class="fill">
+ <h1><a name="TraditionalApplets">Traditional Applets</a></h1>
+
+ <p>
+ You may choose to use traditional <a href="http://java.sun.com/applets/">Java Applets</a> to deploy your
+ in-browser applet and reference the JOGL resources.<p/>
+
+ <p>
+ This method simply requires a Java plugin and uses JogAmp's
+ <a href="../userguide/index.html#automatednativelibraryloading">build-in method to automatically load</a>
+ the <a href="#NativeJARFiles">native JAR files</a>.
+ </p>
+
+ Examples are available:
+ <ul>
+ <li><a href="http://jausoft.com/jogamp/jogl-applet-runner-newt-gears-normal-napplet.html">Demo on jausoft.com and modules on jogamp.org</a></li>
+ <li><a href="http://jogamp.org/deployment/jogamp-current/jogl-applet-runner-newt-gears-normal-napplet.html">Demo and modules on jogamp.org</a></li>
+ </ul>
+ <pre>
+ <object classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
+ width="200" height="200">
+ <param name="code" value="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run">
+ <param name="archive" value="jar/gluegen-rt.jar,
+ jar/jogl-all.jar,
+ jar/jogl-test.jar">
+ <param name="java_arguments" value="-Dsun.java2d.noddraw=true">
+ <param name="gl_event_listener_class" value="com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2">
+ <param name="gl_profile" value="GL2ES2">
+ <param name="gl_swap_interval" value="1">
+ <param name="gl_debug" value="false">
+ <param name="gl_trace" value="false">
+ <comment>
+ <embed code="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run"
+ width="200" height="200"
+ type="application/x-java-applet;version=1.6"
+ pluginspage="http://java.sun.com/javase/downloads/ea.jsp"
+ archive="jar/gluegen-rt.jar,
+ jar/jogl-all.jar,
+ jar/jogl-test.jar"
+ java_arguments="-Dsun.java2d.noddraw=true"
+ gl_event_listener_class="com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2"
+ gl_profile="GL2ES2"
+ gl_swap_interval="1"
+ gl_debug="false"
+ gl_trace="false">
+ <noembed>Sorry, no Java support detected.</noembed>
+ </embed>
+ </comment>
+ </object>
+ </pre>
+
+
<h1><a name="JNLPFiles">JNLP Files</a></h1>
<p>
- You may choose to use JNLP to deploy your application
+ You may choose to use JNLP to deploy your application or in-browser applet
and reference the JOGL resources.<p/>
<p>
@@ -45,7 +96,7 @@
<ul>
<li> <code><b> http://jogamp.org/deployment/jogamp-current/ </b></code> Current Version </li>
<li> <code><b> http://jogamp.org/deployment/jogamp-next/ </b></code> Next Version </li>
- <li> <code><b> http://jogamp.org/deployment/v2.0-rc3/ </b></code> Specific Version </li>
+ <li> <code><b> http://jogamp.org/deployment/v2.0-rc10/ </b></code> Specific Version </li>
</ul>
<h2>Desktop All in One</h2>
@@ -103,8 +154,9 @@
<li>linux-amd64</li>
<li>linux-ia64</li>
<li>linux-i586</li>
- <li>linux-armv7</li>
- <li>android-armv7</li>
+ <li>linux-armv6</li>
+ <li>linux-armv6hf</li>
+ <li>android-armv6</li>
<li>macosx-universal</li>
<li>solaris-sparc</li>
<li>solaris-sparcv9</li>
@@ -138,7 +190,7 @@
<a name="JOGLAllInOneJARsAWT">With AWT</a>:
<ul>
- <li><code>jogl.all.jar</code><br/>
+ <li><code>jogl-all.jar</code><br/>
<ul>
<li><code>jogl-all-natives-<b><i>os.and.arch</i></b>.jar</code></li>
</ul>
@@ -147,7 +199,7 @@
<a name="JOGLAllInOneJARsNoAWT">Without AWT</a>:
<ul>
- <li><code>jogl.all-noawt.jar</code><br/>
+ <li><code>jogl-all-noawt.jar</code><br/>
<ul>
<li><code>jogl-all-natives-<b><i>os.and.arch</i></b>.jar</code></li>
</ul>
@@ -156,7 +208,7 @@
<a name="JOGLAllInOneJARsMobile">Mobile</a>:
<ul>
- <li><code>jogl.all-mobile.jar</code><br/>
+ <li><code>jogl-all-mobile.jar</code><br/>
<ul>
<li><code>jogl-all-natives-<b><i>os.and.arch</i></b>.jar</code></li>
</ul>
@@ -165,7 +217,7 @@
<a name="JOGLAllInOneJARsAndroid">Android</a>:
<ul>
- <li><code>jogl.all-android.jar</code><br/>
+ <li><code>jogl-all-android.jar</code><br/>
<ul>
<li><code>jogl-all-natives-<b><i>os.and.arch</i></b>.jar</code></li>
</ul>
@@ -185,14 +237,14 @@
<ul>
<li>Mandatory:<br/>
<ul>
- <li>nativewindow.core.jar</li>
- <li>jogl.core.jar</li>
+ <li>nativewindow-core.jar</li>
+ <li>jogl-core.jar</li>
</ul></li>
<li>Newt (optional):<br/>
<ul>
- <li>newt.core.jar</li>
- <li>newt.ogl.jar (to use NEWT with JOGL)</li>
+ <li>newt-core.jar</li>
+ <li>newt-ogl.jar (to use NEWT with JOGL)</li>
</ul></li>
</ul>
@@ -203,23 +255,26 @@
<ul>
<li>NativeWindow [pick your platfrom, if available]:<br/>
<ul>
- <li>nativewindow.os.x11.jar</li>
+ <li>nativewindow-os-x11.jar</li>
</ul></li>
<li>JOGL [pick your platform]:<br/>
<ul>
- <li>jogl.os.x11.jar</li>
- <li>jogl.os.win.jar</li>
- <li>jogl.os.osx.jar</li>
+ <li>jogl-os-x11.jar</li>
+ <li>jogl-os-win.jar</li>
+ <li>jogl-os-osx.jar</li>
<li>none</li>
</ul></li>
<li>Newt [pick your platform] (optional):<br/>
<ul>
- <li>newt.driver.x11.jar</li>
- <li>newt.driver.win.jar</li>
- <li>newt.driver.osx.jar</li>
- <li>newt.driver.kd.jar</li>
+ <li>newt-driver-x11.jar</li>
+ <li>newt-driver-win.jar</li>
+ <li>newt-driver-osx.jar</li>
+ <li>newt-driver-kd.jar</li>
+ <li>newt-driver-bcm-vc.jar</li>
+ <li>newt-driver-bcm-old.jar</li>
+ <li>newt-driver-intelgdl.jar</li>
<li>none</li>
</ul></li>
</ul>
@@ -231,17 +286,17 @@
<ul>
<li>Embedded Device Profiles<br/>
<ul>
- <li>jogl.glmobile.jar<br/>
+ <li>jogl-glmobile.jar<br/>
<ul>
- <li>jogl.glmobile.dbg.jar</li>
+ <li>jogl-glmobile-dbg.jar</li>
</ul></li>
</ul></li>
<li>Desktop Profiles<br/>
<ul>
- <li>jogl.gldesktop.jar<br/>
+ <li>jogl-gldesktop.jar<br/>
<ul>
- <li>jogl.gldesktop.dbg.jar</li>
+ <li>jogl-gldesktop-dbg.jar</li>
</ul></li>
</ul></li>
</ul>
@@ -249,26 +304,26 @@
<h4>JOGL Toolkits/Misc (optional)</h4>
<ul>
- <li>jogl.util.jar</li>
- <li>jogl.util.gl2.jar</li>
- <li>jogl.util.fixedfuncemu.jar</li>
+ <li>jogl-util.jar</li>
+ <li>jogl-util-gldesktop.jar</li>
+ <li>jogl-util-fixedfuncemu.jar</li>
</ul>
<h4>AWT (optional) </h4>
<ul>
- <li> nativewindow.awt.jar</li>
- <li> jogl.awt.jar</li>
- <li> jogl.util.awt.jar (if using jogl.util)</li>
- <li> newt.awt.jar (if using with NEWT)</li>
+ <li> nativewindow-awt.jar</li>
+ <li> jogl-awt.jar</li>
+ <li> jogl-util-awt.jar (if using jogl-util)</li>
+ <li> newt-awt.jar (if using with NEWT)</li>
</ul>
<h4>GLU (optional) </h4>
<ul>
- <li>jogl.glutess.jar</li>
- <li>jogl.glumipmap.jar</li>
- <li>jogl.glugl2.jar</li>
+ <li>jogl-glu-tess.jar</li>
+ <li>jogl-glu-mipmap.jar</li>
+ <li>jogl-glu-gldesktop.jar</li>
</ul>
<h2><a name="NativeLibraryFiles">Native Library Files</a></h2>
diff --git a/doc/userguide/index.html b/doc/userguide/index.html
index cdb26f1..f90a260 100644
--- a/doc/userguide/index.html
+++ b/doc/userguide/index.html
@@ -184,9 +184,9 @@ bundles.
Modify your <code>CLASSPATH</code>
environment variable to include the full paths to
-<code>gluegen-rt.jar</code> and <code>jogl.all.jar</code>, for example
+<code>gluegen-rt.jar</code> and <code>jogl-all.jar</code>, for example
<pre>
-".;C:\Some\Other\Package\foo.jar;C:\Users\myhome\jogamp-all-platforms\jar\gluegen-rt.jar;C:\Users\myhome\jogamp-all-platforms\jar\jogl.all.jar".
+".;C:\Some\Other\Package\foo.jar;C:\Users\myhome\jogamp-all-platforms\jar\gluegen-rt.jar;C:\Users\myhome\jogamp-all-platforms\jar\jogl-all.jar".
</pre>
(If you did not previously set the CLASSPATH environment variable, you
may want to make sure that ".", the current directory, is on your new
@@ -208,9 +208,12 @@ size, in particular on smaller devices. See <a href="../deployment/JOGL-DEPLOYME
<p>
JOGL 2.0 has a brand new feature allowing to automatically extract the proper native
-libraries required to use JOGL from JARs containing them without relying on the Java
+libraries required to use JOGL
+<a href="../deployment/JOGL-DEPLOYMENT.html#NativeJARFiles">from JARs containing them</a>
+without relying on the Java
library path or any platform-dependent environment variable allowing to set the location
of native libraries. This allows desktop applications as well as traditional Applets
+<a href="../deployment/JOGL-DEPLOYMENT.html#TraditionalApplets">as traditional Applets</a>
to utilize the native library JAR files the same way Webstart/JNLP does.
</p>
diff --git a/etc/test.sh b/etc/test.sh
index 1912a95..714c3d8 100755
--- a/etc/test.sh
+++ b/etc/test.sh
@@ -12,7 +12,7 @@ echo LIBGL_DRIVERS_PATH: $LIBGL_DRIVERS_PATH 2>&1 | tee -a $logfile
echo LIBGL_DEBUG: $LIBGL_DEBUG 2>&1 | tee -a $logfile
echo java $X_ARGS $D_ARGS $* 2>&1 | tee -a $logfile
-CLASSPATH=jar/gluegen-rt.jar:jar/jogl.all.jar
+CLASSPATH=jar/gluegen-rt.jar:jar/jogl-all.jar
export CLASSPATH
echo CLASSPATH: $CLASSPATH
diff --git a/jnlp-files/jogl-all-awt-cg.jnlp b/jnlp-files/jogl-all-awt-cg.jnlp
index 24c22c2..ab4c1cd 100644
--- a/jnlp-files/jogl-all-awt-cg.jnlp
+++ b/jnlp-files/jogl-all-awt-cg.jnlp
@@ -69,12 +69,16 @@
<nativelib href = "jar/atomic/jogl-cg-natives-linux-amd64.jar" />
</resources>
<resources os="Linux" arch="arm">
- <nativelib href = "jar/jogl-all-natives-linux-armv7.jar" />
- <nativelib href = "jar/atomic/jogl-cg-natives-linux-armv7.jar" />
+ <nativelib href = "jar/jogl-all-natives-linux-armv6.jar" />
+ <nativelib href = "jar/jogl-all-natives-linux-armv6hf.jar" />
+ <nativelib href = "jar/atomic/jogl-cg-natives-linux-armv6.jar" />
+ <nativelib href = "jar/atomic/jogl-cg-natives-linux-armv6hf.jar" />
</resources>
<resources os="Linux" arch="armv7">
- <nativelib href = "jar/jogl-all-natives-linux-armv7.jar" />
- <nativelib href = "jar/atomic/jogl-cg-natives-linux-armv7.jar" />
+ <nativelib href = "jar/jogl-all-natives-linux-armv6.jar" />
+ <nativelib href = "jar/jogl-all-natives-linux-armv6hf.jar" />
+ <nativelib href = "jar/atomic/jogl-cg-natives-linux-armv6.jar" />
+ <nativelib href = "jar/atomic/jogl-cg-natives-linux-armv6hf.jar" />
</resources>
<resources os="Mac OS X" arch="i386">
<nativelib href = "jar/jogl-all-natives-macosx-universal.jar" />
diff --git a/jnlp-files/jogl-all-awt.jnlp b/jnlp-files/jogl-all-awt.jnlp
index 4e05f8d..a666eb4 100644
--- a/jnlp-files/jogl-all-awt.jnlp
+++ b/jnlp-files/jogl-all-awt.jnlp
@@ -56,10 +56,12 @@
<nativelib href = "jar/jogl-all-natives-linux-amd64.jar" />
</resources>
<resources os="Linux" arch="arm">
- <nativelib href = "jar/jogl-all-natives-linux-armv7.jar" />
+ <nativelib href = "jar/jogl-all-natives-linux-armv6.jar" />
+ <nativelib href = "jar/jogl-all-natives-linux-armv6hf.jar" />
</resources>
<resources os="Linux" arch="armv7">
- <nativelib href = "jar/jogl-all-natives-linux-armv7.jar" />
+ <nativelib href = "jar/jogl-all-natives-linux-armv6.jar" />
+ <nativelib href = "jar/jogl-all-natives-linux-armv6hf.jar" />
</resources>
<resources os="Mac OS X" arch="i386">
<nativelib href = "jar/jogl-all-natives-macosx-universal.jar" />
diff --git a/jnlp-files/jogl-all-mobile.jnlp b/jnlp-files/jogl-all-mobile.jnlp
index 43b9b3b..710f74a 100644
--- a/jnlp-files/jogl-all-mobile.jnlp
+++ b/jnlp-files/jogl-all-mobile.jnlp
@@ -56,10 +56,12 @@
<nativelib href = "jar/jogl-all-natives-linux-amd64.jar" />
</resources>
<resources os="Linux" arch="arm">
- <nativelib href = "jar/jogl-all-natives-linux-armv7.jar" />
+ <nativelib href = "jar/jogl-all-natives-linux-armv6.jar" />
+ <nativelib href = "jar/jogl-all-natives-linux-armv6hf.jar" />
</resources>
<resources os="Linux" arch="armv7">
- <nativelib href = "jar/jogl-all-natives-linux-armv7.jar" />
+ <nativelib href = "jar/jogl-all-natives-linux-armv6.jar" />
+ <nativelib href = "jar/jogl-all-natives-linux-armv6hf.jar" />
</resources>
<resources os="Mac OS X" arch="i386">
<nativelib href = "jar/jogl-all-natives-macosx-universal.jar" />
diff --git a/jnlp-files/jogl-all-noawt.jnlp b/jnlp-files/jogl-all-noawt.jnlp
index eed6749..802b9b9 100644
--- a/jnlp-files/jogl-all-noawt.jnlp
+++ b/jnlp-files/jogl-all-noawt.jnlp
@@ -56,10 +56,12 @@
<nativelib href = "jar/jogl-all-natives-linux-amd64.jar" />
</resources>
<resources os="Linux" arch="arm">
- <nativelib href = "jar/jogl-all-natives-linux-armv7.jar" />
+ <nativelib href = "jar/jogl-all-natives-linux-armv6.jar" />
+ <nativelib href = "jar/jogl-all-natives-linux-armv6hf.jar" />
</resources>
<resources os="Linux" arch="armv7">
- <nativelib href = "jar/jogl-all-natives-linux-armv7.jar" />
+ <nativelib href = "jar/jogl-all-natives-linux-armv6.jar" />
+ <nativelib href = "jar/jogl-all-natives-linux-armv6hf.jar" />
</resources>
<resources os="Mac OS X" arch="i386">
<nativelib href = "jar/jogl-all-natives-macosx-universal.jar" />
diff --git a/jnlp-files/jogl-applet-runner-newt-gears-gl3-napplet.html b/jnlp-files/jogl-applet-runner-newt-gears-gl3-napplet.html
new file mode 100644
index 0000000..13d8919
--- /dev/null
+++ b/jnlp-files/jogl-applet-runner-newt-gears-gl3-napplet.html
@@ -0,0 +1,107 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+<title>JOGL NEWT Applet Runner - GearsES2 - GL3 Core - Normal Applet</title>
+</head>
+<body BGCOLOR="#ffffff">
+
+<P>
+JOGL NEWT Applet Runner Special Keys:<br>
+<ul>
+ <li> d - toggle decoration </li>
+ <li> f - toggle fullscreen </li>
+ <li> r - in/out browser window </li>
+ <li> a - on/off always-on-top </li>
+</ul>
+</P>
+
+<P>
+<object classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
+ width="200" height="200">
+ <param name="code" value="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run">
+ <param name="archive" value="jar/gluegen-rt.jar,
+ jar/jogl-all.jar,
+ jar/jogl-test.jar">
+ <param name="java_arguments" value="-Dsun.java2d.noddraw=true">
+ <param name="gl_event_listener_class" value="com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2">
+ <param name="gl_profile" value="GL3">
+ <param name="gl_swap_interval" value="1">
+ <param name="gl_debug" value="false">
+ <param name="gl_trace" value="false">
+ <comment>
+ <embed code="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run"
+ width="200" height="200"
+ type="application/x-java-applet;version=1.6"
+ pluginspage="http://java.sun.com/javase/downloads/ea.jsp"
+ archive="jar/gluegen-rt.jar,
+ jar/jogl-all.jar,
+ jar/jogl-test.jar"
+ java_arguments="-Dsun.java2d.noddraw=true"
+ gl_event_listener_class="com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2"
+ gl_profile="GL3"
+ gl_swap_interval="1"
+ gl_debug="false"
+ gl_trace="false">
+ <noembed>Sorry, no Java support detected.</noembed>
+ </embed>
+ </comment>
+</object>
+
+</P>
+
+<P>
+Applet is using a GL3 core context, failure is expected if n/a on your platform!
+</P>
+
+<P>
+
+The applet above is instantiated with the following code:
+
+<pre>
+<object classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
+ width="200" height="200">
+ <param name="code" value="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run">
+ <param name="archive" value="jar/gluegen-rt.jar,
+ jar/jogl-all.jar,
+ jar/jogl-test.jar">
+ <param name="java_arguments" value="-Dsun.java2d.noddraw=true">
+ <param name="gl_event_listener_class" value="com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2">
+ <param name="gl_profile" value="GL3">
+ <param name="gl_swap_interval" value="1">
+ <param name="gl_debug" value="false">
+ <param name="gl_trace" value="false">
+ <comment>
+ <embed code="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run"
+ width="200" height="200"
+ type="application/x-java-applet;version=1.6"
+ pluginspage="http://java.sun.com/javase/downloads/ea.jsp"
+ archive="jar/gluegen-rt.jar,
+ jar/jogl-all.jar,
+ jar/jogl-test.jar"
+ java_arguments="-Dsun.java2d.noddraw=true"
+ gl_event_listener_class="com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2"
+ gl_profile="GL3"
+ gl_swap_interval="1"
+ gl_debug="false"
+ gl_trace="false">
+ <noembed>Sorry, no Java support detected.</noembed>
+ </embed>
+ </comment>
+</object>
+
+</pre>
+
+</P>
+<P>
+
+Note that the jogl-test.jar, which contains the test applet class,
+<B>does not need to be signed</B>! JogAmp Community signs
+jogl.jar and gluegen-rt.jar, which contain
+JOGL's supporting classes; this is the only
+Java code which needs to be signed in order to deploy applets using
+JOGL and is the only certificate the end user must accept.
+
+</P>
+
+</body>
+</html>
diff --git a/jnlp-files/jogl-test-applets.html b/jnlp-files/jogl-test-applets.html
index 81902a8..132945e 100644
--- a/jnlp-files/jogl-test-applets.html
+++ b/jnlp-files/jogl-test-applets.html
@@ -71,7 +71,8 @@ See Legend below table
<a href="jogl-applet-runner-newt-gears-normal.html">Dual</a><br/>
<a href="jogl-applet-runner-newt-gears-normal-launcheronly.html">LApplet</a><br/>
<a href="jogl-applet-runner-newt-gears-normal-napplet.html">NApplet</a>
- (<a href="jogl-applet-runner-newt-gears-normal-napplet2.html">closeable</a>)<br/>
+ (<a href="jogl-applet-runner-newt-gears-normal-napplet2.html">closeable</a>,
+ <a href="jogl-applet-runner-newt-gears-gl3-napplet.html">force gl3</a>)<br/>
</td>
<td>
Classic OpenGL Gears for ES2
diff --git a/make/build-common.xml b/make/build-common.xml
index 4de5de5..a718ae0 100644
--- a/make/build-common.xml
+++ b/make/build-common.xml
@@ -140,7 +140,7 @@
<istrue value="${isLinuxX86}" />
</condition>
<condition property="swt.jar" value="${project.root}/make/lib/swt/gtk-linux-x86/swt-debug.jar">
- <istrue value="${isLinuxARMv7}" /> <!-- FIXME JAU .. hack -->
+ <istrue value="${isLinuxARMv6}" /> <!-- FIXME JAU .. hack -->
</condition>
<condition property="swt.jar" value="${project.root}/make/lib/swt/gtk-linux-x86/swt-debug.jar">
<istrue value="${isAndroid}" /> <!-- FIXME JAU .. hack -->
@@ -278,6 +278,7 @@
<property name="jogl-glmobile.jar" value="${build.jogl}/jogl-glmobile.jar" />
<property name="jogl-glmobile-dbg.jar" value="${build.jogl}/jogl-glmobile-dbg.jar" />
<property name="jogl-util.jar" value="${build.jogl}/jogl-util.jar" />
+ <property name="jogl-util-graph.jar" value="${build.jogl}/jogl-util-graph.jar" />
<property name="jogl-glutess.jar" value="${build.jogl}/jogl-glu-tess.jar" />
<property name="jogl-glumipmap.jar" value="${build.jogl}/jogl-glu-mipmap.jar" />
<property name="jogl-util-fixedfuncemu.jar" value="${build.jogl}/jogl-util-fixedfuncemu.jar" />
@@ -301,6 +302,7 @@
<pathelement location="${jogl-glmobile.jar}" />
<pathelement location="${jogl-glmobile-dbg.jar}" />
<pathelement location="${jogl-util.jar}" />
+ <pathelement location="${jogl-util-graph.jar}" />
<pathelement location="${jogl-glutess.jar}" />
<pathelement location="${jogl-glumipmap.jar}" />
<pathelement location="${jogl-util-fixedfuncemu.jar}" />
@@ -322,6 +324,7 @@
<pathelement location="${jogl-glmobile.jar}" />
<pathelement location="${jogl-glmobile-dbg.jar}" />
<pathelement location="${jogl-util.jar}" />
+ <pathelement location="${jogl-util-graph.jar}" />
<pathelement location="${jogl-glutess.jar}" />
<pathelement location="${jogl-glumipmap.jar}" />
<pathelement location="${jogl-util-fixedfuncemu.jar}" />
@@ -339,6 +342,7 @@
<pathelement location="${jogl-glmobile.jar}" />
<pathelement location="${jogl-glmobile-dbg.jar}" />
<pathelement location="${jogl-util.jar}" />
+ <pathelement location="${jogl-util-graph.jar}" />
<pathelement location="${jogl-glutess.jar}" />
<pathelement location="${jogl-glumipmap.jar}" />
<pathelement location="${jogl-util-fixedfuncemu.jar}" />
@@ -350,6 +354,7 @@
<pathelement location="${jogl-glmobile.jar}" />
<pathelement location="${jogl-glmobile-dbg.jar}" />
<pathelement location="${jogl-util.jar}" />
+ <pathelement location="${jogl-util-graph.jar}" />
<pathelement location="${jogl-glutess.jar}" />
<pathelement location="${jogl-glumipmap.jar}" />
<pathelement location="${jogl-util-fixedfuncemu.jar}" />
@@ -357,41 +362,49 @@
<pathelement location="${jogl-omx.jar}" />
</path>
<!--
- ${jogl-core.jar} ${jogl-glutess.jar} ${jogl-glumipmap.jar} ${jogl-glu-gldesktop.jar} ${jogl-os-x11.jar} ${jogl-os-win.jar} ${jogl-os-osx.jar} ${jogl-gldesktop.jar} ${jogl-gldesktop-dbg.jar} ${jogl-glmobile.jar} ${jogl-glmobile-dbg.jar} ${jogl-omx.jar} ${jogl-util.jar} ${jogl-util-gldesktop.jar} ${jogl-util-awt.jar} ${jogl-util-fixedfuncemu.jar} ${jogl-sdk.jar} -->
+ ${jogl-core.jar} ${jogl-glutess.jar} ${jogl-glumipmap.jar} ${jogl-glu-gldesktop.jar} ${jogl-os-x11.jar} ${jogl-os-win.jar} ${jogl-os-osx.jar} ${jogl-gldesktop.jar} ${jogl-gldesktop-dbg.jar} ${jogl-glmobile.jar} ${jogl-glmobile-dbg.jar} ${jogl-omx.jar} ${jogl-util.jar} ${jogl-util-graph.jar} ${jogl-util-gldesktop.jar} ${jogl-util-awt.jar} ${jogl-util-fixedfuncemu.jar} ${jogl-sdk.jar} -->
<property name="newt-core.jar" value="${build.newt}/newt-core.jar" />
<property name="newt-ogl.jar" value="${build.newt}/newt-ogl.jar" />
<property name="newt-awt.jar" value="${build.newt}/newt-awt.jar" />
<property name="newt-swt.jar" value="${build.newt}/newt-swt.jar" />
<property name="newt-event.jar" value="${build.newt}/newt-event.jar" /> <!-- using NEWT events w/o NEWT -->
+ <property name="newt-driver-linux.jar" value="${build.newt}/newt-driver-linux.jar" />
<property name="newt-driver-x11.jar" value="${build.newt}/newt-driver-x11.jar" />
<property name="newt-driver-win.jar" value="${build.newt}/newt-driver-win.jar" />
<property name="newt-driver-osx.jar" value="${build.newt}/newt-driver-osx.jar" />
<property name="newt-driver-android.jar" value="${build.newt}/newt-driver-android.jar" /> <!-- excluded from all -->
<property name="newt-driver-kd.jar" value="${build.newt}/newt-driver-kd.jar" /> <!-- excluded from all -->
<property name="newt-driver-intelgdl.jar" value="${build.newt}/newt-driver-intelgdl.jar" /> <!-- excluded from all -->
- <property name="newt-driver-broadcomegl.jar" value="${build.newt}/newt-driver-broadcomegl.jar" /> <!-- excluded from all -->
+ <property name="newt-driver-bcm-old.jar" value="${build.newt}/newt-driver-bcm-old.jar" /> <!-- excluded from all -->
+ <property name="newt-driver-bcm-vc.jar" value="${build.newt}/newt-driver-bcm-vc.jar" />
<path id="newt_all_atoms.classpath">
<pathelement location="${newt-core.jar}" />
<pathelement location="${newt-ogl.jar}" />
<pathelement location="${newt-awt.jar}" />
<pathelement location="${newt-swt.jar}" />
+ <pathelement location="${newt-driver-linux.jar}" />
<pathelement location="${newt-driver-x11.jar}" />
<pathelement location="${newt-driver-win.jar}" />
<pathelement location="${newt-driver-osx.jar}" />
+ <pathelement location="${newt-driver-bcm-vc.jar}" />
</path>
<path id="newt_all-noawt_atoms.classpath">
<pathelement location="${newt-core.jar}" />
<pathelement location="${newt-ogl.jar}" />
+ <pathelement location="${newt-driver-linux.jar}" />
<pathelement location="${newt-driver-x11.jar}" />
<pathelement location="${newt-driver-win.jar}" />
<pathelement location="${newt-driver-osx.jar}" />
+ <pathelement location="${newt-driver-bcm-vc.jar}" />
</path>
<path id="newt_all-mobile_atoms.classpath">
<pathelement location="${newt-core.jar}" />
<pathelement location="${newt-ogl.jar}" />
+ <pathelement location="${newt-driver-linux.jar}" />
<pathelement location="${newt-driver-x11.jar}" />
<pathelement location="${newt-driver-win.jar}" />
+ <pathelement location="${newt-driver-bcm-vc.jar}" />
</path>
<path id="newt_all-android_atoms.classpath">
<pathelement location="${newt-core.jar}" />
diff --git a/make/build-jogl.xml b/make/build-jogl.xml
index 2605104..3c6f0fc 100644
--- a/make/build-jogl.xml
+++ b/make/build-jogl.xml
@@ -89,7 +89,7 @@
value="com/jogamp/gluegen/runtime/opengl/*"/>
<property name="java.part.core"
- value="${java.part.gluegen-gl-rt} javax/media/opengl/* javax/media/opengl/fixedfunc/* javax/media/opengl/glu/* javax/media/opengl/glu/gl2es1/* com/jogamp/opengl/* jogamp/opengl/* jogamp/opengl/glu/* jogamp/opengl/glu/error/*"/>
+ value="${java.part.gluegen-gl-rt} javax/media/opengl/* javax/media/opengl/fixedfunc/* javax/media/opengl/glu/* javax/media/opengl/glu/gl2es1/* com/jogamp/opengl/* jogamp/opengl/* jogamp/opengl/glu/* jogamp/opengl/glu/error/* jogamp/opengl/shader/**"/>
<property name="java.part.core.exclude" value="javax/media/opengl/Debug* javax/media/opengl/Trace*"/>
<property name="java.part.nv-cg"
@@ -167,6 +167,9 @@
<property name="java.part.util.graph.fonts"
value="jogamp/graph/font/fonts/**"/>
+ <property name="java.part.core.shadercode"
+ value="jogamp/opengl/shader/* jogamp/opengl/shader/bin/**"/>
+
<property name="java.part.util.graph.shadercode"
value="jogamp/graph/curve/opengl/shader/* jogamp/graph/curve/opengl/shader/bin/**"/>
@@ -177,7 +180,7 @@
value="jogamp/opengl/util/glsl/fixedfunc/shaders/* jogamp/opengl/util/glsl/fixedfunc/shaders/bin/**"/>
<property name="java.part.nonjava"
- value="${java.part.util.fixedfuncemu.shadercode} ${java.part.util.graph.shadercode} ${java.part.util.graph.fonts}"/>
+ value="${java.part.core.shadercode} ${java.part.util.fixedfuncemu.shadercode} ${java.part.util.graph.shadercode} ${java.part.util.graph.fonts}"/>
<property name="java.part.all-desktop"
value="${java.part.sdk} ${java.part.glx} ${java.part.wgl} ${java.part.cgl} ${java.part.gldesktop} ${java.part.glugldesktop} ${java.part.util.gldesktop}"/>
@@ -1054,7 +1057,7 @@
</javac>
</target>
- <target name="java.compile.secondpass.android" if="isAndroid">
+ <target name="java.compile.secondpass.android" if="android-jars.available">
<!-- Perform the second pass Java compile; everything except portion of fixed function emulation depending on generated code. -->
<javac destdir="${classes}"
includes="${java.part.android}"
@@ -1119,7 +1122,7 @@
<includepath path="/usr/local/include" />
</compiler>
- <compiler id="compiler.cfg.linux.armv7.jogl.x11" extends="compiler.cfg.linux.armv7">
+ <compiler id="compiler.cfg.linux.armv6.jogl.x11" extends="compiler.cfg.linux.armv6">
<!-- Need to force /usr/include headers on to include path (after all others), due to crosscompiler usage -->
<compilerarg value="-idirafter" />
<compilerarg value="/usr/include" />
@@ -1147,7 +1150,7 @@
<syslibset libs="X11"/>
</linker>
- <linker id="linker.cfg.linux.armv7.jogl.x11" extends="linker.cfg.linux.armv7">
+ <linker id="linker.cfg.linux.armv6.jogl.x11" extends="linker.cfg.linux.armv6">
<syslibset dir="${env.TARGET_PLATFORM_ROOT}/usr/lib" libs="X11"/>
</linker>
@@ -1236,10 +1239,10 @@
<property name="linker.cfg.id.os" value="linker.cfg.linux.amd64.jogl.x11" />
</target>
- <target name="c.configure.linux.armv7" if="isLinuxARMv7">
- <echo message="Linux.armv7" />
- <property name="compiler.cfg.id" value="compiler.cfg.linux.armv7.jogl.x11" />
- <property name="linker.cfg.id.os" value="linker.cfg.linux.armv7.jogl.x11" />
+ <target name="c.configure.linux.armv6" if="isLinuxARMv6">
+ <echo message="Linux.armv6" />
+ <property name="compiler.cfg.id" value="compiler.cfg.linux.armv6.jogl.x11" />
+ <property name="linker.cfg.id.os" value="linker.cfg.linux.armv6.jogl.x11" />
</target>
<target name="c.configure.linux.ia64" if="isLinuxIA64">
@@ -1284,7 +1287,7 @@
<property name="linker.cfg.id.os" value="linker.cfg.linux.jogl.x11" />
</target>
- <target name="c.configure.linux" depends="c.configure.linux.armv7,c.configure.linux.x86,c.configure.linux.amd64,c.configure.linux.ia64,c.configure.linux.hppa,c.configure.linux.mips,c.configure.linux.mipsel,c.configure.linux.ppc,c.configure.linux.s390,c.configure.linux.sparc,c.configure.x11" if="isLinux" />
+ <target name="c.configure.linux" depends="c.configure.linux.armv6,c.configure.linux.x86,c.configure.linux.amd64,c.configure.linux.ia64,c.configure.linux.hppa,c.configure.linux.mips,c.configure.linux.mipsel,c.configure.linux.ppc,c.configure.linux.s390,c.configure.linux.sparc,c.configure.x11" if="isLinux" />
<target name="c.configure.android" if="isAndroid">
<echo message="Android" />
@@ -1375,7 +1378,7 @@
<include name="${rootrel.src.c}/timespec.c" if="isOSX"/> <!-- currently only used for OSX -->
<include name="${rootrel.src.c}/macosx/MacOSXCustomCGLCode.c" if="isOSX"/>
<include name="${rootrel.src.c}/macosx/MacOSXWindowSystemInterface.m" if="isOSX"/>
- <include name="${rootrel.src.c}/macosx/MacOSXWindowSystemInterface-pbuffer.m" if="isOSX"/>
+ <include name="${rootrel.src.c}/macosx/MacOSXWindowSystemInterface-calayer.m" if="isOSX"/>
<include name="${rootrel.src.c}/macosx/ContextUpdater.m" if="isOSX"/>
<include name="${rootrel.src.c}/GLXGetProcAddressARB.c" if="isX11"/>
<!-- FIXME: the Mixer should be moved to another library -->
@@ -1550,7 +1553,7 @@
<srcfileset dir="${src.java}"
includes="${java.part.nonjava}"/>
<targetfileset dir="."
- includes="${jogl-util.jar} ${jogl-util-fixedfuncemu.jar}" />
+ includes="${jogl-core.jar} ${jogl-util.jar} ${jogl-util-graph.jar} ${jogl-util-fixedfuncemu.jar}" />
</dependset>
</target>
<target name="build-jars" depends="build-jars-dependset,build-jars-javase" />
@@ -1581,7 +1584,7 @@
</jar>
</target>
- <target name="build-jars-android" depends="setup-manifestfile" if="isAndroid">
+ <target name="build-jars-android" depends="setup-manifestfile" if="android-jars.available">
<jar manifest="${build.jogl}/manifest.mf" destfile="${jogl-os-android.jar}" filesonly="true">
<fileset dir="${classes}" includes="${java.part.android}"/>
</jar>
@@ -1662,10 +1665,14 @@
</jar>
<jar manifest="${build.jogl}/manifest.mf" destfile="${jogl-util.jar}" filesonly="true">
<fileset dir="${classes}"
- includes="${java.part.util} ${java.part.util.glsl} ${java.part.util.graph}"
- excludes="${java.part.util.awt} ${java.part.util.gldesktop} ${java.part.util.fixedfuncemu}"/>
+ includes="${java.part.util} ${java.part.util.glsl}"
+ excludes="${java.part.util.awt} ${java.part.util.gldesktop} ${java.part.util.fixedfuncemu} ${java.part.util.graph}"/>
<fileset dir="resources/assets" includes="jogl/util/**" />
</jar>
+ <jar manifest="${build.jogl}/manifest.mf" destfile="${jogl-util-graph.jar}" filesonly="true">
+ <fileset dir="${classes}"
+ includes="${java.part.util.graph}"/>
+ </jar>
<jar manifest="${build.jogl}/manifest.mf" destfile="${jogl-util-fixedfuncemu.jar}" filesonly="true">
<fileset dir="${classes}"
includes="${java.part.util.fixedfuncemu}"/>
diff --git a/make/build-nativewindow.xml b/make/build-nativewindow.xml
index c77558d..3c97d9d 100644
--- a/make/build-nativewindow.xml
+++ b/make/build-nativewindow.xml
@@ -342,7 +342,7 @@
<includepath path="/usr/local/include" />
</compiler>
- <compiler id="compiler.cfg.linux.armv7.nativewindow.x11" extends="compiler.cfg.linux.armv7">
+ <compiler id="compiler.cfg.linux.armv6.nativewindow.x11" extends="compiler.cfg.linux.armv6">
<!-- Need to force /usr/include headers on to include path (after all others), due to crosscompiler usage -->
<compilerarg value="-idirafter" />
<compilerarg value="/usr/include" />
@@ -396,7 +396,7 @@
<syslibset libs="Xrender"/>
</linker>
- <linker id="linker.cfg.linux.armv7.nativewindow.x11" extends="linker.cfg.linux.armv7">
+ <linker id="linker.cfg.linux.armv6.nativewindow.x11" extends="linker.cfg.linux.armv6">
<syslibset dir="${env.TARGET_PLATFORM_ROOT}/usr/lib" libs="X11" />
<syslibset dir="${env.TARGET_PLATFORM_ROOT}/usr/lib" libs="Xxf86vm" />
<syslibset dir="${env.TARGET_PLATFORM_ROOT}/usr/lib" libs="Xrender" />
@@ -487,10 +487,10 @@
<property name="linker.cfg.id.oswin" value="linker.cfg.linux.amd64.nativewindow.x11" />
</target>
- <target name="c.configure.linux.armv7" if="isLinuxARMv7">
- <echo message="Linux.armv7" />
- <property name="compiler.cfg.id" value="compiler.cfg.linux.armv7.nativewindow.x11" />
- <property name="linker.cfg.id.oswin" value="linker.cfg.linux.armv7.nativewindow.x11" />
+ <target name="c.configure.linux.armv6" if="isLinuxARMv6">
+ <echo message="Linux.armv6" />
+ <property name="compiler.cfg.id" value="compiler.cfg.linux.armv6.nativewindow.x11" />
+ <property name="linker.cfg.id.oswin" value="linker.cfg.linux.armv6.nativewindow.x11" />
</target>
<target name="c.configure.linux.ia64" if="isLinuxIA64">
@@ -535,7 +535,7 @@
<property name="linker.cfg.id.oswin" value="linker.cfg.linux.nativewindow.x11" />
</target>
- <target name="c.configure.linux" depends="c.configure.linux.armv7,c.configure.linux.x86,c.configure.linux.amd64,c.configure.linux.ia64,c.configure.linux.hppa,c.configure.linux.mips,c.configure.linux.mipsel,c.configure.linux.ppc,c.configure.linux.s390,c.configure.linux.sparc,c.configure.x11" if="isLinux" />
+ <target name="c.configure.linux" depends="c.configure.linux.armv6,c.configure.linux.x86,c.configure.linux.amd64,c.configure.linux.ia64,c.configure.linux.hppa,c.configure.linux.mips,c.configure.linux.mipsel,c.configure.linux.ppc,c.configure.linux.s390,c.configure.linux.sparc,c.configure.x11" if="isLinux" />
<target name="c.configure.android" if="isAndroid">
<echo message="Android" />
@@ -759,6 +759,7 @@
<target name="c.build.nativewindow.windowlib.x11" if="isX11">
<javah destdir="${src.generated.c}/X11" classpath="${javah.classpath}" class="jogamp.nativewindow.x11.X11Lib" />
+ <javah destdir="${src.generated.c}/X11" classpath="${javah.classpath}" class="jogamp.nativewindow.x11.X11Util" />
<c.build c.compiler.src.files="c.src.files.x11"
output.lib.name="nativewindow_x11"
diff --git a/make/build-newt.xml b/make/build-newt.xml
index 7767088..7b9a518 100644
--- a/make/build-newt.xml
+++ b/make/build-newt.xml
@@ -48,7 +48,7 @@
setup.noNativeDesktop
setup.addNativeKD
setup.addNativeIntelGDL
- setup.addNativeBroadcomEGL
+ setup.addNativeBroadcom ( always true if 'isLinux' )
- Internal settings, may not be necessary to set them manually,
since all JAR archives are orthogonal.
@@ -71,6 +71,10 @@
-->
<target name="base.init" depends="common.init">
+ <condition property="setup.addNativeBroadcom">
+ <isset property="isLinux"/>
+ </condition>
+
<condition property="setup.nonatives">
<and>
<isfalse value="${isWindows}" />
@@ -79,7 +83,7 @@
<isfalse value="${isAndroid}" />
<isfalse value="${setup.addNativeKD}" />
<isfalse value="${setup.addNativeIntelGDL}" />
- <isfalse value="${setup.addNativeBroadcomEGL}" />
+ <isfalse value="${setup.addNativeBroadcom}" />
</and>
</condition>
@@ -90,7 +94,7 @@
<echo message="isAndroid: ${isAndroid}" />
<echo message="setup.addNativeKD: ${setup.addNativeKD}" />
<echo message="setup.addNativeIntelGDL: ${setup.addNativeIntelGDL}" />
- <echo message="setup.addNativeBroadcomEGL: ${setup.addNativeBroadcomEGL}" />
+ <echo message="setup.addNativeBroadcom: ${setup.addNativeBroadcom}" />
<echo message="setup.nonatives: ${setup.nonatives}" />
<!-- partitioning -->
@@ -110,6 +114,9 @@
<property name="java.part.swt"
value="com/jogamp/newt/swt/**"/>
+ <property name="java.part.driver.linux"
+ value="jogamp/newt/driver/linux/**"/>
+
<property name="java.part.driver.x11"
value="jogamp/newt/driver/x11/**"/>
@@ -125,8 +132,11 @@
<property name="java.part.driver.intelgdl"
value="jogamp/newt/driver/intel/gdl/**"/>
- <property name="java.part.driver.broadcomegl"
- value="jogamp/newt/driver/broadcom/egl/**"/>
+ <property name="java.part.driver.bcm.old"
+ value="jogamp/newt/driver/bcm/egl/**"/>
+
+ <property name="java.part.driver.bcm.vc"
+ value="jogamp/newt/driver/bcm/vc/**"/>
<property name="java.part.driver.android"
value="jogamp/newt/driver/android/**"/>
@@ -201,7 +211,8 @@
<mkdir dir="${src.generated.c}/Windows" />
<mkdir dir="${src.generated.c}/KD" />
<mkdir dir="${src.generated.c}/IntelGDL" />
- <mkdir dir="${src.generated.c}/BroadcomEGL" />
+ <mkdir dir="${src.generated.c}/bcm/egl" />
+ <mkdir dir="${src.generated.c}/bcm/vc/iv" />
<mkdir dir="${classes}" />
<mkdir dir="${obj.newt}" />
</target>
@@ -226,7 +237,7 @@
</javac>
</target>
- <target name="java.compile.android" if="isAndroid">
+ <target name="java.compile.android" if="android-jars.available">
<javac destdir="${classes}"
excludes="${java.excludes.all}"
fork="yes"
@@ -254,7 +265,7 @@
<includepath path="/usr/local/include" />
</compiler>
- <compiler id="compiler.cfg.linux.armv7.newt.x11" extends="compiler.cfg.linux.armv7">
+ <compiler id="compiler.cfg.linux.armv6.newt.x11" extends="compiler.cfg.linux.armv6">
<!-- Need to force /usr/include headers on to include path (after all others), due to crosscompiler usage -->
<compilerarg value="-idirafter" />
<compilerarg value="/usr/include" />
@@ -274,7 +285,16 @@
<syslibset libs="Xrandr"/>
</linker>
- <linker id="linker.cfg.linux.newt.broadcom_egl" extends="linker.cfg.linux">
+ <linker id="linker.cfg.linux.newt.bcm_egl" extends="linker.cfg.linux">
+ <syslibset libs="EGL"/>
+ <syslibset libs="GLES_CM"/>
+ </linker>
+
+ <linker id="linker.cfg.linux.newt.bcm_vc" extends="linker.cfg.linux">
+ <!-- syslibset libs="EGL"/ -->
+ </linker>
+
+ <linker id="linker.cfg.linux.newt.bcm_egl" extends="linker.cfg.linux">
<syslibset libs="EGL"/>
<syslibset libs="GLES_CM"/>
</linker>
@@ -282,19 +302,25 @@
<linker id="linker.cfg.linux.newt.x11" extends="linker.cfg.linux">
<syslibset libs="X11"/>
<syslibset libs="Xrandr"/>
+ <!--syslibset libs="xcb" /-->
+ <!--syslibset libs="X11-xcb" /-->
</linker>
<linker id="linker.cfg.linux.x86.newt.x11" extends="linker.cfg.linux.x86">
<syslibset libs="X11"/>
<syslibset libs="Xrandr"/>
+ <!--syslibset libs="xcb" /-->
+ <!--syslibset libs="X11-xcb" /-->
</linker>
<linker id="linker.cfg.linux.amd64.newt.x11" extends="linker.cfg.linux.amd64">
<syslibset libs="X11"/>
<syslibset libs="Xrandr"/>
+ <!--syslibset libs="xcb" /-->
+ <!--syslibset libs="X11-xcb" /-->
</linker>
- <linker id="linker.cfg.linux.armv7.newt.x11" extends="linker.cfg.linux.armv7">
+ <linker id="linker.cfg.linux.armv6.newt.x11" extends="linker.cfg.linux.armv6">
<syslibset dir="${env.TARGET_PLATFORM_ROOT}/usr/lib" libs="X11" />
<syslibset dir="${env.TARGET_PLATFORM_ROOT}/usr/lib" libs="Xrandr" />
</linker>
@@ -384,11 +410,11 @@
<echo message="linker.cfg.id.oswin ${linker.cfg.id.oswin}" />
</target>
- <target name="c.configure.linux.armv7" if="isLinuxARMv7">
- <echo message="Linux.armv7" />
- <property name="compiler.cfg.id" value="compiler.cfg.linux.armv7.newt.x11" />
- <condition property="linker.cfg.id.oswin" value="linker.cfg.linux.armv7.newt.x11"
- else="linker.cfg.linux.armv7">
+ <target name="c.configure.linux.armv6" if="isLinuxARMv6">
+ <echo message="Linux.armv6" />
+ <property name="compiler.cfg.id" value="compiler.cfg.linux.armv6.newt.x11" />
+ <condition property="linker.cfg.id.oswin" value="linker.cfg.linux.armv6.newt.x11"
+ else="linker.cfg.linux.armv6">
<isset property="isX11" />
</condition>
<echo message="linker.cfg.id.oswin ${linker.cfg.id.oswin}" />
@@ -460,7 +486,7 @@
<property name="linker.cfg.id.oswin" value="linker.cfg.linux.newt.x11" />
</target>
- <target name="c.configure.linux" depends="c.configure.linux.x86,c.configure.linux.amd64,c.configure.linux.armv7,c.configure.linux.hppa,c.configure.linux.mips,c.configure.linux.mipsel,c.configure.linux.ppc,c.configure.linux.s390,c.configure.linux.sparc,c.configure.linux.ia64,c.configure.x11" if="isLinux"/>
+ <target name="c.configure.linux" depends="c.configure.linux.x86,c.configure.linux.amd64,c.configure.linux.armv6,c.configure.linux.hppa,c.configure.linux.mips,c.configure.linux.mipsel,c.configure.linux.ppc,c.configure.linux.s390,c.configure.linux.sparc,c.configure.linux.ia64,c.configure.x11" if="isLinux"/>
<target name="c.configure.android" if="isAndroid">
<echo message="Android" />
@@ -560,11 +586,14 @@
<include name="${rootrel.src.c}/*.m" if="isOSX"/>
<include name="${rootrel.src.c}/AndroidWindow.c" if="isAndroid"/>
<include name="${rootrel.src.c}/X11Display.c" if="isX11"/>
+ <!-- include name="${rootrel.src.c}/X11Event.c" if="isX11"/-->
+ <!-- include name="${rootrel.src.c}/XCBEvent.c" if="isX11"/-->
<include name="${rootrel.src.c}/X11Screen.c" if="isX11"/>
<include name="${rootrel.src.c}/X11Window.c" if="isX11"/>
<include name="${rootrel.src.c}/KDWindow.c" if="setup.addNativeKD"/>
<include name="${rootrel.src.c}/IntelGDL.c" if="setup.addNativeIntelGDL"/>
- <include name="${rootrel.src.c}/BroadcomEGL.c" if="setup.addNativeBroadcomEGL"/>
+ <include name="${rootrel.src.c}/bcm_egl.c" if="setup.addNativeBroadcom"/>
+ <include name="${rootrel.src.c}/bcm_vc_iv.c" if="setup.addNativeBroadcom"/>
</patternset>
<echo message="Compiling @{output.lib.name}" />
@@ -609,7 +638,8 @@
<includepath path="${src.generated.c}/KD" if="setup.addNativeKD" />
<includepath path="${src.generated.c}/IntelGDL" if="setup.addNativeIntelGDL" />
<includepath path="stub_includes/embedded/IntelGDL" if="setup.addNativeIntelGDL" />
- <includepath path="${src.generated.c}/BroadcomEGL" if="setup.addNativeBroadcomEGL" />
+ <includepath path="${src.generated.c}/bcm/egl" if="setup.addNativeBroadcom" />
+ <includepath path="${src.generated.c}/bcm/vc/iv" if="setup.addNativeBroadcom" />
<!-- This must come last to not override real include paths -->
<!-- includepath path="stub_includes/macosx" if="isOSX" / -->
@@ -648,27 +678,30 @@
</macrodef>
<target name="c.build.newt.prepare">
- <javah destdir="${src.generated.c}/KD" classpath="${javah.classpath}" class="jogamp.newt.driver.kd.KDWindow" />
+ <javah destdir="${src.generated.c}/KD" classpath="${javah.classpath}" class="jogamp.newt.driver.kd.WindowDriver" />
- <javah destdir="${src.generated.c}/IntelGDL" classpath="${javah.classpath}" class="jogamp.newt.driver.intel.gdl.Display" />
- <javah destdir="${src.generated.c}/IntelGDL" classpath="${javah.classpath}" class="jogamp.newt.driver.intel.gdl.Screen" />
- <javah destdir="${src.generated.c}/IntelGDL" classpath="${javah.classpath}" class="jogamp.newt.driver.intel.gdl.Window" />
+ <javah destdir="${src.generated.c}/IntelGDL" classpath="${javah.classpath}" class="jogamp.newt.driver.intel.gdl.DisplayDriver" />
+ <javah destdir="${src.generated.c}/IntelGDL" classpath="${javah.classpath}" class="jogamp.newt.driver.intel.gdl.ScreenDriver" />
+ <javah destdir="${src.generated.c}/IntelGDL" classpath="${javah.classpath}" class="jogamp.newt.driver.intel.gdl.WindowDriver" />
- <javah destdir="${src.generated.c}/BroadcomEGL" classpath="${javah.classpath}" class="jogamp.newt.driver.broadcom.egl.Window" />
+ <javah destdir="${src.generated.c}/bcm/egl" classpath="${javah.classpath}" class="jogamp.newt.driver.bcm.egl.WindowDriver" />
+ <javah destdir="${src.generated.c}/bcm/vc/iv" classpath="${javah.classpath}" class="jogamp.newt.driver.bcm.vc.iv.DisplayDriver" />
+ <javah destdir="${src.generated.c}/bcm/vc/iv" classpath="${javah.classpath}" class="jogamp.newt.driver.bcm.vc.iv.ScreenDriver" />
+ <javah destdir="${src.generated.c}/bcm/vc/iv" classpath="${javah.classpath}" class="jogamp.newt.driver.bcm.vc.iv.WindowDriver" />
- <javah destdir="${src.generated.c}/Windows" classpath="${javah.classpath}" class="jogamp.newt.driver.windows.WindowsWindow" />
- <javah destdir="${src.generated.c}/Windows" classpath="${javah.classpath}" class="jogamp.newt.driver.windows.WindowsScreen" />
- <javah destdir="${src.generated.c}/Windows" classpath="${javah.classpath}" class="jogamp.newt.driver.windows.WindowsDisplay" />
- <javah destdir="${src.generated.c}/MacOSX" classpath="${javah.classpath}" class="jogamp.newt.driver.macosx.MacWindow" />
- <javah destdir="${src.generated.c}/MacOSX" classpath="${javah.classpath}" class="jogamp.newt.driver.macosx.MacScreen" />
- <javah destdir="${src.generated.c}/MacOSX" classpath="${javah.classpath}" class="jogamp.newt.driver.macosx.MacDisplay" />
- <javah destdir="${src.generated.c}/X11" classpath="${javah.classpath}" class="jogamp.newt.driver.x11.X11Window" />
- <javah destdir="${src.generated.c}/X11" classpath="${javah.classpath}" class="jogamp.newt.driver.x11.X11Screen" />
- <javah destdir="${src.generated.c}/X11" classpath="${javah.classpath}" class="jogamp.newt.driver.x11.X11Display" />
+ <javah destdir="${src.generated.c}/Windows" classpath="${javah.classpath}" class="jogamp.newt.driver.windows.WindowDriver" />
+ <javah destdir="${src.generated.c}/Windows" classpath="${javah.classpath}" class="jogamp.newt.driver.windows.ScreenDriver" />
+ <javah destdir="${src.generated.c}/Windows" classpath="${javah.classpath}" class="jogamp.newt.driver.windows.DisplayDriver" />
+ <javah destdir="${src.generated.c}/MacOSX" classpath="${javah.classpath}" class="jogamp.newt.driver.macosx.WindowDriver" />
+ <javah destdir="${src.generated.c}/MacOSX" classpath="${javah.classpath}" class="jogamp.newt.driver.macosx.ScreenDriver" />
+ <javah destdir="${src.generated.c}/MacOSX" classpath="${javah.classpath}" class="jogamp.newt.driver.macosx.DisplayDriver" />
+ <javah destdir="${src.generated.c}/X11" classpath="${javah.classpath}" class="jogamp.newt.driver.x11.WindowDriver" />
+ <javah destdir="${src.generated.c}/X11" classpath="${javah.classpath}" class="jogamp.newt.driver.x11.ScreenDriver" />
+ <javah destdir="${src.generated.c}/X11" classpath="${javah.classpath}" class="jogamp.newt.driver.x11.DisplayDriver" />
</target>
<target name="c.build.newt.prepare.android" if="isAndroid">
- <javah destdir="${src.generated.c}/Android" classpath="${javah.classpath}:${android.jar}" class="jogamp.newt.driver.android.AndroidWindow" />
+ <javah destdir="${src.generated.c}/Android" classpath="${javah.classpath}:${android.jar}" class="jogamp.newt.driver.android.WindowDriver" />
</target>
<target name="c.build.newt.windowlib" unless="setup.nonatives">
@@ -730,6 +763,10 @@
</target>
<target name="build-jars-driver" depends="setup-manifestfile">
+ <jar manifest="${build.newt}/manifest.mf" destfile="${newt-driver-linux.jar}" filesonly="true">
+ <fileset dir="${classes}"
+ includes="${java.part.driver.linux}"/>
+ </jar>
<jar manifest="${build.newt}/manifest.mf" destfile="${newt-driver-x11.jar}" filesonly="true">
<fileset dir="${classes}"
includes="${java.part.driver.x11}"/>
@@ -746,9 +783,13 @@
<fileset dir="${classes}"
includes="${java.part.driver.kd}"/>
</jar>
- <jar manifest="${build.newt}/manifest.mf" destfile="${newt-driver-broadcomegl.jar}" filesonly="true">
+ <jar manifest="${build.newt}/manifest.mf" destfile="${newt-driver-bcm-old.jar}" filesonly="true">
+ <fileset dir="${classes}"
+ includes="${java.part.driver.bcm.old}"/>
+ </jar>
+ <jar manifest="${build.newt}/manifest.mf" destfile="${newt-driver-bcm-vc.jar}" filesonly="true">
<fileset dir="${classes}"
- includes="${java.part.driver.broadcomegl}"/>
+ includes="${java.part.driver.bcm.vc}"/>
</jar>
<jar manifest="${build.newt}/manifest.mf" destfile="${newt-driver-intelgdl.jar}" filesonly="true">
<fileset dir="${classes}"
@@ -773,7 +814,7 @@
</jar>
</target>
- <target name="build-jars-android" depends="setup-manifestfile" if="isAndroid">
+ <target name="build-jars-android" depends="setup-manifestfile" if="android-jars.available">
<jar manifest="${build.newt}/manifest.mf" destfile="${newt-driver-android.jar}" filesonly="true">
<fileset dir="${classes}"
includes="${java.part.driver.android}"/>
diff --git a/make/build-test.xml b/make/build-test.xml
index f295ae3..3402b4d 100644
--- a/make/build-test.xml
+++ b/make/build-test.xml
@@ -96,7 +96,7 @@
</jar>
</target>
- <target name="test.compile.android" if="isAndroid">
+ <target name="test.compile.android" if="android-jars.available">
<!-- Perform the junit pass Java Android compile -->
<javac destdir="${classes}"
fork="yes"
@@ -129,7 +129,9 @@
includes="${java.part.test.all}"/>
<fileset dir="resources/assets-test" includes="**" />
</jar>
+ </target>
+ <target name="test.package.android" depends="test.compile.android" if="isAndroid">
<aapt.signed
assetsdir="resources/assets-test"
jarsrcdir="${src}/test"
@@ -171,7 +173,7 @@
</fileset>
</copy>
<antcall target="test.compile.javase" inheritRefs="true" inheritAll="true"/>
- <antcall target="test.compile.android" inheritRefs="true" inheritAll="true"/>
+ <antcall target="test.package.android" inheritRefs="true" inheritAll="true"/>
</target>
<target name="test.manual.run" depends="test.compile">
@@ -865,7 +867,7 @@ rsync:
-rt
-->
- <target name="junit.run.remote.adb" if="isAndroidARMv7">
+ <target name="junit.run.remote.adb" if="isAndroidARMv6">
<echo message="#! /system/bin/sh${line.separator}" append="false" file="${build.test}/targetcommand.sh" />
<echo message="${line.separator}
rsync -rtv --delete --delete-after --delete-excluded \${line.separator}
diff --git a/make/build.xml b/make/build.xml
index 23aa218..44adf80 100644
--- a/make/build.xml
+++ b/make/build.xml
@@ -98,7 +98,7 @@
</copy>
</target>
- <target name="one.jar.dir.android" depends="one.jar.dir.prep" if="isAndroid" unless="one.dir.skip">
+ <target name="one.jar.dir.android" depends="one.jar.dir.prep" if="android-jars.available" unless="one.dir.skip">
<jar manifest="${build.jogl}/manifest.mf" destfile="${jogl-all-android.jar}" filesonly="true" excludes="META-INF/*">
<archives>
<zips>
diff --git a/make/config/jogl/cgl-macosx.cfg b/make/config/jogl/cgl-macosx.cfg
index 7d17c4a..203802d 100644
--- a/make/config/jogl/cgl-macosx.cfg
+++ b/make/config/jogl/cgl-macosx.cfg
@@ -10,6 +10,10 @@ Include gl-common.cfg
Include gl-common-extensions.cfg
Include gl-desktop.cfg
+# Only NIO direct function, no arrays ..
+NIOOnly __ALL__
+NIODirectOnly __ALL__
+
GLHeader GL/cglext.h
Opaque long void *
diff --git a/make/config/jogl/cglext.cfg b/make/config/jogl/cglext.cfg
index 34a59dd..3c67084 100644
--- a/make/config/jogl/cglext.cfg
+++ b/make/config/jogl/cglext.cfg
@@ -14,6 +14,10 @@ ImplJavaClass CGLExtImpl
Include gl-common.cfg
Include gl-desktop.cfg
+# Only NIO direct function, no arrays ..
+NIOOnly __ALL__
+NIODirectOnly __ALL__
+
GLHeader GL/cglext.h
EmitProcAddressTable true
diff --git a/make/config/jogl/egl.cfg b/make/config/jogl/egl.cfg
index ee74b46..b309850 100644
--- a/make/config/jogl/egl.cfg
+++ b/make/config/jogl/egl.cfg
@@ -9,6 +9,10 @@ Style AllStatic
# Shouldn't matter which one of these we pick up
Include egl-common.cfg
+# Only NIO direct function, no arrays ..
+NIOOnly __ALL__
+NIODirectOnly __ALL__
+
HierarchicalNativeOutput false
# Use a ProcAddressTable so we dynamically look up the routines
@@ -44,7 +48,7 @@ CustomJavaCode EGL {
CustomJavaCode EGL if (eglGetProcAddressHandle == 0) {
CustomJavaCode EGL throw new GLException("Passed null pointer for method \"eglGetProcAddress\"");
CustomJavaCode EGL }
-CustomJavaCode EGL return dispatch_eglGetProcAddress1(procname, eglGetProcAddressHandle);
+CustomJavaCode EGL return dispatch_eglGetProcAddress0(procname, eglGetProcAddressHandle);
CustomJavaCode EGL }
diff --git a/make/config/jogl/eglext.cfg b/make/config/jogl/eglext.cfg
index 2e422ff..a7fb454 100644
--- a/make/config/jogl/eglext.cfg
+++ b/make/config/jogl/eglext.cfg
@@ -11,6 +11,10 @@ ImplJavaClass EGLExtImpl
# Shouldn't matter which one of these we pick up
Include egl-common.cfg
+# Only NIO direct function, no arrays ..
+NIOOnly __ALL__
+NIODirectOnly __ALL__
+
ExtendedInterfaceSymbolsIgnore ../build-temp/gensrc/classes/jogamp/opengl/egl/EGL.java
HierarchicalNativeOutput false
diff --git a/make/config/jogl/gl-common.cfg b/make/config/jogl/gl-common.cfg
index 9c54675..f8f4f07 100644
--- a/make/config/jogl/gl-common.cfg
+++ b/make/config/jogl/gl-common.cfg
@@ -360,48 +360,55 @@ ReturnsString glGetStringi
# NIOOnly __ALL__
#
-# NIODirectOnly directives for vertex arrays and other core routines
+# NIODirectOnly directives for pointer functions
+# essential where memory needs to be kept pinpointed after the function call.
# essential where the buffer lifecycle extends the function call.
#
-# Note: API calls like glColorPointer(..) will not be exploded to
-# multiple primitive arrays, since the pointer argument is 'void *'.
+# Note-1: API calls like glColorPointer(..) will not be exploded to
+# multiple primitive arrays, since the pointer argument is 'void *'.
#
-
-#NIO Review: No technical reason to constrain array access for these:
-#NIODirectOnly glColorPointer
-#NIODirectOnly glEdgeFlagPointer
-#NIODirectOnly glIndexPointer
-#NIODirectOnly glNormalPointer
-#NIODirectOnly glTexCoordPointer
-#NIODirectOnly glVertexPointer
-#NIODirectOnly glVertexAttribPointer
-#NIODirectOnly glFogCoordPointer
-#NIODirectOnly glSecondaryColorPointer
-
-#Return values
-#NIODirectOnly glGenBuffers
-#NIODirectOnly glGetPointerv
-#NIODirectOnly glFeedbackBuffer
-#NIODirectOnly glSelectBuffer
-#NIODirectOnly glGetBufferSubData
-
-#
-# NIODirectOnly directives for other extensions
+# Note-2: It may be possible to track the primitive non-direct NIO backed arrays and pinpoint them.
+# JNI's Get*ArrayElements may be able to pinpoint, however it could result
+# in a copy of the data, which would render this feature non performant.
+# The tracking itself may be another no-go, since it would add up complexity
+# and failing to free resources would be another negative sideeffect.
#
-#NIO Review: No technical reason to constrain array access for these:
-#NIODirectOnly glMatrixIndexPointerARB
+NIODirectOnly glColorPointer
+NIODirectOnly glEdgeFlagPointer
+NIODirectOnly glFeedbackBuffer
+NIODirectOnly glFogCoordPointer
+NIODirectOnly glGetBufferSubData
NIODirectOnly glGetProgramStringARB
+NIODirectOnly glIndexPointer
+NIODirectOnly glMatrixIndexPointerARB
+NIODirectOnly glMultiTexCoordPointerEXT
+NIODirectOnly glNormalPointer
NIODirectOnly glPixelDataRangeNV
+NIODirectOnly glSecondaryColorPointer
+NIODirectOnly glSelectBuffer
+NIODirectOnly glTangentPointerEXT
+NIODirectOnly glTexCoordPointer
+NIODirectOnly glVariantPointerEXT
NIODirectOnly glVertexArrayRangeNV
NIODirectOnly glVertexArrayRangeApple
+NIODirectOnly glVertexAttribIPointer
+NIODirectOnly glVertexAttribLPointer
+NIODirectOnly glVertexAttribPointer
+NIODirectOnly glVertexPointer
+NIODirectOnly glVertexWeightPointerEXT
+NIODirectOnly glWeightPointerARB
NIODirectOnly wglFreeMemoryNV
NIODirectOnly glXFreeMemoryNV
+#NIO Review: No technical reason to constrain array access for these:
+#Return values
+#NIODirectOnly glGenBuffers
+#NIODirectOnly glGetPointerv
+
#
-# NIOOnly for a few API calls ..
+# NIODirectOnly directives for other extensions
#
-NIOOnly glVertexAttribPointerNV
-NIOOnly glVertexWeightPointerEXT
+#NIO Review: No technical reason to constrain array access for these:
# Capacity of wglAllocateMemoryNV/glXAllocateMemoryNV return value is
# same as value of first argument
@@ -532,6 +539,8 @@ BufferObjectKind Array glVertexPointer
BufferObjectKind Array glVertexAttribPointer
BufferObjectKind Array glVertexAttribPointerARB
BufferObjectKind Array glVertexAttribPointerNV
+BufferObjectKind Array glVertexAttribIPointer
+BufferObjectKind Array glVertexAttribLPointer
BufferObjectKind Array glVertexWeightPointerEXT
BufferObjectKind Array glWeightPointerARB
@@ -604,6 +613,8 @@ RangeCheck glTexCoordPointer 3 1
RangeCheck glVariantPointerEXT 3 1
RangeCheck glVertexPointer 3 1
RangeCheck glVertexAttribPointer 5 1
+RangeCheck glVertexAttribIPointer 4 1
+RangeCheck glVertexAttribLPointer 4 1
RangeCheck glVertexAttribPointerARB 5 1
RangeCheck glWeightPointerARB 3 1
diff --git a/make/config/jogl/gl-gl4bc.cfg b/make/config/jogl/gl-gl4bc.cfg
index ae77b2e..ce68831 100644
--- a/make/config/jogl/gl-gl4bc.cfg
+++ b/make/config/jogl/gl-gl4bc.cfg
@@ -87,6 +87,16 @@ CustomJavaCode GL4bcImpl glFrustum((double)left, (double)right, (double)bottom
CustomJavaCode GL4bcImpl public void glOrthof(float left, float right, float bottom, float top, float zNear, float zFar) {
CustomJavaCode GL4bcImpl glOrtho((double)left, (double)right, (double)bottom, (double)top, (double)zNear, (double)zFar); }
+JavaPrologue glDepthRangef if ( !_context.isGLES2Compatible() ) {
+JavaPrologue glDepthRangef glDepthRange( (double)zNear, (double)zFar );
+JavaPrologue glDepthRangef return;
+JavaPrologue glDepthRangef }
+
+JavaPrologue glClearDepthf if ( !_context.isGLES2Compatible() ) {
+JavaPrologue glClearDepthf glClearDepth( (double)depth );
+JavaPrologue glClearDepthf return;
+JavaPrologue glClearDepthf }
+
Include gl-headers.cfg
Include gl3ext-headers.cfg
diff --git a/make/config/jogl/gl-impl-CustomJavaCode-common.java b/make/config/jogl/gl-impl-CustomJavaCode-common.java
index b05ba26..283a4e6 100644
--- a/make/config/jogl/gl-impl-CustomJavaCode-common.java
+++ b/make/config/jogl/gl-impl-CustomJavaCode-common.java
@@ -51,6 +51,26 @@
}
@Override
+ public final boolean hasBasicFBOSupport() {
+ return _context.hasBasicFBOSupport();
+ }
+
+ @Override
+ public final boolean hasFullFBOSupport() {
+ return _context.hasFullFBOSupport();
+ }
+
+ @Override
+ public final int getMaxRenderbufferSamples() {
+ return _context.getMaxRenderbufferSamples();
+ }
+
+ @Override
+ public final boolean isTextureFormatBGRA8888Available() {
+ return _context.isTextureFormatBGRA8888Available();
+ }
+
+ @Override
public final GLContext getContext() {
return _context;
}
diff --git a/make/config/jogl/gl2_es2-common.cfg b/make/config/jogl/gl2_es2-common.cfg
index d26c76e..b769f3b 100644
--- a/make/config/jogl/gl2_es2-common.cfg
+++ b/make/config/jogl/gl2_es2-common.cfg
@@ -11,13 +11,3 @@ JavaPrologue glGetShaderPrecisionFormat if ( !_context.isGLES2Compatible() ) {
JavaPrologue glGetShaderPrecisionFormat throw new GLException("Method \"glGetShaderPrecisionFormat\" not available");
JavaPrologue glGetShaderPrecisionFormat }
-JavaPrologue glDepthRangef if ( !_context.isGLES2Compatible() ) {
-JavaPrologue glDepthRangef glDepthRange( (double)zNear, (double)zFar );
-JavaPrologue glDepthRangef return;
-JavaPrologue glDepthRangef }
-
-JavaPrologue glClearDepthf if ( !_context.isGLES2Compatible() ) {
-JavaPrologue glClearDepthf glClearDepth( (double)depth );
-JavaPrologue glClearDepthf return;
-JavaPrologue glClearDepthf }
-
diff --git a/make/config/jogl/glx-CustomCCode.c b/make/config/jogl/glx-CustomCCode.c
index e372e51..71dc68b 100644
--- a/make/config/jogl/glx-CustomCCode.c
+++ b/make/config/jogl/glx-CustomCCode.c
@@ -89,36 +89,30 @@ Java_jogamp_opengl_x11_glx_GLX_dispatch_1glXGetVisualFromFBConfig(JNIEnv *env, j
/* Java->C glue code:
* Java package: jogamp.opengl.x11.glx.GLX
- * Java method: java.nio.LongBuffer glXChooseFBConfig(long dpy, int screen, java.nio.IntBuffer attribList, java.nio.IntBuffer nitems)
+ * Java method: com.jogamp.common.nio.PointerBuffer dispatch_glXChooseFBConfig(long dpy, int screen, java.nio.IntBuffer attribList, java.nio.IntBuffer nitems)
* C function: GLXFBConfig * glXChooseFBConfig(Display * dpy, int screen, const int * attribList, int * nitems);
*/
JNIEXPORT jobject JNICALL
Java_jogamp_opengl_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;
+ typedef GLXFBConfig * (APIENTRY*_local_PFNGLXCHOOSEFBCONFIGPROC)(Display * dpy, int screen, const int * attribList, int * nitems);
+ _local_PFNGLXCHOOSEFBCONFIGPROC ptr_glXChooseFBConfig;
+ int * _attribList_ptr = NULL;
+ int * _nitems_ptr = NULL;
GLXFBConfig * _res;
int count;
jobject jbyteSource;
jobject jbyteCopy;
- ptr_glXChooseFBConfig = (_local_PFNGLXCHOOSEFBCONFIG) (intptr_t) procAddress;
+ if ( NULL != attribList ) {
+ _attribList_ptr = (int *) (((char*) (*env)->GetDirectBufferAddress(env, attribList)) + attribList_byte_offset);
+ }
+ if ( NULL != nitems ) {
+ _nitems_ptr = (int *) (((char*) (*env)->GetDirectBufferAddress(env, nitems)) + nitems_byte_offset);
+ }
+ ptr_glXChooseFBConfig = (_local_PFNGLXCHOOSEFBCONFIGPROC) (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 = (*ptr_glXChooseFBConfig)((Display *) (intptr_t) dpy, (int) screen, (int *) _ptr2, (int *) _ptr3);
- count = _ptr3[0];
- if (attribList != NULL) {
- (*env)->ReleasePrimitiveArrayCritical(env, attribList, _ptr2, 0);
- }
- if (nitems != NULL) {
- (*env)->ReleasePrimitiveArrayCritical(env, nitems, _ptr3, 0);
- }
- if (_res == NULL) return NULL;
+ _res = (* ptr_glXChooseFBConfig) ((Display *) (intptr_t) dpy, (int) screen, (int *) _attribList_ptr, (int *) _nitems_ptr);
+ count = _nitems_ptr[0];
+ if (NULL == _res) return NULL;
_initClazzAccess(env);
@@ -130,29 +124,27 @@ Java_jogamp_opengl_x11_glx_GLX_dispatch_1glXChooseFBConfig(JNIEnv *env, jclass _
return jbyteCopy;
}
+
/* Java->C glue code:
* Java package: jogamp.opengl.x11.glx.GLX
- * Java method: XVisualInfo glXChooseVisual(long dpy, int screen, java.nio.IntBuffer attribList)
+ * Java method: XVisualInfo dispatch_glXChooseVisual(long dpy, int screen, java.nio.IntBuffer attribList)
* C function: XVisualInfo * glXChooseVisual(Display * dpy, int screen, int * attribList);
*/
JNIEXPORT jobject JNICALL
Java_jogamp_opengl_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;
+ typedef XVisualInfo * (APIENTRY*_local_PFNGLXCHOOSEVISUALPROC)(Display * dpy, int screen, int * attribList);
+ _local_PFNGLXCHOOSEVISUALPROC ptr_glXChooseVisual;
+ int * _attribList_ptr = NULL;
XVisualInfo * _res;
jobject jbyteSource;
jobject jbyteCopy;
- ptr_glXChooseVisual = (_local_PFNGLXCHOOSEVISUAL) (intptr_t) procAddress;
+ if ( NULL != attribList ) {
+ _attribList_ptr = (int *) (((char*) (*env)->GetDirectBufferAddress(env, attribList)) + attribList_byte_offset);
+ }
+ ptr_glXChooseVisual = (_local_PFNGLXCHOOSEVISUALPROC) (intptr_t) procAddress;
assert(ptr_glXChooseVisual != NULL);
- if (attribList != NULL) {
- _ptr2 = (int *) (((char*) (*env)->GetPrimitiveArrayCritical(env, attribList, NULL)) + attribList_byte_offset);
- }
- _res = (*ptr_glXChooseVisual)((Display *) (intptr_t) dpy, (int) screen, (int *) _ptr2);
- if (attribList != NULL) {
- (*env)->ReleasePrimitiveArrayCritical(env, attribList, _ptr2, 0);
- }
- if (_res == NULL) return NULL;
+ _res = (* ptr_glXChooseVisual) ((Display *) (intptr_t) dpy, (int) screen, (int *) _attribList_ptr);
+ if (NULL == _res) return NULL;
_initClazzAccess(env);
diff --git a/make/config/jogl/glx-CustomJavaCode.java b/make/config/jogl/glx-CustomJavaCode.java
index 36ad100..ed126a5 100644
--- a/make/config/jogl/glx-CustomJavaCode.java
+++ b/make/config/jogl/glx-CustomJavaCode.java
@@ -16,43 +16,49 @@
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 glXChooseFBConfig(long dpy, int screen, int[] attribList, int attribList_offset, int[] nitems, int nitems_offset)
- {
+ /** Entry point to C language function: <code> GLXFBConfig * glXChooseFBConfig(Display * dpy, int screen, const int * attribList, int * nitems); </code> <br>Part of CORE FUNC
+ @param attribList a direct only {@link java.nio.IntBuffer}
+ @param nitems a direct only {@link java.nio.IntBuffer} */
+ public static PointerBuffer glXChooseFBConfig(long dpy, int screen, IntBuffer attribList, IntBuffer nitems) {
+
+ if (!Buffers.isDirect(attribList))
+ throw new GLException("Argument \"attribList\" is not a direct buffer");
+ if (!Buffers.isDirect(nitems))
+ throw new GLException("Argument \"nitems\" is not a direct buffer");
final long __addr_ = glxProcAddressTable._addressof_glXChooseFBConfig;
if (__addr_ == 0) {
- throw new GLException("Method \"glXChooseFBConfig\" not available");
+ throw new GLException("Method \"glXChooseFBConfig\" 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 = dispatch_glXChooseFBConfig(dpy, screen, attribList, Buffers.SIZEOF_INT * attribList_offset, nitems, Buffers.SIZEOF_INT * nitems_offset, __addr_);
-
+ final ByteBuffer _res;
+ _res = dispatch_glXChooseFBConfig(dpy, screen, attribList, Buffers.getDirectBufferByteOffset(attribList), nitems, Buffers.getDirectBufferByteOffset(nitems), __addr_);
if (_res == null) return null;
+ Buffers.nativeOrder(_res);
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 dispatch_glXChooseFBConfig(long dpy, int screen, Object attribList, int attribList_byte_offset, Object nitems, int nitems_byte_offset, long procAddr);
+ /** Entry point to C language function: <code> GLXFBConfig * glXChooseFBConfig(Display * dpy, int screen, const int * attribList, int * nitems); </code> <br>Part of CORE FUNC
+ @param attribList a direct only {@link java.nio.IntBuffer}
+ @param nitems a direct only {@link java.nio.IntBuffer} */
+ private static native ByteBuffer dispatch_glXChooseFBConfig(long dpy, int screen, Object attribList, int attribList_byte_offset, Object nitems, int nitems_byte_offset, long procAddress);
- /** Interface to C language function: <br> - Alias for: <br> <code> XVisualInfo * glXChooseVisual(Display * dpy, int screen, int * attribList); </code> */
- public static XVisualInfo glXChooseVisual(long dpy, int screen, int[] attribList, int attribList_offset)
- {
+
+ /** Entry point to C language function: <code> XVisualInfo * glXChooseVisual(Display * dpy, int screen, int * attribList); </code> <br>Part of <code>GLX_VERSION_1_X</code>
+ @param attribList a direct only {@link java.nio.IntBuffer} */
+ public static XVisualInfo glXChooseVisual(long dpy, int screen, IntBuffer attribList) {
+
+ if (!Buffers.isDirect(attribList))
+ throw new GLException("Argument \"attribList\" is not a direct buffer");
final long __addr_ = glxProcAddressTable._addressof_glXChooseVisual;
if (__addr_ == 0) {
- throw new GLException("Method \"glXChooseVisual\" not available");
+ 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 = dispatch_glXChooseVisual(dpy, screen, attribList, Buffers.SIZEOF_INT * attribList_offset, __addr_);
-
+ final ByteBuffer _res;
+ _res = dispatch_glXChooseVisual(dpy, screen, attribList, Buffers.getDirectBufferByteOffset(attribList), __addr_);
if (_res == null) return null;
- return XVisualInfo.create(_res);
+ return XVisualInfo.create(Buffers.nativeOrder(_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 dispatch_glXChooseVisual(long dpy, int screen, Object attribList, int attribList_byte_offset, long procAddr);
+ /** Entry point to C language function: <code> XVisualInfo * glXChooseVisual(Display * dpy, int screen, int * attribList); </code> <br>Part of <code>GLX_VERSION_1_X</code>
+ @param attribList a direct only {@link java.nio.IntBuffer} */
+ private static native ByteBuffer dispatch_glXChooseVisual(long dpy, int screen, Object attribList, int attribList_byte_offset, long procAddress);
diff --git a/make/config/jogl/glx-x11.cfg b/make/config/jogl/glx-x11.cfg
index 4daa78b..017b1e0 100644
--- a/make/config/jogl/glx-x11.cfg
+++ b/make/config/jogl/glx-x11.cfg
@@ -13,6 +13,10 @@ Include gl-desktop.cfg
GLHeader GL/glx.h
GLHeader GL/glxext.h
+# Only NIO direct function, no arrays ..
+NIOOnly __ALL__
+NIODirectOnly __ALL__
+
ForceProcAddressGen __ALL__
LocalProcAddressCallingConvention __ALL__ APIENTRY
@@ -95,6 +99,6 @@ 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 return dispatch_glXGetProcAddress0(procname, glXGetProcAddressHandle);
CustomJavaCode GLX }
diff --git a/make/config/jogl/glxext.cfg b/make/config/jogl/glxext.cfg
index de23b9f..c73753e 100644
--- a/make/config/jogl/glxext.cfg
+++ b/make/config/jogl/glxext.cfg
@@ -13,6 +13,10 @@ ExtendedInterfaceSymbolsIgnore ../build-temp/gensrc/classes/jogamp/opengl/x11/gl
Include gl-common.cfg
Include gl-desktop.cfg
+# Only NIO direct function, no arrays ..
+NIOOnly __ALL__
+NIODirectOnly __ALL__
+
GLHeader GL/glx.h
GLHeader GL/glxext.h
diff --git a/make/config/jogl/wgl-win32.cfg b/make/config/jogl/wgl-win32.cfg
index 4d2fea5..d9dbb13 100644
--- a/make/config/jogl/wgl-win32.cfg
+++ b/make/config/jogl/wgl-win32.cfg
@@ -18,6 +18,10 @@ GLHeader GL/wglext.h
ForceProcAddressGen __ALL__
LocalProcAddressCallingConvention __ALL__ APIENTRY
+# Only NIO direct function, no arrays ..
+NIOOnly __ALL__
+NIODirectOnly __ALL__
+
AllowNonGLExtensions true
EmitProcAddressTable true
ProcAddressTableClassName WGLProcAddressTable
@@ -63,6 +67,6 @@ 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 return dispatch_wglGetProcAddress0(procname, wglGetProcAddressHandle);
CustomJavaCode WGL }
diff --git a/make/config/jogl/wglext.cfg b/make/config/jogl/wglext.cfg
index 15986b6..57707d6 100644
--- a/make/config/jogl/wglext.cfg
+++ b/make/config/jogl/wglext.cfg
@@ -13,6 +13,10 @@ Include gl-desktop.cfg
AllowNonGLExtensions true
+# Only NIO direct function, no arrays ..
+NIOOnly __ALL__
+NIODirectOnly __ALL__
+
GLHeader wingdi.h
GLHeader GL/wglext.h
diff --git a/make/config/nativewindow/x11-CustomJavaCode.java b/make/config/nativewindow/x11-CustomJavaCode.java
index 56aec47..8e5da3b 100644
--- a/make/config/nativewindow/x11-CustomJavaCode.java
+++ b/make/config/nativewindow/x11-CustomJavaCode.java
@@ -36,6 +36,11 @@
}
private static native Object GetRelativeLocation0(long display, int screen_index, long src_win, long dest_win, int src_x, int src_y);
+ public static boolean QueryExtension(long display, String extensionName) {
+ return QueryExtension0(display, extensionName);
+ }
+ private static native boolean QueryExtension0(long display, String extensionName);
+
public static native int XCloseDisplay(long display);
public static native void XUnlockDisplay(long display);
public static native void XLockDisplay(long display);
diff --git a/make/scripts/adb-install-all-armv6.sh b/make/scripts/adb-install-all-armv6.sh
new file mode 100755
index 0000000..0ba9f3c
--- /dev/null
+++ b/make/scripts/adb-install-all-armv6.sh
@@ -0,0 +1,4 @@
+#adb $* install ../../gluegen/build-android-armv6/jogamp-android-launcher.apk
+#adb $* install ../../gluegen/build-android-armv6/gluegen-rt-android-armeabi.apk
+adb $* install ../build-android-armv6/jar/jogl-all-android-armeabi.apk
+adb $* install ../build-android-armv6/jar/jogl-test-android.apk
diff --git a/make/scripts/adb-launch-main.sh b/make/scripts/adb-launch-main.sh
index ff47a7a..6d67192 100644
--- a/make/scripts/adb-launch-main.sh
+++ b/make/scripts/adb-launch-main.sh
@@ -12,7 +12,7 @@ export TARGET_IP=jautab01
export TARGET_ADB_PORT=5555
export TARGET_ROOT=/data/projects
-export BUILD_DIR=../build-android-armv7
+export BUILD_DIR=../build-android-armv6
if [ -e /opt-linux-x86/android-sdk-linux_x86 ] ; then
export ANDROID_SDK_HOME=/opt-linux-x86/android-sdk-linux_x86
@@ -61,9 +61,9 @@ am start -a android.intent.action.MAIN -n jogamp.android.launcher/jogamp.android
# \
#dalvikvm \
# -Xjnigreflimit:2000 \
-# -cp ../../gluegen/make/$BUILD_DIR/jogamp.android-launcher.apk:../../gluegen/make/lib/ant-junit-all.apk:../../gluegen/make/$BUILD_DIR/gluegen-rt-android-armeabi-v7a.apk:$BUILD_DIR/jar/jogl.all-android-armeabi-v7a.apk:$BUILD_DIR/jar/jogl.test.apk \
+# -cp ../../gluegen/make/$BUILD_DIR/jogamp.android-launcher.apk:../../gluegen/make/lib/ant-junit-all.apk:../../gluegen/make/$BUILD_DIR/gluegen-rt-android-armeabi.apk:$BUILD_DIR/jar/jogl.all-android-armeabi.apk:$BUILD_DIR/jar/jogl.test.apk \
# -Dgluegen.root=../../gluegen \
-# -Drootrel.build=build-android-armv7 \
+# -Drootrel.build=build-android-armv6 \
# com.android.internal.util.WithFramework \
# $TSTCLASS \
" >> $BUILD_DIR/jogl-targetcommand.sh
diff --git a/make/scripts/adb-reinstall-all-armv6.sh b/make/scripts/adb-reinstall-all-armv6.sh
new file mode 100755
index 0000000..0e62c59
--- /dev/null
+++ b/make/scripts/adb-reinstall-all-armv6.sh
@@ -0,0 +1,5 @@
+sdir=`dirname $0`
+
+$sdir/adb-uninstall-all.sh $*
+$sdir/adb-install-all-armv6.sh $*
+
diff --git a/make/scripts/java-win32-dbg.bat b/make/scripts/java-win32-dbg.bat
index 6f82067..e0760d0 100755
--- a/make/scripts/java-win32-dbg.bat
+++ b/make/scripts/java-win32-dbg.bat
@@ -1,26 +1,27 @@
set BLD_SUB=build-win32
-set J2RE_HOME=c:\jre1.6.0_30_x32
-set JAVA_HOME=c:\jdk1.6.0_30_x32
+set J2RE_HOME=c:\jre1.6.0_35_x32
+set JAVA_HOME=c:\jdk1.6.0_35_x32
set ANT_PATH=C:\apache-ant-1.8.2
set PROJECT_ROOT=D:\projects\jogamp\jogl
set BLD_DIR=..\%BLD_SUB%
-set FFMPEG_LIB=%PROJECT_ROOT%\make\lib\ffmpeg\x32
-
-REM set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%FFMPEG_LIB%;%PATH%
-REM set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%PROJECT_ROOT%\make\lib\external\angle\win32;%PATH%
-set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%PROJECT_ROOT%\make\lib\external\PVRVFrame\OGLES-2.0\Windows_x86_32;%PATH%
+REM set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%PATH%
+REM set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%PROJECT_ROOT%\make\lib\external\angle\win32\20120127;%PATH%
+set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%PROJECT_ROOT%\make\lib\external\angle\win32\20121010-chrome;%PATH%
+REM set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%PROJECT_ROOT%\make\lib\external\PVRVFrame\OGLES-2.0\Windows_x86_32;%PATH%
REM set LIB_DIR=%BLD_DIR%\lib;..\..\gluegen\%BLD_SUB%\obj
-set LIB_DIR=%FFMPEG_LIB%
+REM set FFMPEG_LIB=%PROJECT_ROOT%\make\lib\ffmpeg\x32
+REM set LIB_DIR=%FFMPEG_LIB%
+set LIB_DIR=
set CP_ALL=.;%BLD_DIR%\jar\jogl-all.jar;%BLD_DIR%\jar\jogl-test.jar;..\..\gluegen\%BLD_SUB%\gluegen-rt.jar;..\..\gluegen\make\lib\junit.jar;%ANT_PATH%\lib\ant.jar;%ANT_PATH%\lib\ant-junit.jar;%BLD_DIR%\..\make\lib\swt\win32-win32-x86\swt-debug.jar
echo CP_ALL %CP_ALL%
-set D_ARGS="-Djogl.debug.GLContext" "-Djogl.debug.FBObject"
+set D_ARGS="-Djogl.debug.GLDrawable" "-Djogl.debug.GLContext" "-Djogl.debug.FBObject" "-Djogl.enable.ANGLE"
REM set D_ARGS="-Djogl.debug.GLDrawable" "-Djogl.debug.EGLDrawableFactory.DontQuery"
REM set D_ARGS="-Djogl.debug.GLDrawable" "-Djogl.debug.EGLDrawableFactory.QueryNativeTK"
REM set D_ARGS="-Djogl.debug=all" "-Dnewt.debug=all" "-Dnativewindow.debug=all"
diff --git a/make/scripts/java-win32.bat b/make/scripts/java-win32.bat
index 1d84302..d357157 100755
--- a/make/scripts/java-win32.bat
+++ b/make/scripts/java-win32.bat
@@ -1,18 +1,21 @@
set BLD_SUB=build-win32
-set J2RE_HOME=c:\jre1.6.0_30_x32
-set JAVA_HOME=c:\jdk1.6.0_30_x32
+set J2RE_HOME=c:\jre1.6.0_35_x32
+set JAVA_HOME=c:\jdk1.6.0_35_x32
set ANT_PATH=C:\apache-ant-1.8.2
set PROJECT_ROOT=D:\projects\jogamp\jogl
set BLD_DIR=..\%BLD_SUB%
-REM set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;c:\mingw\bin;%PATH%
-REM set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%PROJECT_ROOT%\make\lib\angle\win32;%PATH%
-set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%PROJECT_ROOT%\make\lib\PVRVFrame\OGLES-2.0\Windows_x86_32;%PATH%
+REM set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%PATH%
+REM set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%PROJECT_ROOT%\make\lib\external\angle\win32\20120127;%PATH%
+set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%PROJECT_ROOT%\make\lib\external\angle\win32\20121010-chrome;%PATH%
+REM set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%PROJECT_ROOT%\make\lib\external\PVRVFrame\OGLES-2.0\Windows_x86_32;%PATH%
set BLD_DIR=..\%BLD_SUB%
REM set LIB_DIR=..\..\gluegen\%BLD_SUB%\obj;%BLD_DIR%\lib
+REM set FFMPEG_LIB=%PROJECT_ROOT%\make\lib\ffmpeg\x32
+REM set LIB_DIR=%FFMPEG_LIB%
set LIB_DIR=
set CP_ALL=.;%BLD_DIR%\jar\jogl-all.jar;%BLD_DIR%\jar\jogl-test.jar;..\..\gluegen\%BLD_SUB%\gluegen-rt.jar;..\..\gluegen\make\lib\junit.jar;%ANT_PATH%\lib\ant.jar;%ANT_PATH%\lib\ant-junit.jar;%BLD_DIR%\..\make\lib\swt\win32-win32-x86\swt-debug.jar
diff --git a/make/scripts/java-win64-dbg.bat b/make/scripts/java-win64-dbg.bat
index c8a9045..5dc34f4 100755
--- a/make/scripts/java-win64-dbg.bat
+++ b/make/scripts/java-win64-dbg.bat
@@ -1,7 +1,7 @@
set BLD_SUB=build-win64
-set J2RE_HOME=c:\jre1.6.0_30_x64
-set JAVA_HOME=c:\jdk1.6.0_30_x64
+set J2RE_HOME=c:\jre1.6.0_35_x64
+set JAVA_HOME=c:\jdk1.6.0_35_x64
set ANT_PATH=C:\apache-ant-1.8.2
set PROJECT_ROOT=D:\projects\jogamp\jogl
@@ -30,6 +30,7 @@ REM set D_ARGS="-Djogl.debug.ExtensionAvailabilityCache" "-Djogl.debug=all" "-Dn
REM set D_ARGS="-Djogl.debug=all" "-Dnewt.debug=all" "-Dnativewindow.debug=all" "-Djogamp.debug.NativeLibrary=true"
REM set D_ARGS="-Djogl.debug.GLContext" "-Djogl.debug.ExtensionAvailabilityCache" "-Djogamp.debug.ProcAddressHelper=true"
REM set D_ARGS="-Djogl.debug.GraphicsConfiguration"
+REM set D_ARGS="-Djogl.debug.GLContext" "-Djogl.debug.GLDrawable" "-Dnativewindow.debug.GraphicsConfiguration"
REM set D_ARGS="-Djogamp.debug.JNILibLoader=true" "-Djogamp.debug.NativeLibrary=true" "-Djogamp.debug.NativeLibrary.Lookup=true" "-Djogl.debug.GLProfile=true"
REM set D_ARGS="-Djogl.debug=all" "-Dnewt.debug=all" "-Dnativewindow.debug=all" "-Djogamp.debug.Lock" "-Djogamp.debug.Lock.TraceLock"
REM set D_ARGS="-Djogl.debug=all" "-Dnativewindow.debug=all"
@@ -37,7 +38,9 @@ REM set D_ARGS="-Djogl.debug=all"
REM set D_ARGS="-Djogl.debug.GLCanvas" "-Djogl.debug.Animator" "-Djogl.debug.GLContext" "-Djogl.debug.GLContext.TraceSwitch" "-Djogl.debug.DebugGL" "-Djogl.debug.TraceGL"
REM set D_ARGS="-Djogl.debug.GLCanvas" "-Djogl.debug.Animator" "-Djogl.debug.GLContext" "-Djogl.debug.GLContext.TraceSwitch" "-Djogl.windows.useWGLVersionOf5WGLGDIFuncSet"
REM set D_ARGS="-Djogl.debug.GLCanvas" "-Djogl.debug.Animator" "-Djogl.debug.GLContext" "-Djogl.debug.GLContext.TraceSwitch"
-set D_ARGS="-Dnewt.debug.Window" "-Dnewt.debug.Display"
+REM set D_ARGS="-Dnewt.debug.Window"
+REM set D_ARGS="-Dnewt.debug.Window.KeyEvent"
+REM set D_ARGS="-Dnewt.debug.Window" "-Dnewt.debug.Display"
REM set D_ARGS="-Djogl.debug.GLDebugMessageHandler" "-Djogl.debug.DebugGL" "-Djogl.debug.TraceGL"
REM set D_ARGS="-Djogl.debug.DebugGL" "-Djogl.debug.GLDebugMessageHandler" "-Djogl.debug.GLSLCode"
REM set D_ARGS="-Djogl.debug.GLContext" "-Dnewt.debug=all"
@@ -51,4 +54,5 @@ REM set X_ARGS="-Dsun.java2d.noddraw=true" "-Dsun.java2d.opengl=true" "-Dsun.awt
REM set X_ARGS="-Dsun.java2d.noddraw=true" "-Dsun.java2d.d3d=false" "-Dsun.java2d.ddoffscreen=false" "-Dsun.java2d.gdiblit=false" "-Dsun.java2d.opengl=false" "-Dsun.awt.noerasebackground=true" "-Xms512m" "-Xmx1024m"
REM set X_ARGS="-Dsun.java2d.noddraw=true" "-Dsun.java2d.d3d=false" "-Dsun.java2d.ddoffscreen=false" "-Dsun.java2d.gdiblit=false" "-Dsun.java2d.opengl=true" "-Dsun.awt.noerasebackground=true" "-Xms512m" "-Xmx1024m"
-%J2RE_HOME%\bin\java -classpath %CP_ALL% "-Djava.library.path=%LIB_DIR%" %D_ARGS% %X_ARGS% %* > java-win64-dbg.log 2>&1
+REM %J2RE_HOME%\bin\java -classpath %CP_ALL% "-Djava.library.path=%LIB_DIR%" %D_ARGS% %X_ARGS% %* > java-win64-dbg.log 2>&1
+%J2RE_HOME%\bin\java -classpath %CP_ALL% "-Djava.library.path=%LIB_DIR%" %D_ARGS% %X_ARGS% %*
diff --git a/make/scripts/java-win64.bat b/make/scripts/java-win64.bat
index 2c09fee..99f9bdc 100755
--- a/make/scripts/java-win64.bat
+++ b/make/scripts/java-win64.bat
@@ -1,7 +1,7 @@
set BLD_SUB=build-win64
-set J2RE_HOME=c:\jre1.6.0_30_x64
-set JAVA_HOME=c:\jdk1.6.0_30_x64
+set J2RE_HOME=c:\jre1.6.0_35_x64
+set JAVA_HOME=c:\jdk1.6.0_35_x64
set ANT_PATH=C:\apache-ant-1.8.2
REM set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;c:\mingw\bin;%PATH%
diff --git a/make/scripts/lstjars.sh b/make/scripts/lstjars.sh
index 82e378e..5763e41 100755
--- a/make/scripts/lstjars.sh
+++ b/make/scripts/lstjars.sh
@@ -1,5 +1,7 @@
#! /bin/sh
+#set -x
+
THISDIR=$(pwd)
BUILDDIR=$1
@@ -21,7 +23,7 @@ fi
function report() {
#ls -1 -s --block-size=1024 $*
#ls -1 -s --block-size=1024 $* | awk ' BEGIN { sum=0 ; } { sum=sum+$1; } END { printf("%d Total\n", sum); }'
- du -ksc $*
+ du -ksc $* | awk ' { printf("%5d kB %s\n", $1, $2); } '
}
OSS=x11
@@ -35,15 +37,23 @@ function listdeployment() {
echo
echo JOGL ALL
- report gluegen-rt.$JAR_SUFFIX jogl.all.$JAR_SUFFIX libgluegen-rt.so.gz libnativewindow_awt.so.gz libnativewindow_x11.so.gz libjogl_desktop.so.gz libnewt.so.gz
+ report gluegen-rt.$JAR_SUFFIX jogl-all.$JAR_SUFFIX libgluegen-rt.so.gz libnativewindow_awt.so.gz libnativewindow_x11.so.gz libjogl_desktop.so.gz libnewt.so.gz
echo
echo JOGL ALL no AWT
- report gluegen-rt.$JAR_SUFFIX jogl.all-noawt.$JAR_SUFFIX libgluegen-rt.so.gz libnativewindow_x11.so.gz libjogl_desktop.so.gz libnewt.so.gz
+ report gluegen-rt.$JAR_SUFFIX jogl-all-noawt.$JAR_SUFFIX libgluegen-rt.so.gz libnativewindow_x11.so.gz libjogl_desktop.so.gz libnewt.so.gz
+ echo
+
+ echo JOGL Min X11 Min egl es1 es2
+ report gluegen-rt.$JAR_SUFFIX atomic/jogl-core.$JAR_SUFFIX atomic/jogl-glmobile.$JAR_SUFFIX atomic/jogl-util.$JAR_SUFFIX atomic/nativewindow-core.$JAR_SUFFIX atomic/newt-core.$JAR_SUFFIX atomic/nativewindow-os-x11.$JAR_SUFFIX atomic/newt-driver-x11.$JAR_SUFFIX libgluegen-rt.so.gz libjogl_mobile.so.gz libnativewindow_x11.so.gz libnewt.so.gz
echo
echo JOGL Android - mobile egl es1 es2
- report gluegen-rt.$JAR_SUFFIX jogl.all-android.$JAR_SUFFIX libgluegen-rt.so.gz libjogl_mobile.so.gz
+ report gluegen-rt-android.$JAR_SUFFIX jogl-all-android.$JAR_SUFFIX libgluegen-rt.so.gz libjogl_mobile.so.gz
+ echo
+
+ echo JOGL Min Android/Mobile Min egl es1 es2
+ report gluegen-rt-android.$JAR_SUFFIX atomic/jogl-core.$JAR_SUFFIX atomic/jogl-glmobile.$JAR_SUFFIX atomic/jogl-os-android.$JAR_SUFFIX atomic/jogl-util.$JAR_SUFFIX atomic/nativewindow-core.$JAR_SUFFIX atomic/newt-core.$JAR_SUFFIX atomic/newt-driver-android.$JAR_SUFFIX libgluegen-rt.so.gz libjogl_mobile.so.gz
echo
}
@@ -52,6 +62,7 @@ mkdir -p $STATDIR
cp -a $BUILDDIR/lib/*.so $STATDIR
cp -a $BUILDDIR/jar/* $STATDIR
cp -a $BUILDDIR_GLUEGEN/gluegen-rt.jar $STATDIR
+cp -a $BUILDDIR_GLUEGEN/gluegen-rt-android.jar $STATDIR
cp -a $BUILDDIR_GLUEGEN/obj/libgluegen-rt.so $STATDIR
cd $STATDIR
@@ -84,13 +95,14 @@ sort atomic/jogl*.lst | uniq -d
cat atomic/*.lst | sort -u > allparts.lst
mv nope/*jar .
-cat jogl.all.lst gluegen-rt.lst | sort -u > allall.lst
+cat jogl-all.lst gluegen-rt.lst | sort -u > allall.lst
echo all vs allparts delta
echo
diff -Nur allparts.lst allall.lst
-mv nope/* .
+mv nope/*.jar .
+#mv nope/atomic/*.jar atomic/
listdeployment jar
diff --git a/make/scripts/make.jogl.all.android-armv6-cross.sh b/make/scripts/make.jogl.all.android-armv6-cross.sh
new file mode 100755
index 0000000..2625600
--- /dev/null
+++ b/make/scripts/make.jogl.all.android-armv6-cross.sh
@@ -0,0 +1,92 @@
+#! /bin/sh
+
+export NODE_LABEL=.
+
+export HOST_UID=jogamp
+# jogamp02 - 10.1.0.122
+export HOST_IP=10.1.0.122
+export HOST_RSYNC_ROOT=PROJECTS/JOGL
+
+export TARGET_UID=jogamp
+export TARGET_IP=panda02
+#export TARGET_IP=jautab03
+#export TARGET_IP=jauphone04
+export TARGET_ADB_PORT=5555
+# needs executable bit (probably su)
+export TARGET_ROOT=/data/projects
+export TARGET_ANT_HOME=/usr/share/ant
+
+echo ANDROID_SDK_HOME $ANDROID_SDK_HOME
+echo NDK_ROOT $NDK_ROOT
+
+if [ -z "$NDK_ROOT" ] ; then
+ #
+ # Generic android-ndk
+ #
+ if [ -e /usr/local/android-ndk ] ; then
+ NDK_ROOT=/usr/local/android-ndk
+ elif [ -e /opt-linux-x86/android-ndk ] ; then
+ NDK_ROOT=/opt-linux-x86/android-ndk
+ elif [ -e /opt/android-ndk ] ; then
+ NDK_ROOT=/opt/android-ndk
+ #
+ # Specific android-ndk-r7b
+ #
+ elif [ -e /usr/local/android-ndk-r7b ] ; then
+ NDK_ROOT=/usr/local/android-ndk-r7b
+ elif [ -e /opt-linux-x86/android-ndk-r7b ] ; then
+ NDK_ROOT=/opt-linux-x86/android-ndk-r7b
+ elif [ -e /opt/android-ndk-r7b ] ; then
+ NDK_ROOT=/opt/android-ndk-r7b
+ else
+ echo NDK_ROOT is not specified and does not exist in default locations
+ exit 1
+ fi
+elif [ ! -e $NDK_ROOT ] ; then
+ echo NDK_ROOT $NDK_ROOT does not exist
+ exit 1
+fi
+export NDK_ROOT
+
+if [ -z "$ANDROID_SDK_HOME" ] ; then
+ if [ -e /usr/local/android-sdk-linux_x86 ] ; then
+ ANDROID_SDK_HOME=/usr/local/android-sdk-linux_x86
+ elif [ -e /opt-linux-x86/android-sdk-linux_x86 ] ; then
+ ANDROID_SDK_HOME=/opt-linux-x86/android-sdk-linux_x86
+ elif [ -e /opt/android-sdk-linux_x86 ] ; then
+ ANDROID_SDK_HOME=/opt/android-sdk-linux_x86
+ else
+ echo ANDROID_SDK_HOME is not specified and does not exist in default locations
+ exit 1
+ fi
+elif [ ! -e $ANDROID_SDK_HOME ] ; then
+ echo ANDROID_SDK_HOME $ANDROID_SDK_HOME does not exist
+ exit 1
+fi
+export ANDROID_SDK_HOME
+
+export ANDROID_VERSION=9
+export SOURCE_LEVEL=1.6
+export TARGET_LEVEL=1.6
+export TARGET_RT_JAR=/opt-share/jre1.6.0_30/lib/rt.jar
+
+export GCC_VERSION=4.4.3
+HOST_ARCH=linux-x86
+export TARGET_TRIPLE=arm-linux-androideabi
+
+export NDK_TOOLCHAIN_ROOT=$NDK_ROOT/toolchains/${TARGET_TRIPLE}-${GCC_VERSION}/prebuilt/${HOST_ARCH}
+export TARGET_PLATFORM_ROOT=${NDK_ROOT}/platforms/android-${ANDROID_VERSION}/arch-arm
+
+# Need to add toolchain bins to the PATH.
+export PATH="$NDK_TOOLCHAIN_ROOT/$TARGET_TRIPLE/bin:$ANDROID_SDK_HOME/platform-tools:$PATH"
+
+export GLUEGEN_CPPTASKS_FILE=`pwd`/../../gluegen/make/lib/gluegen-cpptasks-android-armv6.xml
+
+#export JUNIT_DISABLED="true"
+#export JUNIT_RUN_ARG0="-Dnewt.test.Screen.disableScreenMode"
+
+# BUILD_ARCHIVE=true \
+ant \
+ -Drootrel.build=build-android-armv6 \
+ $* 2>&1 | tee -a make.jogl.all.android-armv6-cross.log
+
diff --git a/make/scripts/make.jogl.all.linux-armv7-cross.sh b/make/scripts/make.jogl.all.linux-armv6-cross.sh
similarity index 81%
rename from make/scripts/make.jogl.all.linux-armv7-cross.sh
rename to make/scripts/make.jogl.all.linux-armv6-cross.sh
index 5bb5728..9f31b79 100755
--- a/make/scripts/make.jogl.all.linux-armv7-cross.sh
+++ b/make/scripts/make.jogl.all.linux-armv6-cross.sh
@@ -14,7 +14,7 @@ export PATH
# -Dgluegen.cpptasks.detected.os=true \
# -DisUnix=true \
# -DisLinux=true \
-# -DisLinuxARMv7=true \
+# -DisLinuxARMv6=true \
# -DisX11=false \
export NODE_LABEL=.
@@ -29,22 +29,22 @@ export TARGET_IP=panda01
export TARGET_ROOT=/home/jogamp/projects-cross
export TARGET_ANT_HOME=/usr/share/ant
-export TARGET_PLATFORM_ROOT=/opt-linux-armv7-armel
+export TARGET_PLATFORM_ROOT=/opt-linux-armv6-armel
export TARGET_PLATFORM_LIBS=$TARGET_PLATFORM_ROOT/usr/lib
export TARGET_JAVA_LIBS=$TARGET_PLATFORM_ROOT/jre/lib/arm
-export GLUEGEN_CPPTASKS_FILE="../../gluegen/make/lib/gluegen-cpptasks-linux-armv4.xml"
+export GLUEGEN_CPPTASKS_FILE="../../gluegen/make/lib/gluegen-cpptasks-linux-armv6.xml"
#export JUNIT_DISABLED="true"
export JUNIT_RUN_ARG0="-Dnewt.test.Screen.disableScreenMode"
ant \
- -Drootrel.build=build-linux-armv7 \
+ -Drootrel.build=build-linux-armv6 \
\
-Dsetup.addNativeKD=true \
-Dsetup.addNativeOpenMAX=true \
- -Dsetup.addNativeBroadcomEGL=true \
- $* 2>&1 | tee make.jogl.all.linux-armv7-cross.log
+ -Dsetup.addNativeBroadcom=true \
+ $* 2>&1 | tee make.jogl.all.linux-armv6-cross.log
diff --git a/make/scripts/make.jogl.all.linux-armv7.sh b/make/scripts/make.jogl.all.linux-armv6.sh
similarity index 77%
rename from make/scripts/make.jogl.all.linux-armv7.sh
rename to make/scripts/make.jogl.all.linux-armv6.sh
index 0fd0b6e..3d526ea 100755
--- a/make/scripts/make.jogl.all.linux-armv7.sh
+++ b/make/scripts/make.jogl.all.linux-armv6.sh
@@ -8,20 +8,20 @@ export PATH
# -Dgluegen.cpptasks.detected.os=true \
# -DisUnix=true \
# -DisLinux=true \
-# -DisLinuxARMv7=true \
+# -DisLinuxARMv6=true \
# -DisX11=false \
export TARGET_PLATFORM_ROOT=/
export TARGET_PLATFORM_LIBS=/usr/lib/arm-linux-gnueabi
export TARGET_JAVA_LIBS=/usr/lib/jvm/default-java/jre/lib/arm
-export GLUEGEN_CPPTASKS_FILE="../../gluegen/make/lib/gluegen-cpptasks-linux-armv4.xml"
+export GLUEGEN_CPPTASKS_FILE="../../gluegen/make/lib/gluegen-cpptasks-linux-armv6.xml"
ant \
- -Drootrel.build=build-linux-armv7 \
+ -Drootrel.build=build-linux-armv6 \
-Dsetup.addNativeKD=true \
-Dsetup.addNativeOpenMAX=true \
- -Dsetup.addNativeBroadcomEGL=true \
+ -Dsetup.addNativeBroadcom=true \
-Djunit.run.arg0="-Dnewt.test.Screen.disableScreenMode" \
- $* 2>&1 | tee make.jogl.all.linux-armv7.log
+ $* 2>&1 | tee make.jogl.all.linux-armv6.log
diff --git a/make/scripts/make.jogl.all.linux-armv7hf-cross.sh b/make/scripts/make.jogl.all.linux-armv6hf-cross.sh
similarity index 79%
rename from make/scripts/make.jogl.all.linux-armv7hf-cross.sh
rename to make/scripts/make.jogl.all.linux-armv6hf-cross.sh
index cd82d82..6295a90 100755
--- a/make/scripts/make.jogl.all.linux-armv7hf-cross.sh
+++ b/make/scripts/make.jogl.all.linux-armv6hf-cross.sh
@@ -14,7 +14,7 @@ export PATH
# -Dgluegen.cpptasks.detected.os=true \
# -DisUnix=true \
# -DisLinux=true \
-# -DisLinuxARMv7=true \
+# -DisLinuxARMv6=true \
# -DisX11=false \
export NODE_LABEL=.
@@ -24,27 +24,27 @@ export HOST_IP=jogamp02
export HOST_RSYNC_ROOT=PROJECTS/JOGL
export TARGET_UID=jogamp
-export TARGET_IP=panda01
+export TARGET_IP=panda02
#export TARGET_IP=jautab02
export TARGET_ROOT=/home/jogamp/projects-cross
export TARGET_ANT_HOME=/usr/share/ant
-export TARGET_PLATFORM_ROOT=/opt-linux-armv7-armhf
+export TARGET_PLATFORM_ROOT=/opt-linux-armv6-armhf
export TARGET_PLATFORM_LIBS=$TARGET_PLATFORM_ROOT/usr/lib
export TARGET_JAVA_LIBS=$TARGET_PLATFORM_ROOT/jre/lib/arm
-export GLUEGEN_CPPTASKS_FILE="../../gluegen/make/lib/gluegen-cpptasks-linux-armv7hf.xml"
+export GLUEGEN_CPPTASKS_FILE="../../gluegen/make/lib/gluegen-cpptasks-linux-armv6hf.xml"
#export JUNIT_DISABLED="true"
export JUNIT_RUN_ARG0="-Dnewt.test.Screen.disableScreenMode"
ant \
- -Drootrel.build=build-linux-armv7hf \
+ -Drootrel.build=build-linux-armv6hf \
\
-Dsetup.addNativeKD=true \
-Dsetup.addNativeOpenMAX=true \
- -Dsetup.addNativeBroadcomEGL=true \
- $* 2>&1 | tee make.jogl.all.linux-armv7hf-cross.log
+ -Dsetup.addNativeBroadcom=true \
+ $* 2>&1 | tee make.jogl.all.linux-armv6hf-cross.log
diff --git a/make/scripts/make.jogl.all.linux-armv6hf.sh b/make/scripts/make.jogl.all.linux-armv6hf.sh
new file mode 100755
index 0000000..7d9480f
--- /dev/null
+++ b/make/scripts/make.jogl.all.linux-armv6hf.sh
@@ -0,0 +1,27 @@
+#! /bin/sh
+
+# arm-linux-gnueabihf == armhf triplet
+PATH=`pwd`/../../gluegen/make/lib/linux/arm-linux-gnueabihf/bin:$PATH
+export PATH
+
+# -Dc.compiler.debug=true
+# -Dgluegen.cpptasks.detected.os=true \
+# -DisUnix=true \
+# -DisLinux=true \
+# -DisLinuxARMv6=true \
+# -DisX11=false \
+
+export TARGET_PLATFORM_ROOT=/
+export TARGET_PLATFORM_LIBS=/usr/lib/arm-linux-gnueabihf
+export TARGET_JAVA_LIBS=/usr/lib/jvm/java-6-openjdk-armhf/jre/lib/arm
+
+export GLUEGEN_CPPTASKS_FILE="../../gluegen/make/lib/gluegen-cpptasks-linux-armv6hf.xml"
+
+ant \
+ -Drootrel.build=build-linux-armv6hf \
+ -Dsetup.addNativeKD=true \
+ -Dsetup.addNativeOpenMAX=true \
+ -Dsetup.addNativeBroadcom=true \
+ -Djunit.run.arg0="-Dnewt.test.Screen.disableScreenMode" \
+ $* 2>&1 | tee make.jogl.all.linux-armv6hf.log
+
diff --git a/make/scripts/make.jogl.all.win32.bat b/make/scripts/make.jogl.all.win32.bat
index 52ea33a..c4c80a7 100755
--- a/make/scripts/make.jogl.all.win32.bat
+++ b/make/scripts/make.jogl.all.win32.bat
@@ -1,7 +1,7 @@
set THISDIR="C:\JOGL"
-set J2RE_HOME=c:\jre1.6.0_30_x32
-set JAVA_HOME=c:\jdk1.6.0_30_x32
+set J2RE_HOME=c:\jre1.6.0_35_x32
+set JAVA_HOME=c:\jdk1.6.0_35_x32
set ANT_PATH=C:\apache-ant-1.8.2
set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;c:\mingw\bin;%PATH%
diff --git a/make/scripts/make.jogl.all.win64.bat b/make/scripts/make.jogl.all.win64.bat
index e1d258c..7355c6a 100755
--- a/make/scripts/make.jogl.all.win64.bat
+++ b/make/scripts/make.jogl.all.win64.bat
@@ -1,10 +1,10 @@
set THISDIR="C:\JOGL"
-set J2RE_HOME=c:\jre1.6.0_30_x64
-set JAVA_HOME=c:\jdk1.6.0_30_x64
+set J2RE_HOME=c:\jre1.6.0_35_x64
+set JAVA_HOME=c:\jdk1.6.0_35_x64
set ANT_PATH=C:\apache-ant-1.8.2
-set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;c:\mingw64\bin;c:\mingw\bin;%PATH%
+set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;c:\mingw64\bin;%PATH%
set LIB_GEN=%THISDIR%\lib
set CLASSPATH=.;%THISDIR%\build-win64\classes
diff --git a/make/scripts/targetcommand-awt.sh b/make/scripts/targetcommand-awt.sh
index af3b5f7..6bd4dd2 100755
--- a/make/scripts/targetcommand-awt.sh
+++ b/make/scripts/targetcommand-awt.sh
@@ -2,6 +2,8 @@
THISDIR=`pwd`
+ROOT_REL=build-linux-armv6hf
+
#XTRA_FLAGS="-Dnewt.test.Screen.disableScreenMode"
XTRA_FLAGS="-Dnewt.test.Screen.disableScreenMode -Djogl.debug.EGL -Dnativewindow.debug.GraphicsConfiguration -Djogl.debug.GLDrawable"
#XTRA_FLAGS="-Dnewt.debug.Screen"
@@ -14,23 +16,24 @@ XTRA_FLAGS="-Dnewt.test.Screen.disableScreenMode -Djogl.debug.EGL -Dnativewindow
#XTRA_FLAGS="-Djogl.debug.TraceGL"
#XTRA_FLAGS="-Djogl.debug.DebugGL -Djogl.debug.TraceGL"
-TSTCLASS=com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2AWT
+#TSTCLASS=com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2AWT
#TSTCLASS=com.jogamp.opengl.test.junit.jogl.demos.gl2.awt.TestGearsAWT
+TSTCLASS=com.jogamp.opengl.test.junit.jogl.awt.TestAWT01GLn
mkdir -p $THISDIR/projects-cross
rsync -av --delete --delete-after --delete-excluded \
--exclude 'build-x86*/' --exclude 'build-linux-x*/' --exclude 'build-android*/' --exclude 'build-win*/' --exclude 'build-mac*/' \
--exclude 'classes/' --exclude 'src/' --exclude '.git/' --exclude '*-java-src.zip' \
+ --exclude 'make/lib/external/' \
jogamp at jogamp02::PROJECTS/JOGL/gluegen jogamp at jogamp02::PROJECTS/JOGL/jogl $THISDIR/projects-cross
cd $THISDIR/projects-cross/jogl/make
function junit_run() {
java \
- -cp ../../gluegen/make/lib/junit.jar:/usr/share/ant/lib/ant.jar:/usr/share/ant/lib/ant-junit.jar:../../gluegen/build-linux-armv7/gluegen-rt.jar:../build-linux-armv7/jar/jogl.all.jar:../build-linux-armv7/jar/jogl.test.jar\
+ -cp ../../gluegen/make/lib/junit.jar:/usr/share/ant/lib/ant.jar:/usr/share/ant/lib/ant-junit.jar:../../gluegen/$ROOT_REL/gluegen-rt.jar:../$ROOT_REL/jar/jogl-all.jar:../$ROOT_REL/jar/jogl-test.jar\
$XTRA_FLAGS \
- com.jogamp.newt.util.MainThread\
org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner \
$TSTCLASS \
filtertrace=true \
@@ -46,9 +49,8 @@ function junit_run() {
function main_run() {
java \
- -cp ../../gluegen/make/lib/junit.jar:/usr/share/ant/lib/ant.jar:/usr/share/ant/lib/ant-junit.jar:../../gluegen/build-linux-armv7/gluegen-rt.jar:../build-linux-armv7/jar/jogl.all.jar:../build-linux-armv7/jar/jogl.test.jar\
+ -cp ../../gluegen/make/lib/junit.jar:/usr/share/ant/lib/ant.jar:/usr/share/ant/lib/ant-junit.jar:../../gluegen/$ROOT_REL/gluegen-rt.jar:../$ROOT_REL/jar/jogl-all.jar:../$ROOT_REL/jar/jogl-test.jar\
$XTRA_FLAGS \
- com.jogamp.newt.util.MainThread\
$TSTCLASS \
$*
}
diff --git a/make/scripts/targetcommand-awt.sh b/make/scripts/targetcommand-loop.sh
old mode 100755
new mode 100644
similarity index 59%
copy from make/scripts/targetcommand-awt.sh
copy to make/scripts/targetcommand-loop.sh
index af3b5f7..fc7baa7
--- a/make/scripts/targetcommand-awt.sh
+++ b/make/scripts/targetcommand-loop.sh
@@ -2,8 +2,14 @@
THISDIR=`pwd`
-#XTRA_FLAGS="-Dnewt.test.Screen.disableScreenMode"
-XTRA_FLAGS="-Dnewt.test.Screen.disableScreenMode -Djogl.debug.EGL -Dnativewindow.debug.GraphicsConfiguration -Djogl.debug.GLDrawable"
+ROOT_REL=build-linux-armv6hf
+
+# export LD_LIBRARY_PATH=$THISDIR/PVRTrace/:$LD_LIBRARY_PATH
+
+XTRA_FLAGS="-Dnewt.test.Screen.disableScreenMode"
+#XTRA_FLAGS="-Dnewt.test.Screen.disableScreenMode -Djogl.debug.TraceGL"
+#XTRA_FLAGS="-Dnewt.test.Screen.disableScreenMode -Djogl.debug.DebugGL -Djogl.debug.TraceGL"
+#XTRA_FLAGS="-Dnewt.test.Screen.disableScreenMode -Djogl.debug.EGL -Dnativewindow.debug.GraphicsConfiguration -Djogl.debug.GLDrawable"
#XTRA_FLAGS="-Dnewt.debug.Screen"
#XTRA_FLAGS="-Dnativewindow.debug.GraphicsConfiguration -Dnativewindow.debug.NativeWindow"
#XTRA_FLAGS="-Dnewt.debug.Window -Djogl.debug.EGL -Djogl.debug.GLContext -Djogl.debug.GLDrawable"
@@ -14,23 +20,26 @@ XTRA_FLAGS="-Dnewt.test.Screen.disableScreenMode -Djogl.debug.EGL -Dnativewindow
#XTRA_FLAGS="-Djogl.debug.TraceGL"
#XTRA_FLAGS="-Djogl.debug.DebugGL -Djogl.debug.TraceGL"
-TSTCLASS=com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2AWT
-#TSTCLASS=com.jogamp.opengl.test.junit.jogl.demos.gl2.awt.TestGearsAWT
-
- mkdir -p $THISDIR/projects-cross
+#TSTCLASS=com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT
+TSTCLASS=com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestRedSquareES2NEWT
+
+ mkdir -p $THISDIR/projects-cross
rsync -av --delete --delete-after --delete-excluded \
--exclude 'build-x86*/' --exclude 'build-linux-x*/' --exclude 'build-android*/' --exclude 'build-win*/' --exclude 'build-mac*/' \
--exclude 'classes/' --exclude 'src/' --exclude '.git/' --exclude '*-java-src.zip' \
+ --exclude 'make/lib/external/' \
jogamp at jogamp02::PROJECTS/JOGL/gluegen jogamp at jogamp02::PROJECTS/JOGL/jogl $THISDIR/projects-cross
cd $THISDIR/projects-cross/jogl/make
+ cp -a $THISDIR/pvrtrace.cfg .
+
function junit_run() {
java \
- -cp ../../gluegen/make/lib/junit.jar:/usr/share/ant/lib/ant.jar:/usr/share/ant/lib/ant-junit.jar:../../gluegen/build-linux-armv7/gluegen-rt.jar:../build-linux-armv7/jar/jogl.all.jar:../build-linux-armv7/jar/jogl.test.jar\
+ -cp ../../gluegen/make/lib/junit.jar:/usr/share/ant/lib/ant.jar:/usr/share/ant/lib/ant-junit.jar:../../gluegen/$ROOT_REL/gluegen-rt.jar:../$ROOT_REL/jar/jogl-all-noawt.jar:../$ROOT_REL/jar/jogl-test.jar\
+ -Djava.awt.headless=true\
$XTRA_FLAGS \
- com.jogamp.newt.util.MainThread\
org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner \
$TSTCLASS \
filtertrace=true \
@@ -46,14 +55,21 @@ function junit_run() {
function main_run() {
java \
- -cp ../../gluegen/make/lib/junit.jar:/usr/share/ant/lib/ant.jar:/usr/share/ant/lib/ant-junit.jar:../../gluegen/build-linux-armv7/gluegen-rt.jar:../build-linux-armv7/jar/jogl.all.jar:../build-linux-armv7/jar/jogl.test.jar\
+ -cp ../../gluegen/make/lib/junit.jar:/usr/share/ant/lib/ant.jar:/usr/share/ant/lib/ant-junit.jar:../../gluegen/$ROOT_REL/gluegen-rt.jar:../$ROOT_REL/jar/jogl-all-noawt.jar:../$ROOT_REL/jar/jogl-test.jar\
+ -Djava.awt.headless=true\
$XTRA_FLAGS \
- com.jogamp.newt.util.MainThread\
$TSTCLASS \
$*
}
-# junit_run 2>&1 | tee $THISDIR/targetcommand.log
-main_run $* 2>&1 | tee $THISDIR/targetcommand.log
+let i=0
+
+while true ; do
+ let i=$i+1
+ echo TEST RUN $i
+ # junit_run $*
+ main_run -time 100 $*
+ cp -a trace-*.pvrt $THISDIR/
+done
diff --git a/make/scripts/targetcommand-newt.sh b/make/scripts/targetcommand-newt.sh
index 47b7a0b..1cf7c30 100755
--- a/make/scripts/targetcommand-newt.sh
+++ b/make/scripts/targetcommand-newt.sh
@@ -2,10 +2,13 @@
THISDIR=`pwd`
+ROOT_REL=build-linux-armv6hf
+
export LD_LIBRARY_PATH=$THISDIR/PVRTrace/:$LD_LIBRARY_PATH
-XTRA_FLAGS="-Dnewt.test.Screen.disableScreenMode -Djogl.debug.DebugGL -Djogl.debug.TraceGL -Djogl.debug.GLContext.TraceSwitch "
+#XTRA_FLAGS="-Dnewt.test.Screen.disableScreenMode -Djogl.debug.DebugGL -Djogl.debug.TraceGL -Djogl.debug.GLContext.TraceSwitch "
#XTRA_FLAGS="-Dnewt.test.Screen.disableScreenMode -Djogl.debug.DebugGL -Djogl.debug.TraceGL"
+#XTRA_FLAGS="-Dnewt.test.Screen.disableScreenMode -Djogl.debug.DebugGL"
#XTRA_FLAGS="-Dnewt.test.Screen.disableScreenMode -Djogl.debug.EGL -Dnativewindow.debug.GraphicsConfiguration -Djogl.debug.GLDrawable"
#XTRA_FLAGS="-Dnewt.debug.Screen"
#XTRA_FLAGS="-Dnativewindow.debug.GraphicsConfiguration -Dnativewindow.debug.NativeWindow"
@@ -26,8 +29,11 @@ XTRA_FLAGS="-Dnewt.test.Screen.disableScreenMode -Djogl.debug.DebugGL -Djogl.deb
#TSTCLASS=com.jogamp.opengl.test.junit.graph.TestTextRendererNEWT01 # (Tegra regressions)
#TSTCLASS=com.jogamp.opengl.test.junit.jogl.acore.TestGLDebug00NEWT
#TSTCLASS=com.jogamp.opengl.test.junit.jogl.acore.TestGLDebug01NEWT
-TSTCLASS=com.jogamp.opengl.test.junit.jogl.acore.TestGPUMemSec01NEWT
+#TSTCLASS=com.jogamp.opengl.test.junit.jogl.acore.TestGPUMemSec01NEWT
+TSTCLASS=com.jogamp.opengl.test.junit.jogl.acore.TestGLDrawable01NEWT
#TSTCLASS=com.jogamp.opengl.test.junit.jogl.acore.TestInitConcurrentNEWT
+#TSTCLASS=com.jogamp.opengl.test.junit.jogl.acore.TestFBODrawableNEWT
+#TSTCLASS=com.jogamp.opengl.test.junit.jogl.caps.TestMultisampleES1NEWT
# Some Regressions (Panda, Omap4)
#
@@ -42,16 +48,16 @@ TSTCLASS=com.jogamp.opengl.test.junit.jogl.acore.TestGPUMemSec01NEWT
#TSTCLASS=com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES2NEWT2
#TSTCLASS=com.jogamp.opengl.test.junit.jogl.acore.TestShutdownCompleteNEWT
#TSTCLASS=com.jogamp.opengl.test.junit.jogl.acore.TestShutdownSharedNEWT
-#TSTCLASS=com.jogamp.opengl.test.junit.jogl.caps.TestMultisampleES1NEWT
#TSTCLASS=com.jogamp.opengl.test.junit.jogl.caps.TestTranslucencyNEWT
#TSTCLASS=com.jogamp.opengl.test.junit.jogl.demos.es1.newt.TestGearsES1NEWT
#TSTCLASS=com.jogamp.opengl.test.junit.jogl.demos.es1.newt.TestRedSquareES1NEWT
#TSTCLASS=com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestElektronenMultipliziererNEWT
#TSTCLASS=com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT
#TSTCLASS=com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestRedSquareES2NEWT
+#TSTCLASS=com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieCube
#TSTCLASS=com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestGearsNEWT
-#TSTCLASS=com.jogamp.opengl.test.junit.jogl.drawable.TestDrawable01NEWT
#TSTCLASS=com.jogamp.opengl.test.junit.jogl.glsl.TestFBOMRTNEWT01
+#TSTCLASS=com.jogamp.opengl.test.junit.jogl.acore.TestFBOMix2DemosES2NEWT
#TSTCLASS=com.jogamp.opengl.test.junit.jogl.glsl.TestGLSLShaderState01NEWT
#TSTCLASS=com.jogamp.opengl.test.junit.jogl.glsl.TestGLSLShaderState02NEWT
#TSTCLASS=com.jogamp.opengl.test.junit.jogl.glsl.TestGLSLSimple01NEWT
@@ -81,6 +87,7 @@ TSTCLASS=com.jogamp.opengl.test.junit.jogl.acore.TestGPUMemSec01NEWT
rsync -av --delete --delete-after --delete-excluded \
--exclude 'build-x86*/' --exclude 'build-linux-x*/' --exclude 'build-android*/' --exclude 'build-win*/' --exclude 'build-mac*/' \
--exclude 'classes/' --exclude 'src/' --exclude '.git/' --exclude '*-java-src.zip' \
+ --exclude 'make/lib/external/' \
jogamp at jogamp02::PROJECTS/JOGL/gluegen jogamp at jogamp02::PROJECTS/JOGL/jogl $THISDIR/projects-cross
cd $THISDIR/projects-cross/jogl/make
@@ -89,10 +96,9 @@ TSTCLASS=com.jogamp.opengl.test.junit.jogl.acore.TestGPUMemSec01NEWT
function junit_run() {
java \
- -cp ../../gluegen/make/lib/junit.jar:/usr/share/ant/lib/ant.jar:/usr/share/ant/lib/ant-junit.jar:../../gluegen/build-linux-armv7/gluegen-rt.jar:../build-linux-armv7/jar/jogl.all-noawt.jar:../build-linux-armv7/jar/jogl.test.jar\
+ -cp ../../gluegen/make/lib/junit.jar:/usr/share/ant/lib/ant.jar:/usr/share/ant/lib/ant-junit.jar:../../gluegen/$ROOT_REL/gluegen-rt.jar:../$ROOT_REL/jar/jogl-all-noawt.jar:../$ROOT_REL/jar/jogl-test.jar\
-Djava.awt.headless=true\
$XTRA_FLAGS \
- com.jogamp.newt.util.MainThread\
org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner \
$TSTCLASS \
filtertrace=true \
@@ -108,10 +114,9 @@ function junit_run() {
function main_run() {
java \
- -cp ../../gluegen/make/lib/junit.jar:/usr/share/ant/lib/ant.jar:/usr/share/ant/lib/ant-junit.jar:../../gluegen/build-linux-armv7/gluegen-rt.jar:../build-linux-armv7/jar/jogl.all-noawt.jar:../build-linux-armv7/jar/jogl.test.jar\
+ -cp ../../gluegen/make/lib/junit.jar:/usr/share/ant/lib/ant.jar:/usr/share/ant/lib/ant-junit.jar:../../gluegen/$ROOT_REL/gluegen-rt.jar:../$ROOT_REL/jar/jogl-all-noawt.jar:../$ROOT_REL/jar/jogl-test.jar\
-Djava.awt.headless=true\
$XTRA_FLAGS \
- com.jogamp.newt.util.MainThread\
$TSTCLASS \
$*
}
diff --git a/make/scripts/tests-armv6_armel.sh b/make/scripts/tests-armv6_armel.sh
new file mode 100755
index 0000000..8bc3eff
--- /dev/null
+++ b/make/scripts/tests-armv6_armel.sh
@@ -0,0 +1,7 @@
+#! /bin/bash
+
+spath=`dirname $0`
+
+. $spath/tests.sh `which java` -DummyArg ../build-linux-armv6 $*
+
+
diff --git a/make/scripts/tests-armv6_armhf.sh b/make/scripts/tests-armv6_armhf.sh
new file mode 100755
index 0000000..6b66a47
--- /dev/null
+++ b/make/scripts/tests-armv6_armhf.sh
@@ -0,0 +1,7 @@
+#! /bin/bash
+
+spath=`dirname $0`
+
+. $spath/tests.sh `which java` -DummyArg ../build-linux-armv6hf $*
+
+
diff --git a/make/scripts/tests-armv7l_eabi.sh b/make/scripts/tests-armv7l_eabi.sh
deleted file mode 100755
index 2ed3070..0000000
--- a/make/scripts/tests-armv7l_eabi.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-#! /bin/bash
-
-spath=`dirname $0`
-
-. $spath/tests.sh `which java` -DummyArg ../build-armv7l_eabi $*
-
-
diff --git a/make/scripts/tests-javaws-x64.bat b/make/scripts/tests-javaws-x64.bat
index 40f1182..deef4ca 100755
--- a/make/scripts/tests-javaws-x64.bat
+++ b/make/scripts/tests-javaws-x64.bat
@@ -1,4 +1,4 @@
-set JRE_PATH=C:\jre1.6.0_30_x64\bin
+set JRE_PATH=C:\jre1.6.0_35_x64\bin
set LOG_PATH=%USERPROFILE%\AppData\LocalLow\Sun\Java\Deployment\log
%JRE_PATH%\javaws -uninstall
diff --git a/make/scripts/tests-linux-armv6.sh b/make/scripts/tests-linux-armv6.sh
new file mode 100755
index 0000000..8bc3eff
--- /dev/null
+++ b/make/scripts/tests-linux-armv6.sh
@@ -0,0 +1,7 @@
+#! /bin/bash
+
+spath=`dirname $0`
+
+. $spath/tests.sh `which java` -DummyArg ../build-linux-armv6 $*
+
+
diff --git a/make/scripts/tests-linux-armv6hf.sh b/make/scripts/tests-linux-armv6hf.sh
new file mode 100755
index 0000000..6b66a47
--- /dev/null
+++ b/make/scripts/tests-linux-armv6hf.sh
@@ -0,0 +1,7 @@
+#! /bin/bash
+
+spath=`dirname $0`
+
+. $spath/tests.sh `which java` -DummyArg ../build-linux-armv6hf $*
+
+
diff --git a/make/scripts/tests-linux-armv7.sh b/make/scripts/tests-linux-armv7.sh
deleted file mode 100755
index 6ec93db..0000000
--- a/make/scripts/tests-linux-armv7.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-#! /bin/bash
-
-spath=`dirname $0`
-
-. $spath/tests.sh `which java` -DummyArg ../build-linux-armv7 $*
-
-
diff --git a/make/scripts/tests-linux-armv7hf.sh b/make/scripts/tests-linux-armv7hf.sh
deleted file mode 100755
index 5526e81..0000000
--- a/make/scripts/tests-linux-armv7hf.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-#! /bin/bash
-
-spath=`dirname $0`
-
-. $spath/tests.sh `which java` -DummyArg ../build-linux-armv7hf $*
-
-
diff --git a/make/scripts/tests-x32.bat b/make/scripts/tests-x32.bat
index 7947759..ec6c41f 100755
--- a/make/scripts/tests-x32.bat
+++ b/make/scripts/tests-x32.bat
@@ -1,6 +1,7 @@
REM scripts\java-win32-dbg.bat jogamp.newt.awt.opengl.VersionApplet
-REM scripts\java-win32-dbg.bat com.jogamp.newt.opengl.GLWindow
+scripts\java-win32-dbg.bat com.jogamp.newt.opengl.GLWindow
REM scripts\java-win32-dbg.bat javax.media.opengl.awt.GLCanvas
+REM scripts\java-win32.bat com.jogamp.opengl.test.junit.jogl.acore.TestInitConcurrentNEWT %*
REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestMainVersionGLWindowNEWT %*
REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.jogl.offscreen.TestOffscreen01GLPBufferNEWT -time 5000
REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.jogl.awt.TestAWT01GLn
@@ -71,6 +72,10 @@ REM scripts\java-win32.bat com.jogamp.opengl.test.junit.newt.TestWindowClosingPr
REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWT01GLn %*
REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWT02GLn %*
REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWTAWT01GLn $*
+REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting04AWT $*
+REM scripts\java-win32.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting01aSWT $*
+REM scripts\java-win32.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting04SWT $*
+REM scripts\java-win32.bat com.jogamp.opengl.test.junit.jogl.swt.TestNewtCanvasSWTGLn $*
REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.jogl.offscreen.TestOffscreen02BitmapNEWT -time 5000
@@ -94,7 +99,7 @@ REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestGPUMe
REM scripts\java-win32.bat com.jogamp.opengl.test.junit.jogl.acore.TestMapBuffer01NEWT
REM scripts\java-win32.bat com.jogamp.opengl.test.junit.jogl.glsl.TestRulerNEWT01
-scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestFBODrawableNEWT %*
+REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestFBODrawableNEWT %*
REM scripts\java-win32.bat com.jogamp.opengl.test.junit.jogl.glsl.TestFBOMRTNEWT01
REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestElektronenMultipliziererNEWT %*
diff --git a/make/scripts/tests-x64.bat b/make/scripts/tests-x64.bat
index 6d3e46a..c8bc030 100755
--- a/make/scripts/tests-x64.bat
+++ b/make/scripts/tests-x64.bat
@@ -1,6 +1,9 @@
REM scripts\java-win64-dbg.bat jogamp.newt.awt.opengl.VersionApplet
REM scripts\java-win64-dbg.bat com.jogamp.newt.opengl.GLWindow
REM scripts\java-win64-dbg.bat javax.media.opengl.awt.GLCanvas
+REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestGLCapabilities01NEWT %*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestShutdownCompleteNEWT %*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestShutdownCompleteAWT %*
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestMainVersionGLWindowNEWT %*
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.offscreen.TestOffscreen01GLPBufferNEWT -time 5000
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.awt.TestAWT01GLn
@@ -16,7 +19,7 @@ REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestGLPro
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestGearsNewtAWTWrapper %*
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestGearsNEWT -time 30000
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.demos.es1.newt.TestGearsES1NEWT %*
-REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT %*
+scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT %*
REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT -vsync -time 4000 -x 10 -y 10 -width 100 -height 100 -screen 0
REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT -vsync -time 40000 -width 100 -height 100 -screen 0 %*
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.awt.TestAWTCardLayoutAnimatorStartStopBug532 %*
@@ -29,6 +32,12 @@ REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.glsl.TestGLSLSi
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestParenting01AWT
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestListenerCom01AWT
+
+REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestNewtKeyEventOrderAWT %*
+REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestNewtKeyEventAutoRepeatAWT %*
+REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestNewtKeyPressReleaseUnmaskRepeatAWT %*
+REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestNewtKeyCodesAWT %*
+REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestNewtKeyCodeModifiersAWT %*
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting01NEWT %*
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting02NEWT %*
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting01bAWT %*
@@ -37,13 +46,13 @@ REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestP
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting03bAWT -time 100000
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParentingFocusTraversal01AWT %*
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParentingOffscreenLayer01AWT %*
-REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting01aSWT $*
-REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting04AWT $*
-scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting04SWT $*
+REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting01aSWT %*
+REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting04AWT %*
+REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting04SWT %*
-REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWTAccessor03AWTGLn $*
-REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWTJOGLGLCanvas01GLn $*
-REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestNewtCanvasSWTGLn $*
+REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWTAccessor03AWTGLn %*
+REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWTJOGLGLCanvas01GLn %*
+REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestNewtCanvasSWTGLn %*
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestWindows01NEWT
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestGLWindows01NEWT
@@ -70,9 +79,9 @@ REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.caps.TestMultis
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.awt.TestBug461OffscreenSupersamplingSwingAWT
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.glsl.TestShaderCompilationBug459AWT
-REM scripts\java-win64.bat com.jogamp.opengl.test.junit.newt.TestWindowClosingProtocol01AWT $*
-REM scripts\java-win64.bat com.jogamp.opengl.test.junit.newt.TestWindowClosingProtocol02NEWT $*
-REM scripts\java-win64.bat com.jogamp.opengl.test.junit.newt.TestWindowClosingProtocol03NewtAWT $*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.newt.TestWindowClosingProtocol01AWT %*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.newt.TestWindowClosingProtocol02NEWT %*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.newt.TestWindowClosingProtocol03NewtAWT %*
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWT01GLn %*
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWT02GLn %*
@@ -93,16 +102,25 @@ REM scripts\java-win64.bat com.jogamp.opengl.test.junit.graph.demos.GPUTextNewtD
REM scripts\java-win64.bat com.jogamp.opengl.test.junit.graph.demos.GPURegionNewtDemo01
REM scripts\java-win64.bat com.jogamp.opengl.test.junit.graph.demos.GPURegionNewtDemo02
-REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestGLDebug00NEWT $*
-REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestGLDebug01NEWT $*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestGLDebug00NEWT %*
+REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestGLDebug01NEWT %*
-REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestGPUMemSec01NEWT $*
-REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestGPUMemSec01NEWT $*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestGPUMemSec01NEWT %*
+REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestGPUMemSec01NEWT %*
REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestMapBuffer01NEWT
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableDelegateOnOffscrnCapsNEWT $*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableGLWindowOnOffscrnCapsNEWT $*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableGLCanvasOnOffscrnCapsAWT $*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableFactoryOffscrnCapsNEWT $*
+
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestFBOAutoDrawableFactoryNEWT $*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestFBOAutoDrawableOffThreadSharedContextES2NEWT $*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestFBOMix2DemosES2NEWT $*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestFBOMRTNEWT01 $*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestFBOAutoDrawableDeadlockAWT $*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.awt.TestBug461FBOSupersamplingSwingAWT
REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.glsl.TestRulerNEWT01
-REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestFBODrawableNEWT %*
-REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.glsl.TestFBOMRTNEWT01 %*
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestElektronenMultipliziererNEWT %*
diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh
index 43d04c6..ef64aa7 100755
--- a/make/scripts/tests.sh
+++ b/make/scripts/tests.sh
@@ -32,7 +32,13 @@ MOSX=0
MOSX_MT=0
uname -a | grep -i Darwin && MOSX=1
if [ $MOSX -eq 1 ] ; then
- #export NSZombieEnabled=YES
+ echo setup OSX environment vars
+ export NSZombieEnabled=YES
+ export NSTraceEvents=YES
+ #export OBJC_PRINT_EXCEPTIONS=YES
+ echo NSZombieEnabled $NSZombieEnabled 2>&1 | tee -a java-run.log
+ echo NSTraceEvents $NSTraceEvents 2>&1 | tee -a java-run.log
+ echo OBJC_PRINT_EXCEPTIONS $OBJC_PRINT_EXCEPTIONS 2>&1 | tee -a java-run.log
MOSX_MT=1
fi
@@ -53,31 +59,49 @@ function jrun() {
swton=$1
shift
- #D_ARGS="-Djogl.debug.TraceGL -Djogl.debug.DebugGL -Djogl.debug.GLSLCode"
+ #D_ARGS="-Dnativewindow.debug.X11Util.ATI_HAS_NO_XCLOSEDISPLAY_BUG"
+ #D_ARGS="-Dnativewindow.debug.X11Util.ATI_HAS_NO_MULTITHREADING_BUG"
+ #D_ARGS="-Djogl.disable.opengles"
+ #D_ARGS="-Djogl.debug.DebugGL -Djogl.debug.FBObject"
+ #D_ARGS="-Djogl.debug.FBObject -Djogl.debug.TraceGL -Djogl.debug.GLBufferStateTracker"
#D_ARGS="-Djogl.debug.FBObject"
+ #D_ARGS="-Djogl.debug.GLSLCode"
+ #D_ARGS="-Djogl.debug.GLSLCode -Djogl.debug.DebugGL -Djogl.debug.TraceGL"
+ #D_ARGS="-Djogl.debug.FixedFuncPipeline -Djogl.debug.GLSLCode"
+ #D_ARGS="-Djogl.debug.FixedFuncPipeline -Djogl.debug.GLSLState"
+ #D_ARGS="-Djogl.debug.FixedFuncPipeline"
+ #D_ARGS="-Djogl.debug.ImmModeSink.Buffer -Djogl.debug.ImmModeSink.Draw"
+ #D_ARGS="-Djogl.debug.FixedFuncPipeline -Djogl.debug.GLSLState -Djogl.debug.ImmModeSink.Buffer -Djogl.debug.ImmModeSink.Draw"
+ #D_ARGS="-Djogl.debug.TraceGL -Djogl.debug.DebugGL -Djogl.debug.GLSLCode"
+ #D_ARGS="-Djogl.debug.DebugGL -Djogl.debug.FBObject -Djogl.debug.GLContext -Djogl.debug.GLDrawable -Djogl.debug.GLCanvas -Dnewt.debug.Window"
#D_ARGS="-Dnativewindow.debug.GraphicsConfiguration -Djogl.debug.GLDrawable -Djogl.debug.GLContext -Djogl.debug.FBObject"
#D_ARGS="-Djogl.debug.GLContext.NoProfileAliasing"
#D_ARGS="-Djogamp.debug=all -Dnativewindow.debug=all -Djogl.debug=all -Dnewt.debug=all"
- #D_ARGS="-Djogl.debug=all -Dnativewindow.debug=all -Dnewt.debug=all"
- #D_ARGS="-Djogl.debug=all -Dnativewindow.debug=all -Dnewt.debug=all -Djogamp.debug.Lock"
- #D_ARGS="-Djogl.debug=all -Dnativewindow.debug=all"
- #D_ARGS="-Dnewt.debug.Window"
+ #D_ARGS="-Dnativewindow.debug=all -Djogl.debug=all -Dnewt.debug=all"
+ #D_ARGS="-Djogl.debug=all -Dnewt.debug=all"
+ #D_ARGS="-Djogl.debug.GLContext -Djogl.debug.GLDrawable -Dnativewindow.debug.GraphicsConfiguration"
#D_ARGS="-Djogl.debug.GLDrawable"
+ #D_ARGS="-Djogl.fbo.force.none"
+ #D_ARGS="-Djogl.debug=all -Dnativewindow.debug=all -Dnewt.debug=all -Djogamp.debug.Lock"
+ #D_ARGS="-Djogl.debug=all"
#D_ARGS="-Djogl.debug.EGLDrawableFactory.DontQuery -Djogl.debug.GLDrawable"
#D_ARGS="-Djogl.debug.EGLDrawableFactory.QueryNativeTK -Djogl.debug.GLDrawable"
#D_ARGS="-Djogl.debug.GLDebugMessageHandler"
#D_ARGS="-Djogl.debug.GLDebugMessageHandler -Djogl.debug.DebugGL"
#D_ARGS="-Djogl.debug.GLDebugMessageHandler -Djogl.debug.TraceGL -Djogl.debug.DebugGL -Djogl.debug.GLSLCode -Djogl.debug.GLSLState"
#D_ARGS="-Djogl.debug.GLDebugMessageHandler -Djogl.debug.DebugGL -Djogl.debug.TraceGL"
- #D_ARGS="-Djogamp.debug.NativeLibrary -Djogamp.debug.NativeLibrary.UseCurrentThreadLibLoader"
+ #D_ARGS="-Djogamp.debug.NativeLibrary"
#D_ARGS="-Djogl.1thread=false -Djogl.debug.Threading"
#D_ARGS="-Djogl.1thread=true -Djogl.debug.Threading"
#D_ARGS="-Djogl.debug.DebugGL -Djogl.debug.TraceGL -Djogl.debug.GLContext.TraceSwitch -Djogl.debug=all"
#D_ARGS="-Djogamp.debug.IOUtil -Djogl.debug.GLSLCode -Djogl.debug.GLMediaPlayer"
#D_ARGS="-Djogl.debug.GLArrayData"
- #D_ARGS="-Djogl.debug.EGL -Dnativewindow.debug.GraphicsConfiguration -Djogl.debug.GLDrawable"
+ #D_ARGS="-Djogl.debug.GLDrawable"
+ #D_ARGS="-Djogl.debug.EGLDisplayUtil -Dnativewindow.debug.GraphicsConfiguration -Djogl.debug.GLDrawable"
+ #D_ARGS="-Djogl.debug.EGLDisplayUtil -Dnativewindow.debug.X11Util"
#D_ARGS="-Djogl.debug.GLDrawable"
#D_ARGS="-Dnewt.test.Screen.disableScreenMode -Dnewt.debug.Screen"
+ #D_ARGS="-Dnewt.debug.Screen -Djogl.debug.Animator"
#D_ARGS="-Djogl.debug.ExtensionAvailabilityCache -Djogl.debug=all -Dnativewindow.debug=all -Djogamp.debug.ProcAddressHelper=true -Djogamp.debug.NativeLibrary=true -Djogamp.debug.NativeLibrary.Lookup=true"
#D_ARGS="-Dnewt.debug.MainThread"
#D_ARGS="-Dnewt.debug.Window"
@@ -87,26 +111,26 @@ function jrun() {
#D_ARGS="-Djogl.debug.GLContext -Djogl.debug.GLProfile -Djogl.debug.GLDrawable"
#D_ARGS="-Djogl.debug.GLContext -Djogl.debug.GLProfile"
#D_ARGS="-Djogl.debug.GLProfile"
- #D_ARGS="-Dnewt.debug.EDT -Dnativewindow.debug.ToolkitLock.TraceLock -Dnativewindow.debug.NativeWindow"
#D_ARGS="-Dnativewindow.debug.NativeWindow"
#D_ARGS="-Dnewt.debug.Window -Dnewt.debug.Display -Dnewt.debug.EDT"
#D_ARGS="-Dnewt.debug.EDT -Dnewt.debug.Window -Djogl.debug.GLContext"
#D_ARGS="-Dnativewindow.debug.X11Util.XErrorStackDump -Dnativewindow.debug.X11Util.TraceDisplayLifecycle -Dnativewindow.debug.X11Util"
#D_ARGS="-Dnativewindow.debug.X11Util -Djogl.debug.GLContext -Djogl.debug.GLDrawable -Dnewt.debug=all"
#D_ARGS="-Dnativewindow.debug.X11Util -Dnativewindow.debug.X11Util.XSync"
+ #D_ARGS="-Dnativewindow.debug.X11Util.XSync -Dnativewindow.debug.X11Util.TraceDisplayLifecycle"
#D_ARGS="-Dnativewindow.debug.X11Util.XSync -Dnewt.debug.Window"
#D_ARGS="-Djogl.debug.GLDrawable -Djogl.debug.GLContext"
+ #D_ARGS="-Dnativewindow.debug.NativeWindow -Dnativewindow.debug.X11Util"
#D_ARGS="-Djogamp.common.utils.locks.Lock.timeout=3000 -Djogamp.debug.Lock -Djogl.debug.GLContext.TraceSwitch"
- #D_ARGS="-Djogamp.common.utils.locks.Lock.timeout=600000 -Djogamp.debug.Lock -Djogamp.debug.Lock.TraceLock"
+ #D_ARGS="-Djogamp.common.utils.locks.Lock.timeout=3000 -Djogamp.debug.Lock -Dnativewindow.debug.ToolkitLock.TraceLock"
#D_ARGS="-Djogamp.common.utils.locks.Lock.timeout=600000 -Djogamp.debug.Lock -Djogamp.debug.Lock.TraceLock -Dnativewindow.debug.ToolkitLock.TraceLock"
#D_ARGS="-Djogamp.common.utils.locks.Lock.timeout=600000 -Djogamp.debug.Lock -Dnativewindow.debug.X11Util"
#D_ARGS="-Dnewt.debug.EDT -Djogamp.common.utils.locks.Lock.timeout=600000 -Djogl.debug.Animator -Dnewt.debug.Display -Dnewt.debug.Screen"
- #D_ARGS="-Dnewt.debug.Screen"
#D_ARGS="-Dnewt.debug.Window -Djogamp.common.utils.locks.Lock.timeout=600000 -Djogl.debug.Animator"
#D_ARGS="-Djogl.debug.Animator -Dnewt.debug=all"
#D_ARGS="-Dnewt.debug.EDT -Dnewt.debug.Display -Dnativewindow.debug.X11Util -Djogl.debug.GLDrawable -Djogl.debug.GLCanvas"
#D_ARGS="-Djogl.debug.GLContext"
- #D_ARGS="-Dnativewindow.debug.GraphicsConfiguration -Djogl.debug.CapabilitiesChooser"
+ #D_ARGS="-Dnativewindow.debug.GraphicsConfiguration -Djogl.debug.CapabilitiesChooser -Djogl.debug.GLDrawable -Djogl.debug.GLProfile"
#D_ARGS="-Dnewt.debug.Screen -Dnewt.debug.EDT -Djogamp.debug.Lock"
#D_ARGS="-Djogl.debug.GLContext -Dnativewindow.debug.GraphicsConfiguration"
#D_ARGS="-Dnewt.debug.EDT"
@@ -122,7 +146,10 @@ function jrun() {
#D_ARGS="-Djogl.debug.Animator"
#D_ARGS="-Dnativewindow.debug=all"
#D_ARGS="-Djogl.debug.GLCanvas"
- #D_ARGS="-Dnativewindow.debug.ToolkitLock.TraceLock"
+ #D_ARGS="-Djogl.debug.GLContext -Dnativewindow.debug.X11Util.XSync"
+ #D_ARGS="-Dnativewindow.debug.X11Util.XSync -Dnativewindow.debug.ToolkitLock.TraceLock"
+ #D_ARGS="-Dnativewindow.debug.NativeWindow"
+ #D_ARGS="-Dnativewindow.debug.ToolkitLock"
#D_ARGS="-Djogl.debug.graph.curve -Djogl.debug.GLSLCode -Djogl.debug.TraceGL"
#D_ARGS="-Djogl.debug.graph.curve -Djogl.debug.GLSLState"
#D_ARGS="-Djogamp.debug.JNILibLoader -Djogamp.debug.TempJarCache -Djogamp.debug.JarUtil"
@@ -174,6 +201,8 @@ function jrun() {
#export LD_LIBRARY_PATH=/opt-linux-x86_64/mesa-7.8.1/lib64:$LD_LIBRARY_PATH
#export LD_LIBRARY_PATH=/usr/lib/mesa:/usr/lib32/mesa:$LD_LIBRARY_PATH
#export LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu/mesa:/usr/lib/i386-linux-gnu/mesa:$LD_LIBRARY_PATH
+ #export LD_LIBRARY_PATH=`pwd`/lib/external/mesa/x86_64-linux-gnu:$LD_LIBRARY_PATH
+ #export LD_LIBRARY_PATH=`pwd`/lib/external/mesa/x86_64-linux-gnu/gallium:$LD_LIBRARY_PATH
echo
echo "Test Start: $*"
echo
@@ -181,6 +210,9 @@ function jrun() {
echo
echo $javaexe $javaxargs $X_ARGS $D_ARGS $C_ARG $*
#LIBGL_DRIVERS_PATH=/usr/lib/mesa:/usr/lib32/mesa \
+ #LIBGL_DEBUG=verbose INTEL_STRICT_CONFORMANCE=1 INTEL_DEBUG="buf bat" \
+ #LIBGL_DEBUG=verbose MESA_DEBUG=true INTEL_STRICT_CONFORMANCE=1 \
+ #export LIBGL_DEBUG=verbose MESA_DEBUG=true LIBGL_ALWAYS_SOFTWARE=true
#gdb --args $javaexe $javaxargs $X_ARGS $D_ARGS $C_ARG $*
$javaexe $javaxargs $X_ARGS $D_ARGS $C_ARG $*
echo
@@ -206,7 +238,7 @@ function testawtswt() {
}
#
-# newt (testnoawt and testawt)
+# core/newt (testnoawt and testawt)
#
#testnoawt com.jogamp.nativewindow.NativeWindowVersion $*
#testnoawt com.jogamp.opengl.JoglVersion $*
@@ -214,15 +246,18 @@ function testawtswt() {
#testnoawt com.jogamp.newt.opengl.GLWindow $*
#testnoawt com.jogamp.opengl.test.junit.jogl.offscreen.TestOffscreen01GLPBufferNEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.offscreen.TestOffscreen02BitmapNEWT $*
-#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $*
+testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestElektronenMultipliziererNEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFloatUtil01MatrixMatrixMultNOUI $*
-testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestNEWTCloseX11DisplayBug565 $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestPMVMatrix01NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestPMVMatrix02NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestNEWTCloseX11DisplayBug565 $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestMainVersionGLWindowNEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLProfile00NEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLProfile01NEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestShutdownCompleteNEWT $*
-#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestShutdownSharedNEWT $*
-#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestInitConcurrentNEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestInitConcurrent01NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestInitConcurrent02NEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLContextSurfaceLockNEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLDebug00NEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLDebug01NEWT $*
@@ -230,10 +265,28 @@ testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestNEWTCloseX11DisplayBug565
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextListNEWT2 $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES1NEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES2NEWT $*
-#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES2NEWT2 $*
-#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableDelegateNEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableDelegateOnOffscrnCapsNEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLContextDrawableSwitchNEWT $*
-#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBODrawableNEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestPointsNEWT $*
+
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableGLWindowOnOffscrnCapsNEWT $*
+#testawt com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableGLCanvasOnOffscrnCapsAWT $*
+#testawt com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableNewtCanvasAWTOnOffscrnCapsAWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableFactoryOffscrnCapsNEWT $*
+
+#testawt com.jogamp.opengl.test.junit.jogl.acore.TestOffscreenLayer01GLCanvasAWT $*
+#testawt com.jogamp.opengl.test.junit.jogl.acore.TestOffscreenLayer02NewtCanvasAWT $*
+#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParentingFocusTraversal01AWT $*
+#testawt com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2AWT $*
+
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOAutoDrawableFactoryNEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOOffThreadSharedContextMix2DemosES2NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOOnThreadSharedContext1DemoES2NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOMix2DemosES2NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOMRTNEWT01 $*
+#testawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOAutoDrawableDeadlockAWT $*
+#testawt com.jogamp.opengl.test.junit.jogl.awt.TestBug461FBOSupersamplingSwingAWT
+#testawt com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2AWT $*
#testnoawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting01NEWT $*
#testnoawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting02NEWT $*
@@ -273,13 +326,15 @@ testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestNEWTCloseX11DisplayBug565
#testawt javax.media.opengl.awt.GLCanvas $*
#testawt com.jogamp.opengl.test.junit.jogl.acore.TestMainVersionGLCanvasAWT $*
#testawt com.jogamp.opengl.test.junit.jogl.awt.TestBug551AWT $*
+#testawt com.jogamp.opengl.test.junit.jogl.awt.TestBug572AWT $*
+#testawt com.jogamp.opengl.test.junit.jogl.awt.TestBug611AWT $*
#testawt com.jogamp.opengl.test.junit.jogl.awt.TestAWT01GLn $*
#testawt com.jogamp.opengl.test.junit.jogl.acore.TestAWTCloseX11DisplayBug565 $*
#testawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextListAWT $*
#testawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextNewtAWTBug523 $*
+#testawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOAutoDrawableDeadlockAWT $*
#testawt com.jogamp.opengl.test.junit.jogl.acore.TestPBufferDeadlockAWT $*
#testawt com.jogamp.opengl.test.junit.jogl.acore.TestShutdownCompleteAWT $*
-#testawt com.jogamp.opengl.test.junit.jogl.acore.TestShutdownSharedAWT $*
#testawt com.jogamp.opengl.test.junit.jogl.acore.x11.TestGLXCallsOnAWT $*
#testawt com.jogamp.opengl.test.junit.jogl.awt.TestSwingAWT01GLn
#testawt com.jogamp.opengl.test.junit.jogl.awt.TestAWT03GLCanvasRecreate01 $*
@@ -290,7 +345,8 @@ testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestNEWTCloseX11DisplayBug565
#testawt com.jogamp.opengl.test.junit.jogl.demos.gl2.awt.TestGearsAWTAnalyzeBug455 $*
#testawt com.jogamp.opengl.test.junit.jogl.demos.gl2.awt.TestGearsGLJPanelAWT $*
#testawt com.jogamp.opengl.test.junit.jogl.demos.gl2.awt.TestGearsGLJPanelAWTBug450 $*
-#testawt com.jogamp.opengl.test.junit.jogl.awt.TestBug461OffscreenSupersamplingSwingAWT
+#testawt com.jogamp.opengl.test.junit.jogl.awt.TestBug461FBOSupersamplingSwingAWT
+#testawt com.jogamp.opengl.test.junit.jogl.awt.TestBug461PBufferSupersamplingSwingAWT
#testawt com.jogamp.opengl.test.junit.jogl.glu.TestBug463ScaleImageMemoryAWT $*
#testawt com.jogamp.opengl.test.junit.jogl.awt.TestAWTCardLayoutAnimatorStartStopBug532 $*
@@ -314,11 +370,16 @@ testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestNEWTCloseX11DisplayBug565
#
# newt.awt (testawt)
#
-#testawt com.jogamp.opengl.test.junit.jogl.newt.TestSwingAWTRobotUsageBeforeJOGLInitBug411
-#testawt com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestGearsNewtAWTWrapper
+#testawt com.jogamp.opengl.test.junit.jogl.newt.TestSwingAWTRobotUsageBeforeJOGLInitBug411 $*
+#testawt com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestGearsNewtAWTWrapper $*
#testawt com.jogamp.opengl.test.junit.newt.TestEventSourceNotAWTBug
#testawt com.jogamp.opengl.test.junit.newt.TestFocus01SwingAWTRobot $*
#testawt com.jogamp.opengl.test.junit.newt.TestFocus02SwingAWTRobot $*
+#testawt com.jogamp.opengl.test.junit.newt.TestNewtKeyEventOrderAWT $*
+#testawt com.jogamp.opengl.test.junit.newt.TestNewtKeyEventAutoRepeatAWT $*
+#testawt com.jogamp.opengl.test.junit.newt.TestNewtKeyPressReleaseUnmaskRepeatAWT $*
+#testawt com.jogamp.opengl.test.junit.newt.TestNewtKeyCodesAWT $*
+#testawt com.jogamp.opengl.test.junit.newt.TestNewtKeyCodeModifiersAWT $*
#testawt com.jogamp.opengl.test.junit.newt.TestListenerCom01AWT
#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting01aAWT $*
#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting01bAWT $*
@@ -330,8 +391,6 @@ testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestNEWTCloseX11DisplayBug565
#testawtswt com.jogamp.opengl.test.junit.newt.parenting.TestParenting01aSWT $*
#testawtswt com.jogamp.opengl.test.junit.newt.parenting.TestParenting04SWT $*
#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParentingFocusTraversal01AWT $*
-#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParentingOffscreenLayer01GLCanvasAWT $*
-#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParentingOffscreenLayer02NewtCanvasAWT $*
#testawt com.jogamp.opengl.test.junit.newt.parenting.TestTranslucentParentingAWT $*
#testawt com.jogamp.opengl.test.junit.newt.TestCloseNewtAWT
#testawt com.jogamp.opengl.test.junit.jogl.caps.TestMultisampleES1AWT $*
@@ -339,6 +398,8 @@ testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestNEWTCloseX11DisplayBug565
#testnoawt com.jogamp.opengl.test.junit.jogl.caps.TestMultisampleES2NEWT $*
#testawt com.jogamp.opengl.test.junit.jogl.caps.TestTranslucencyAWT $*
#testawt com.jogamp.opengl.test.junit.jogl.caps.TestTranslucencyNEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.caps.TestBug605FlippedImageNEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.caps.TestBug605FlippedImageAWT $*
#testawt com.jogamp.opengl.test.junit.jogl.glsl.TestShaderCompilationBug459AWT
#testawt com.jogamp.opengl.test.junit.newt.TestWindowClosingProtocol01AWT $*
@@ -348,6 +409,14 @@ testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestNEWTCloseX11DisplayBug565
#testawt $*
#
+# Misc Utils
+#
+#testnoawt com.jogamp.opengl.test.junit.jogl.util.TestImmModeSinkES1NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.util.TestES1FixedFunctionPipelineNEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es1.newt.TestGearsES1NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es1.newt.TestRedSquareES1NEWT $*
+
+#
# Texture / TextureUtils
#
#testnoawt com.jogamp.opengl.test.junit.jogl.util.TestPNGImage01NEWT $*
@@ -365,16 +434,13 @@ testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestNEWTCloseX11DisplayBug565
#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieCube $*
#
-# GLSL / FBO / ..
+# GLSL
#
#testnoawt com.jogamp.opengl.test.junit.jogl.glsl.TestTransformFeedbackVaryingsBug407NEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.glsl.TestGLSLSimple01NEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.glsl.TestGLSLShaderState01NEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.glsl.TestGLSLShaderState02NEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.glsl.TestRulerNEWT01 $*
-#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOMRTNEWT01 $*
-#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOMix2DemosES2NEWT $*
-#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBODrawableNEWT $*
#
# Graph
@@ -409,14 +475,16 @@ testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestNEWTCloseX11DisplayBug565
#testawt com.jogamp.opengl.test.junit.newt.TestFocus01SwingAWTRobot $*
#testawt com.jogamp.opengl.test.junit.newt.TestFocus02SwingAWTRobot $*
-#linux:
-
# osx:
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLDrawable02NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.newt.TestScreenMode02NEWT
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBODrawableNEWT $*
#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParentingFocusTraversal01AWT $*
-#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParentingOffscreenLayer01GLCanvasAWT $*
-#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParentingOffscreenLayer01GLCanvasAWT $*
-#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParentingOffscreenLayer02NewtCanvasAWT $*
+#linux:
+#testawt com.jogamp.opengl.test.junit.newt.TestWindowClosingProtocol01AWT $*
+
+
$spath/count-edt-start.sh java-run.log
diff --git a/make/stub_includes/opengl/GL/glxext.h b/make/stub_includes/opengl/GL/glxext.h
index 06dbb27..3d85521 100644
--- a/make/stub_includes/opengl/GL/glxext.h
+++ b/make/stub_includes/opengl/GL/glxext.h
@@ -439,6 +439,16 @@ typedef GLXContext ( * PFNGLXCREATECONTEXTATTRIBSARBPROC) (Display *dpy, GLXFBCo
#define GLX_EXT_visual_info 1
#endif
+#ifndef GLX_MESA_swap_control
+#define GLX_MESA_swap_control 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern int glXSwapIntervalMESA(unsigned int interval);
+extern int glXGetSwapIntervalMESA(void);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef int ( * PFNGLXSWAPINTERVALMESAPROC)(unsigned int interval);
+typedef int ( * PFNGLXGETSWAPINTERVALMESAPROC)(void);
+#endif
+
#ifndef GLX_SGI_swap_control
#define GLX_SGI_swap_control 1
#ifdef GLX_GLXEXT_PROTOTYPES
diff --git a/make/stub_includes/opengl/macosx-window-system.h b/make/stub_includes/opengl/macosx-window-system.h
index 47b51a5..aaa0cc4 100644
--- a/make/stub_includes/opengl/macosx-window-system.h
+++ b/make/stub_includes/opengl/macosx-window-system.h
@@ -13,6 +13,7 @@
#include <AppKit/NSOpenGLLayer.h>
#include <OpenGL/CGLDevice.h>
#include <OpenGL/OpenGL.h>
+#include <gluegen_stdint.h>
typedef int Bool;
@@ -31,7 +32,7 @@ NSView* getNSView(NSOpenGLContext* ctx);
NSOpenGLContext* createContext(NSOpenGLContext* shareContext,
NSView* nsView,
- Bool allowIncompleteView,
+ Bool incompleteView,
NSOpenGLPixelFormat* pixelFormat,
Bool opaque,
int* viewNotReady);
@@ -51,12 +52,13 @@ NSOpenGLPixelBuffer* createPBuffer(int renderTarget, int internalFormat, int wid
Bool destroyPBuffer(NSOpenGLPixelBuffer* pBuffer);
void setContextPBuffer(NSOpenGLContext* ctx, NSOpenGLPixelBuffer* pBuffer);
void setContextTextureImageToPBuffer(NSOpenGLContext* ctx, NSOpenGLPixelBuffer* pBuffer, GLenum colorBuffer);
+Bool isNSOpenGLPixelBuffer(uint64_t object);
-// NSOpenGLLayer* createNSOpenGLLayer(NSOpenGLContext* ctx, NSOpenGLPixelFormat* fmt, NSView* view, Bool opaque);
-NSOpenGLLayer* createNSOpenGLLayer(NSOpenGLContext* ctx, NSOpenGLPixelFormat* fmt, NSOpenGLPixelBuffer* pbuffer, Bool opaque, int texWidth, int texHeight);
+NSOpenGLLayer* createNSOpenGLLayer(NSOpenGLContext* ctx, int gl3ShaderProgramName, NSOpenGLPixelFormat* fmt, NSOpenGLPixelBuffer* p, uint32_t texID, Bool opaque, int texWidth, int texHeight);
void setNSOpenGLLayerSwapInterval(NSOpenGLLayer* layer, int interval);
void waitUntilNSOpenGLLayerIsReady(NSOpenGLLayer* layer, long to_micros);
-void setNSOpenGLLayerNeedsDisplay(NSOpenGLLayer* glLayer);
+void setNSOpenGLLayerNeedsDisplayFBO(NSOpenGLLayer* layer, uint32_t texID);
+void setNSOpenGLLayerNeedsDisplayPBuffer(NSOpenGLLayer* layer, NSOpenGLPixelBuffer* p);
void releaseNSOpenGLLayer(NSOpenGLLayer *glLayer);
void* getProcAddress(const char *procName);
@@ -67,6 +69,3 @@ void setSwapInterval(NSOpenGLContext* ctx, int interval);
Bool setGammaRamp(int tableSize, float* redRamp, float* greenRamp, float* blueRamp);
void resetGammaRamp();
-/* returns the screen refresh rate in Hz */
-int getScreenRefreshRate(int scrn_idx);
-
diff --git a/make/stub_includes/x11/window-lib.c b/make/stub_includes/x11/window-lib.c
index bc5df4a..1204d03 100644
--- a/make/stub_includes/x11/window-lib.c
+++ b/make/stub_includes/x11/window-lib.c
@@ -27,9 +27,12 @@ extern void XLockDisplay(Display *display);
extern void XUnlockDisplay(Display *display);
-extern Window RootWindow(Display *display, int screen_number);
extern int DefaultScreen(Display *display);
+extern int ScreenCount(Display *display);
+
+extern Window RootWindow(Display *display, int screen_number);
+
extern XVisualInfo *XGetVisualInfo(
Display* /* display */,
long /* vinfo_mask */,
diff --git a/make/versions.xml b/make/versions.xml
index f5d17ba..6256831 100644
--- a/make/versions.xml
+++ b/make/versions.xml
@@ -12,7 +12,7 @@
betas before release candidates to give the Community time to
react.-->
<property name="jogl_base_version" value="2.0" />
- <property name="jogl_int_version" value="0914010" /> <!-- xxyyzzz, xx=API yy screen-from-to zzz app-version-->
+ <property name="jogl_int_version" value="0914011" /> <!-- xxyyzzz, xx=API yy screen-from-to zzz app-version-->
<!-- Uncomment this property in order to produce a JOGL release
build without running the "RI" (Reference Implementation)
diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/RenderState.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/RenderState.java
index eb07142..5e305d6 100644
--- a/src/jogl/classes/com/jogamp/graph/curve/opengl/RenderState.java
+++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/RenderState.java
@@ -93,19 +93,19 @@ public abstract class RenderState {
return false;
}
- public StringBuilder toString(StringBuilder sb) {
+ public StringBuilder toString(StringBuilder sb, boolean alsoUnlocated) {
if(null==sb) {
sb = new StringBuilder();
}
sb.append("RenderState[");
- st.toString(sb).append(Platform.getNewline());
+ st.toString(sb, alsoUnlocated).append(Platform.getNewline());
sb.append("]");
return sb;
}
public String toString() {
- return toString(null).toString();
+ return toString(null, false).toString();
}
}
diff --git a/src/jogl/classes/com/jogamp/opengl/FBObject.java b/src/jogl/classes/com/jogamp/opengl/FBObject.java
index 644d87b..b7188a7 100644
--- a/src/jogl/classes/com/jogamp/opengl/FBObject.java
+++ b/src/jogl/classes/com/jogamp/opengl/FBObject.java
@@ -28,13 +28,13 @@
package com.jogamp.opengl;
-import java.util.ArrayList;
import java.util.Arrays;
import javax.media.opengl.GL;
import javax.media.opengl.GL2GL3;
import javax.media.opengl.GL3;
import javax.media.opengl.GLBase;
+import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
@@ -47,7 +47,7 @@ import com.jogamp.opengl.FBObject.Attachment.Type;
* Core utility class simplifying usage of framebuffer objects (FBO)
* with all {@link GLProfile}s.
* <p>
- * Supports on-the-fly reconfiguration of dimension and multisample buffers via {@link #reset(GL, int, int, int)}
+ * Supports on-the-fly reconfiguration of dimension and multisample buffers via {@link #reset(GL, int, int, int, boolean)}
* while preserving the {@link Attachment} references.
* </p>
* <p>
@@ -59,54 +59,36 @@ import com.jogamp.opengl.FBObject.Attachment.Type;
*/
public class FBObject {
protected static final boolean DEBUG = Debug.debug("FBObject");
+ private static final boolean forceMinimumFBOSupport = Debug.isPropertyDefined("jogl.fbo.force.min", true);
+ private static final boolean FBOResizeQuirk = false;
+
+ private static enum DetachAction { NONE, DISPOSE, RECREATE };
/**
- * Returns <code>true</code> if basic FBO support is available, otherwise <code>false</code>.
- * <p>
- * Basic FBO is supported if the context is either GL-ES >= 2.0, GL >= core 3.0 or implements the extensions
- * <code>ARB_ES2_compatibility</code>, <code>ARB_framebuffer_object</code>, <code>EXT_framebuffer_object</code> or <code>OES_framebuffer_object</code>.
- * </p>
- * <p>
- * Basic FBO support may only include one color attachment and no multisampling,
- * as well as limited internal formats for renderbuffer.
- * </p>
- * @see GLContext#hasFBO()
- */
- public static final boolean supportsBasicFBO(GL gl) {
- return gl.getContext().hasFBO();
- }
-
- /**
- * Returns <code>true</code> if full FBO support is available, otherwise <code>false</code>.
- * <p>
- * Full FBO is supported if the context is either GL >= core 3.0 or implements the extensions
- * <code>ARB_framebuffer_object</code>, or all of
- * <code>EXT_framebuffer_object</code>, <code>EXT_framebuffer_multisample</code>,
- * <code>EXT_framebuffer_blit</code>, <code>GL_EXT_packed_depth_stencil</code>.
- * </p>
- * <p>
- * Full FBO support includes multiple color attachments and multisampling.
- * </p>
+ * Marker interface, denotes a color buffer attachment.
+ * <p>Always an instance of {@link Attachment}.</p>
+ * <p>Either an instance of {@link ColorAttachment} or {@link TextureAttachment}.</b>
*/
- public static final boolean supportsFullFBO(GL gl) {
- return gl.isGL3() || // GL >= 3.0
-
- gl.isExtensionAvailable(GLExtensions.ARB_framebuffer_object) || // ARB_framebuffer_object
-
- ( gl.isExtensionAvailable(GLExtensions.EXT_framebuffer_object) && // All EXT_framebuffer_object*
- gl.isExtensionAvailable(GLExtensions.EXT_framebuffer_multisample) &&
- gl.isExtensionAvailable(GLExtensions.EXT_framebuffer_blit) &&
- gl.isExtensionAvailable(GLExtensions.EXT_packed_depth_stencil) ) ;
- }
-
- public static final int getMaxSamples(GL gl) {
- if( supportsFullFBO(gl) ) {
- int[] val = new int[] { 0 } ;
- gl.glGetIntegerv(GL2GL3.GL_MAX_SAMPLES, val, 0);
- return val[0];
- } else {
- return 0;
- }
+ public static interface Colorbuffer {
+ /**
+ * Initializes the color buffer and set it's parameter, if uninitialized, i.e. name is <code>zero</code>.
+ * @return <code>true</code> if newly initialized, otherwise <code>false</code>.
+ * @throws GLException if buffer generation or setup fails. The just created buffer name will be deleted in this case.
+ */
+ public boolean initialize(GL gl) throws GLException;
+
+ /**
+ * Releases the color buffer if initialized, i.e. name is not <code>zero</code>.
+ * @throws GLException if buffer release fails.
+ */
+ public void free(GL gl) throws GLException;
+
+ /**
+ * Writes the internal format to the given GLCapabilities object.
+ * @param caps the destination for format bits
+ * @param rgba8Avail whether rgba8 is available
+ */
+ public void formatToGLCapabilities(GLCapabilities caps, boolean rgba8Avail);
}
/** Common super class of all attachments */
@@ -137,7 +119,7 @@ public class FBObject {
case GL.GL_DEPTH24_STENCIL8:
return Type.DEPTH_STENCIL;
default:
- throw new IllegalArgumentException("format invalid: 0x"+Integer.toHexString(format));
+ throw new IllegalArgumentException("format invalid: "+toHexString(format));
}
}
};
@@ -152,21 +134,91 @@ public class FBObject {
private int name;
- /** <code>true</code> if resource is initialized by {@link #initialize(GL)}, hence {@link #free(GL)} is allowed to free the GL resources. */
- protected boolean resourceOwner;
-
- private int initCounter;
-
protected Attachment(Type type, int iFormat, int width, int height, int name) {
this.type = type;
this.format = iFormat;
this.width = width;
this.height = height;
this.name = name;
- this.resourceOwner = false;
- this.initCounter = 0;
}
+ /**
+ * Writes the internal format to the given GLCapabilities object.
+ * @param caps the destination for format bits
+ * @param rgba8Avail whether rgba8 is available
+ */
+ public final void formatToGLCapabilities(GLCapabilities caps, boolean rgba8Avail) {
+ final int _format;
+ switch(format) {
+ case GL.GL_RGBA:
+ case 4:
+ _format = rgba8Avail ? GL.GL_RGBA8 : GL.GL_RGBA4;
+ break;
+ case GL.GL_RGB:
+ case 3:
+ _format = rgba8Avail ? GL.GL_RGB8 : GL.GL_RGB565;
+ break;
+ default:
+ _format = format;
+ }
+ switch(_format) {
+ case GL.GL_RGBA4:
+ caps.setRedBits(4);
+ caps.setGreenBits(4);
+ caps.setBlueBits(4);
+ caps.setAlphaBits(4);
+ break;
+ case GL.GL_RGB5_A1:
+ caps.setRedBits(5);
+ caps.setGreenBits(5);
+ caps.setBlueBits(5);
+ caps.setAlphaBits(1);
+ break;
+ case GL.GL_RGB565:
+ caps.setRedBits(5);
+ caps.setGreenBits(6);
+ caps.setBlueBits(5);
+ caps.setAlphaBits(0);
+ break;
+ case GL.GL_RGB8:
+ caps.setRedBits(8);
+ caps.setGreenBits(8);
+ caps.setBlueBits(8);
+ caps.setAlphaBits(0);
+ break;
+ case GL.GL_RGBA8:
+ caps.setRedBits(8);
+ caps.setGreenBits(8);
+ caps.setBlueBits(8);
+ caps.setAlphaBits(8);
+ break;
+ case GL.GL_DEPTH_COMPONENT16:
+ caps.setDepthBits(16);
+ break;
+ case GL.GL_DEPTH_COMPONENT24:
+ caps.setDepthBits(24);
+ break;
+ case GL.GL_DEPTH_COMPONENT32:
+ caps.setDepthBits(32);
+ break;
+ case GL.GL_STENCIL_INDEX1:
+ caps.setStencilBits(1);
+ break;
+ case GL.GL_STENCIL_INDEX4:
+ caps.setStencilBits(4);
+ break;
+ case GL.GL_STENCIL_INDEX8:
+ caps.setStencilBits(8);
+ break;
+ case GL.GL_DEPTH24_STENCIL8:
+ caps.setDepthBits(24);
+ caps.setStencilBits(8);
+ break;
+ default:
+ throw new IllegalArgumentException("format invalid: "+toHexString(format));
+ }
+ }
+
/** width of attachment */
public final int getWidth() { return width; }
/** height of attachment */
@@ -177,45 +229,31 @@ public class FBObject {
public final int getName() { return name; }
/* pp */ final void setName(int n) { name = n; }
- public final int getInitCounter() { return initCounter; }
-
/**
- * Initializes the attachment buffer and set it's parameter, if uninitialized, i.e. name is <code>zero</code>.
- * <p>Implementation employs an initialization counter, hence it can be paired recursively with {@link #free(GL)}.</p>
- * @throws GLException if buffer generation or setup fails. The just created buffer name will be deleted in this case.
- */
- public void initialize(GL gl) throws GLException {
- initCounter++;
- /*
- super.initialize(gl);
- if(1 == getInitCounter() && 0 == getName() ) {
+ * Initializes the attachment and set it's parameter, if uninitialized, i.e. name is <code>zero</code>.
+ * <pre>
+ final boolean init = 0 == name;
+ if( init ) {
do init ..
- freeResources = true; // if all OK
}
- */
- }
+ return init;
+ * </pre>
+ * @return <code>true</code> if newly initialized, otherwise <code>false</code>.
+ * @throws GLException if buffer generation or setup fails. The just created buffer name will be deleted in this case.
+ */
+ public abstract boolean initialize(GL gl) throws GLException;
/**
- * Releases the attachment buffer if initialized, i.e. name is <code>zero</code>.
- * <p>Implementation employs an initialization counter, hence it can be paired recursively with {@link #initialize(GL)}.</p>
- * @throws GLException if buffer release fails.
- */
- public void free(GL gl) throws GLException {
- /*
- if(1 == getInitCounter() && freeResources && .. ) {
+ * Releases the attachment if initialized, i.e. name is not <code>zero</code>.
+ * <pre>
+ if(0 != name) {
do free ..
- }
- super.free(gl);
- */
- initCounter--;
- if(0 == initCounter) {
- resourceOwner = false;
name = 0;
}
- if(DEBUG) {
- System.err.println("Attachment.free: "+this);
- }
- }
+ * </pre>
+ * @throws GLException if buffer release fails.
+ */
+ public abstract void free(GL gl) throws GLException;
/**
* <p>
@@ -229,9 +267,9 @@ public class FBObject {
if( ! ( o instanceof Attachment ) ) return false;
final Attachment a = (Attachment)o;
return type == a.type &&
- format == a.format ||
- width == a.width ||
- height== a.height ||
+ format == a.format &&
+ width == a.width &&
+ height== a.height &&
name == a.name ;
}
@@ -255,9 +293,8 @@ public class FBObject {
int objectHashCode() { return super.hashCode(); }
public String toString() {
- return getClass().getSimpleName()+"[type "+type+", format 0x"+Integer.toHexString(format)+", "+width+"x"+height+
- ", name 0x"+Integer.toHexString(name)+", obj 0x"+Integer.toHexString(objectHashCode())+
- ", resOwner "+resourceOwner+", initCount "+initCounter+"]";
+ return getClass().getSimpleName()+"[type "+type+", format "+toHexString(format)+", "+width+"x"+height+
+ "; name "+toHexString(name)+", obj "+toHexString(objectHashCode())+"]";
}
public static Type getType(int attachmentPoint, int maxColorAttachments) {
@@ -270,17 +307,17 @@ public class FBObject {
case GL.GL_STENCIL_ATTACHMENT:
return Type.STENCIL;
default:
- throw new IllegalArgumentException("Invalid attachment point 0x"+Integer.toHexString(attachmentPoint));
+ throw new IllegalArgumentException("Invalid attachment point "+toHexString(attachmentPoint));
}
}
}
-
+
/** Other renderbuffer attachment which maybe a colorbuffer, depth or stencil. */
public static class RenderAttachment extends Attachment {
private int samples;
/**
- * @param type allowed types are {@link Type#DEPTH}, {@link Type#STENCIL} or {@link Type#COLOR}
+ * @param type allowed types are {@link Type#DEPTH_STENCIL} {@link Type#DEPTH}, {@link Type#STENCIL} or {@link Type#COLOR}
* @param iFormat
* @param samples
* @param width
@@ -298,6 +335,7 @@ public class FBObject {
private static Type validateType(Type type) {
switch(type) {
+ case DEPTH_STENCIL:
case DEPTH:
case STENCIL:
case COLOR:
@@ -336,14 +374,13 @@ public class FBObject {
}
@Override
- public void initialize(GL gl) throws GLException {
- super.initialize(gl);
- if( 1 == getInitCounter() && 0 == getName() ) {
+ public boolean initialize(GL gl) throws GLException {
+ final boolean init = 0 == getName();
+ if( init ) {
+ checkPreGLError(gl);
+
final int[] name = new int[] { -1 };
gl.glGenRenderbuffers(1, name, 0);
- if( 0 == name[0] ) {
- throw new GLException("null renderbuffer, "+this);
- }
setName(name[0]);
gl.glBindRenderbuffer(GL.GL_RENDERBUFFER, getName());
@@ -352,43 +389,37 @@ public class FBObject {
} else {
gl.glRenderbufferStorage(GL.GL_RENDERBUFFER, format, getWidth(), getHeight());
}
- int glerr = gl.glGetError();
+ final int glerr = gl.glGetError();
if(GL.GL_NO_ERROR != glerr) {
gl.glDeleteRenderbuffers(1, name, 0);
setName(0);
- throw new GLException("GL Error 0x"+Integer.toHexString(glerr)+" while creating "+this);
+ throw new GLException("GL Error "+toHexString(glerr)+" while creating "+this);
}
- resourceOwner = true;
if(DEBUG) {
- System.err.println("Attachment.init: "+this);
+ System.err.println("Attachment.init.X: "+this);
}
}
+ return init;
}
@Override
public void free(GL gl) {
- if(1 == getInitCounter() && resourceOwner && 0 != getName() ) {
- final int[] name = new int[] { getName() };
+ final int[] name = new int[] { getName() };
+ if( 0 != name[0] ) {
+ if(DEBUG) {
+ System.err.println("Attachment.free.0: "+this);
+ }
gl.glDeleteRenderbuffers(1, name, 0);
+ setName(0);
}
- super.free(gl);
}
public String toString() {
- return getClass().getSimpleName()+"[type "+type+", format 0x"+Integer.toHexString(format)+", samples "+samples+", "+getWidth()+"x"+getHeight()+
- ", name 0x"+Integer.toHexString(getName())+", obj 0x"+Integer.toHexString(objectHashCode())+
- ", resOwner "+resourceOwner+", initCount "+getInitCounter()+"]";
+ return getClass().getSimpleName()+"[type "+type+", format "+toHexString(format)+", samples "+samples+", "+getWidth()+"x"+getHeight()+
+ ", name "+toHexString(getName())+", obj "+toHexString(objectHashCode())+"]";
}
}
- /**
- * Marker interface, denotes a color buffer attachment.
- * <p>Always an instance of {@link Attachment}.</p>
- * <p>Either an instance of {@link ColorAttachment} or {@link TextureAttachment}.</b>
- */
- public static interface Colorbuffer {
- }
-
/** Color render buffer attachment */
public static class ColorAttachment extends RenderAttachment implements Colorbuffer {
public ColorAttachment(int iFormat, int samples, int width, int height, int name) {
@@ -441,9 +472,11 @@ public class FBObject {
* @throws GLException if texture generation and setup fails. The just created texture name will be deleted in this case.
*/
@Override
- public void initialize(GL gl) throws GLException {
- super.initialize(gl);
- if( 1 == getInitCounter() && 0 == getName() ) {
+ public boolean initialize(GL gl) throws GLException {
+ final boolean init = 0 == getName();
+ if( init ) {
+ checkPreGLError(gl);
+
final int[] name = new int[] { -1 };
gl.glGenTextures(1, name, 0);
if(0 == name[0]) {
@@ -452,7 +485,6 @@ public class FBObject {
setName(name[0]);
gl.glBindTexture(GL.GL_TEXTURE_2D, name[0]);
- gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, format, getWidth(), getHeight(), 0, dataFormat, dataType, null);
if( 0 < magFilter ) {
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, magFilter);
}
@@ -464,32 +496,131 @@ public class FBObject {
}
if( 0 < wrapT ) {
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, wrapT);
- }
+ }
+ boolean preTexImage2D = true;
int glerr = gl.glGetError();
+ if(GL.GL_NO_ERROR == glerr) {
+ preTexImage2D = false;
+ gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, format, getWidth(), getHeight(), 0, dataFormat, dataType, null);
+ glerr = gl.glGetError();
+ }
if(GL.GL_NO_ERROR != glerr) {
gl.glDeleteTextures(1, name, 0);
setName(0);
- throw new GLException("GL Error 0x"+Integer.toHexString(glerr)+" while creating "+this);
+ throw new GLException("GL Error "+toHexString(glerr)+" while creating (pre TexImage2D "+preTexImage2D+") "+this);
+ }
+ if(DEBUG) {
+ System.err.println("Attachment.init.X: "+this);
}
- resourceOwner = true;
- }
- if(DEBUG) {
- System.err.println("Attachment.init: "+this);
}
+ return init;
}
@Override
public void free(GL gl) {
- if(1 == getInitCounter() && resourceOwner && 0 != getName() ) {
- final int[] name = new int[] { getName() };
+ final int[] name = new int[] { getName() };
+ if( 0 != name[0] ) {
+ if(DEBUG) {
+ System.err.println("Attachment.free.0: "+this);
+ }
gl.glDeleteTextures(1, name, 0);
+ setName(0);
}
- super.free(gl);
+ }
+ public String toString() {
+ return getClass().getSimpleName()+"[type "+type+", target GL_TEXTURE_2D, level 0, format "+toHexString(format)+
+ ", "+getWidth()+"x"+getHeight()+", border 0, dataFormat "+toHexString(dataFormat)+
+ ", dataType "+toHexString(dataType)+
+ "; min/mag "+toHexString(minFilter)+"/"+toHexString(magFilter)+
+ ", wrap S/T "+toHexString(wrapS)+"/"+toHexString(wrapT)+
+ "; name "+toHexString(getName())+", obj "+toHexString(objectHashCode())+"]";
+ }
+ }
+ static String toHexString(int v) {
+ return "0x"+Integer.toHexString(v);
+ }
+
+ /**
+ * Creates a color {@link TextureAttachment}, i.e. type {@link Type#COLOR_TEXTURE},
+ * selecting the texture data type and format automatically.
+ *
+ * <p>Using default min/mag filter {@link GL#GL_NEAREST} and default wrapS/wrapT {@link GL#GL_CLAMP_TO_EDGE}.</p>
+ *
+ * @param glp the chosen {@link GLProfile}
+ * @param alpha set to <code>true</code> if you request alpha channel, otherwise <code>false</code>;
+ * @param width texture width
+ * @param height texture height
+ * @return the created and uninitialized color {@link TextureAttachment}
+ */
+ public static final TextureAttachment createColorTextureAttachment(GLProfile glp, boolean alpha, int width, int height) {
+ return createColorTextureAttachment(glp, alpha, width, height, GL.GL_NEAREST, GL.GL_NEAREST, GL.GL_CLAMP_TO_EDGE, GL.GL_CLAMP_TO_EDGE);
+ }
+
+ /**
+ * Creates a color {@link TextureAttachment}, i.e. type {@link Type#COLOR_TEXTURE},
+ * selecting the texture data type and format automatically.
+ *
+ * @param glp the chosen {@link GLProfile}
+ * @param alpha set to <code>true</code> if you request alpha channel, otherwise <code>false</code>;
+ * @param width texture width
+ * @param height texture height
+ * @param magFilter if > 0 value for {@link GL#GL_TEXTURE_MAG_FILTER}
+ * @param minFilter if > 0 value for {@link GL#GL_TEXTURE_MIN_FILTER}
+ * @param wrapS if > 0 value for {@link GL#GL_TEXTURE_WRAP_S}
+ * @param wrapT if > 0 value for {@link GL#GL_TEXTURE_WRAP_T}
+ * @return the created and uninitialized color {@link TextureAttachment}
+ */
+ public static final TextureAttachment createColorTextureAttachment(GLProfile glp, boolean alpha, int width, int height,
+ int magFilter, int minFilter, int wrapS, int wrapT) {
+ final int textureInternalFormat, textureDataFormat, textureDataType;
+ if(glp.isGLES()) {
+ textureInternalFormat = alpha ? GL.GL_RGBA : GL.GL_RGB;
+ textureDataFormat = alpha ? GL.GL_RGBA : GL.GL_RGB;
+ textureDataType = GL.GL_UNSIGNED_BYTE;
+ } else {
+ textureInternalFormat = alpha ? GL.GL_RGBA8 : GL.GL_RGB8;
+ // textureInternalFormat = alpha ? GL.GL_RGBA : GL.GL_RGB;
+ // textureInternalFormat = alpha ? 4 : 3;
+ textureDataFormat = alpha ? GL.GL_BGRA : GL.GL_RGB;
+ textureDataType = alpha ? GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV : GL.GL_UNSIGNED_BYTE;
+ }
+ return createColorTextureAttachment(textureInternalFormat, width, height, textureDataFormat, textureDataType, magFilter, minFilter, wrapS, wrapT);
+ }
+
+ /**
+ * Creates a color {@link TextureAttachment}, i.e. type {@link Type#COLOR_TEXTURE}.
+ *
+ * @param internalFormat internalFormat parameter to {@link GL#glTexImage2D(int, int, int, int, int, int, int, int, long)}
+ * @param width texture width
+ * @param height texture height
+ * @param dataFormat format parameter to {@link GL#glTexImage2D(int, int, int, int, int, int, int, int, long)}
+ * @param dataType type parameter to {@link GL#glTexImage2D(int, int, int, int, int, int, int, int, long)}
+ * @param magFilter if > 0 value for {@link GL#GL_TEXTURE_MAG_FILTER}
+ * @param minFilter if > 0 value for {@link GL#GL_TEXTURE_MIN_FILTER}
+ * @param wrapS if > 0 value for {@link GL#GL_TEXTURE_WRAP_S}
+ * @param wrapT if > 0 value for {@link GL#GL_TEXTURE_WRAP_T}
+ * @return the created and uninitialized color {@link TextureAttachment}
+ */
+ public static final TextureAttachment createColorTextureAttachment(int internalFormat, int width, int height, int dataFormat, int dataType,
+ int magFilter, int minFilter, int wrapS, int wrapT) {
+ return new TextureAttachment(Type.COLOR_TEXTURE, internalFormat, width, height, dataFormat, dataType,
+ magFilter, minFilter, wrapS, wrapT, 0 /* name */);
+ }
+
+ private static boolean hasAlpha(int format) {
+ switch(format) {
+ case GL.GL_RGBA8:
+ case GL.GL_RGBA4:
+ case GL.GL_RGBA:
+ case GL.GL_BGRA:
+ case 4:
+ return true;
+ default:
+ return false;
}
}
private boolean initialized;
- private boolean basicFBOSupport;
private boolean fullFBOSupport;
private boolean rgba8Avail;
private boolean depth24Avail;
@@ -503,6 +634,7 @@ public class FBObject {
private int width, height, samples;
private int vStatus;
+ private boolean ignoreStatus;
private int fbName;
private boolean bound;
@@ -519,18 +651,21 @@ public class FBObject {
//
private final void validateColorAttachmentPointRange(int point) {
+ if(!initialized) {
+ throw new GLException("FBO not initialized");
+ }
if(maxColorAttachments != colorAttachmentPoints.length) {
throw new InternalError("maxColorAttachments "+maxColorAttachments+", array.lenght "+colorAttachmentPoints);
}
if(0 > point || point >= maxColorAttachments) {
- throw new IllegalArgumentException("attachment point out of range: "+point+", should be within [0.."+(maxColorAttachments-1)+"]");
+ throw new IllegalArgumentException("attachment point out of range: "+point+", should be within [0.."+(maxColorAttachments-1)+"], "+this);
}
}
private final void validateAddColorAttachment(int point, Colorbuffer ca) {
validateColorAttachmentPointRange(point);
if( null != colorAttachmentPoints[point] ) {
- throw new IllegalArgumentException("Cannot attach "+ca+", attachment point already in use by "+colorAttachmentPoints[point]);
+ throw new IllegalArgumentException("Cannot attach "+ca+", attachment point already in use by "+colorAttachmentPoints[point]+", "+this);
}
}
@@ -617,7 +752,6 @@ public class FBObject {
this.initialized = false;
// TBD @ init
- this.basicFBOSupport = false;
this.fullFBOSupport = false;
this.rgba8Avail = false;
this.depth24Avail = false;
@@ -635,7 +769,8 @@ public class FBObject {
this.width = 0;
this.height = 0;
this.samples = 0;
- this.vStatus = -1;
+ this.vStatus = -1;
+ this.ignoreStatus = false;
this.fbName = 0;
this.bound = false;
@@ -652,14 +787,11 @@ public class FBObject {
private void init(GL gl, int width, int height, int samples) throws GLException {
if(initialized) {
throw new GLException("FBO already initialized");
- }
- fullFBOSupport = supportsFullFBO(gl);
-
- if( !fullFBOSupport && !supportsBasicFBO(gl) ) {
+ }
+ if( !gl.hasBasicFBOSupport() ) {
throw new GLException("FBO not supported w/ context: "+gl.getContext()+", "+this);
}
-
- basicFBOSupport = true;
+ fullFBOSupport = gl.hasFullFBOSupport();
rgba8Avail = gl.isGL2GL3() || gl.isExtensionAvailable(GLExtensions.OES_rgb8_rgba8);
depth24Avail = fullFBOSupport || gl.isExtensionAvailable(GLExtensions.OES_depth24);
@@ -669,64 +801,51 @@ public class FBObject {
stencil08Avail = fullFBOSupport || gl.isExtensionAvailable(GLExtensions.OES_stencil8);
stencil16Avail = fullFBOSupport;
- packedDepthStencilAvail = fullFBOSupport || gl.isExtensionAvailable(GLExtensions.OES_packed_depth_stencil);
+ packedDepthStencilAvail = fullFBOSupport ||
+ gl.isExtensionAvailable(GLExtensions.OES_packed_depth_stencil) ||
+ gl.isExtensionAvailable(GLExtensions.EXT_packed_depth_stencil) ;
final boolean NV_fbo_color_attachments = gl.isExtensionAvailable(GLExtensions.NV_fbo_color_attachments);
int val[] = new int[1];
- int glerr = gl.glGetError();
- if(DEBUG && GL.GL_NO_ERROR != glerr) {
- System.err.println("FBObject.init-preexisting.0 GL Error 0x"+Integer.toHexString(glerr));
- }
+ checkPreGLError(gl);
int realMaxColorAttachments = 1;
maxColorAttachments = 1;
if( null != samplesSink && fullFBOSupport || NV_fbo_color_attachments ) {
try {
gl.glGetIntegerv(GL2GL3.GL_MAX_COLOR_ATTACHMENTS, val, 0);
- glerr = gl.glGetError();
- if(GL.GL_NO_ERROR == glerr) {
- realMaxColorAttachments = 1 <= val[0] ? val[0] : 1; // cap minimum to 1
- } else if(DEBUG) {
- System.err.println("FBObject.init-GL_MAX_COLOR_ATTACHMENTS query GL Error 0x"+Integer.toHexString(glerr));
- }
- } catch (GLException gle) {}
+ realMaxColorAttachments = 1 <= val[0] ? val[0] : 1; // cap minimum to 1
+ } catch (GLException gle) { gle.printStackTrace(); }
}
maxColorAttachments = realMaxColorAttachments <= 8 ? realMaxColorAttachments : 8; // cap to limit array size
colorAttachmentPoints = new Colorbuffer[maxColorAttachments];
colorAttachmentCount = 0;
- maxSamples = 0;
- if(fullFBOSupport) {
- gl.glGetIntegerv(GL2GL3.GL_MAX_SAMPLES, val, 0);
- glerr = gl.glGetError();
- if(GL.GL_NO_ERROR == glerr) {
- maxSamples = val[0];
- } else if(DEBUG) {
- System.err.println("FBObject.init-GL_MAX_SAMPLES query GL Error 0x"+Integer.toHexString(glerr));
- }
+ maxSamples = gl.getMaxRenderbufferSamples();
+ if(!forceMinimumFBOSupport) {
+ gl.glGetIntegerv(GL.GL_MAX_TEXTURE_SIZE, val, 0);
+ maxTextureSize = val[0];
+ gl.glGetIntegerv(GL.GL_MAX_RENDERBUFFER_SIZE, val, 0);
+ maxRenderbufferSize = val[0];
+ } else {
+ maxTextureSize = 2048;
+ maxRenderbufferSize = 2048;
}
- gl.glGetIntegerv(GL.GL_MAX_TEXTURE_SIZE, val, 0);
- maxTextureSize = val[0];
- gl.glGetIntegerv(GL.GL_MAX_RENDERBUFFER_SIZE, val, 0);
- this.maxRenderbufferSize = val[0];
- glerr = gl.glGetError();
- if(DEBUG && GL.GL_NO_ERROR != glerr) {
- System.err.println("FBObject.init-preexisting.1 GL Error 0x"+Integer.toHexString(glerr));
- }
+ checkPreGLError(gl);
this.width = width;
this.height = height;
this.samples = samples <= maxSamples ? samples : maxSamples;
if(DEBUG) {
- System.err.println("FBObject "+width+"x"+height+", "+samples+" -> "+samples+" samples");
- System.err.println("basicFBOSupport: "+basicFBOSupport);
+ System.err.println("FBObject "+width+"x"+height+", "+samples+" -> "+this.samples+" samples");
System.err.println("fullFBOSupport: "+fullFBOSupport);
- System.err.println("maxColorAttachments: "+maxColorAttachments+"/"+realMaxColorAttachments);
+ System.err.println("isSamplesSink: "+(null == samplesSink));
+ System.err.println("maxColorAttachments: "+maxColorAttachments+"/"+realMaxColorAttachments+" [capped/real]");
System.err.println("maxSamples: "+maxSamples);
System.err.println("maxTextureSize: "+maxTextureSize);
System.err.println("maxRenderbufferSize: "+maxRenderbufferSize);
@@ -751,12 +870,8 @@ public class FBObject {
throw new GLException("size "+width+"x"+height+" exceeds on of the maxima [texture "+maxTextureSize+", renderbuffer "+maxRenderbufferSize+"]");
}
- if(null != samplesSink) {
- // init sampling sink
- samplesSink.reset(gl, width, height);
- resetMSAATexture2DSink(gl);
- }
-
+ resetSamplingSink(gl);
+
// generate fbo ..
gl.glGenFramebuffers(1, val, 0);
fbName = val[0];
@@ -770,10 +885,11 @@ public class FBObject {
if(!gl.glIsFramebuffer(fbName)) {
checkNoError(gl, GL.GL_INVALID_VALUE, "FBObject Init.isFB"); // throws GLException
}
- bound = true;
+ bound = true;
+ samplesSinkDirty = true;
initialized = true;
- updateStatus(gl);
+ vStatus = GL.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; // always incomplete w/o attachments!
if(DEBUG) {
System.err.println("FBObject.init(): "+this);
}
@@ -787,7 +903,7 @@ public class FBObject {
* to match the new given parameters.
* </p>
* <p>
- * Currently incompatibility and hence recreation is given if
+ * Incompatibility and hence recreation is forced if
* the size or sample count doesn't match for subsequent calls.
* </p>
*
@@ -799,7 +915,7 @@ public class FBObject {
* @throws GLException in case of an error
*/
public final void reset(GL gl, int newWidth, int newHeight) {
- reset(gl, newWidth, newHeight, 0);
+ reset(gl, newWidth, newHeight, 0, false);
}
/**
@@ -810,28 +926,41 @@ public class FBObject {
* to match the new given parameters.
* </p>
* <p>
- * Currently incompatibility and hence recreation is given if
- * the size or sample count doesn't match for subsequent calls.
+ * Currently incompatibility and hence recreation of the attachments will be performed
+ * if the size or sample count doesn't match for subsequent calls.
* </p>
*
* <p>Leaves the FBO bound state untouched</p>
*
* @param gl the current GL context
- * @param newWidth
- * @param newHeight
+ * @param newWidth the new width, it's minimum is capped to 1
+ * @param newHeight the new height, it's minimum is capped to 1
* @param newSamples if > 0, MSAA will be used, otherwise no multisampling. Will be capped to {@link #getMaxSamples()}.
- * @throws GLException in case of an error
+ * @param resetSamplingSink <code>true</code> calls {@link #resetSamplingSink(GL)} immediatly.
+ * <code>false</code> postpones resetting the sampling sink until {@link #use(GL, TextureAttachment)} or {@link #syncSamplingSink(GL)},
+ * allowing to use the samples sink's FBO and texture until then. The latter is useful to benefit
+ * from implicit double buffering while resetting the sink just before it's being used, eg. at swap-buffer.
+ *
+ * @throws GLException in case of an error, i.e. size too big, etc ..
*/
- public final void reset(GL gl, int newWidth, int newHeight, int newSamples) {
+ public final void reset(GL gl, int newWidth, int newHeight, int newSamples, boolean resetSamplingSink) {
if(!initialized) {
init(gl, newWidth, newHeight, newSamples);
return;
}
+
newSamples = newSamples <= maxSamples ? newSamples : maxSamples; // clamp
if( newWidth != width || newHeight != height || newSamples != samples ) {
+ if(0>=newWidth) { newWidth = 1; }
+ if(0>=newHeight) { newHeight = 1; }
+ if(newWidth > 2 + maxTextureSize || newHeight> 2 + maxTextureSize ||
+ newWidth > maxRenderbufferSize || newHeight> maxRenderbufferSize ) {
+ throw new GLException("size "+width+"x"+height+" exceeds on of the maxima [texture "+maxTextureSize+", renderbuffer "+maxRenderbufferSize+"]");
+ }
+
if(DEBUG) {
- System.err.println("FBObject.reset - START - "+this);
+ System.err.println("FBObject.reset - START - "+width+"x"+height+", "+samples+" -> "+newWidth+"x"+newHeight+", "+newSamples+"; "+this);
}
final boolean wasBound = isBound();
@@ -839,12 +968,14 @@ public class FBObject {
width = newWidth;
height = newHeight;
samples = newSamples;
- detachAllImpl(gl, true , true);
- resetMSAATexture2DSink(gl);
+ detachAllImpl(gl, true , true);
+ if(resetSamplingSink) {
+ resetSamplingSink(gl);
+ }
- if(wasBound) {
- bind(gl);
- } else {
+ samplesSinkDirty = true;
+
+ if(!wasBound) {
unbind(gl);
}
@@ -854,6 +985,28 @@ public class FBObject {
}
}
+ /**
+ * Writes the internal format of the attachments to the given GLCapabilities object.
+ * @param caps the destination for format bits
+ */
+ public final void formatToGLCapabilities(GLCapabilities caps) {
+ caps.setSampleBuffers(samples > 0);
+ caps.setNumSamples(samples);
+ caps.setDepthBits(0);
+ caps.setStencilBits(0);
+
+ final Colorbuffer cb = samples > 0 ? getSamplingSink() : getColorbuffer(0);
+ if(null != cb) {
+ cb.formatToGLCapabilities(caps, rgba8Avail);
+ }
+ if(null != depth) {
+ depth.formatToGLCapabilities(caps, rgba8Avail);
+ }
+ if(null != stencil && stencil != depth) {
+ stencil.formatToGLCapabilities(caps, rgba8Avail);
+ }
+ }
+
/**
* Note that the status may reflect an incomplete state during transition of attachments.
* @return The FB status. {@link GL.GL_FRAMEBUFFER_COMPLETE} if ok, otherwise return GL FBO error state or -1
@@ -877,31 +1030,31 @@ public class FBObject {
return "OK";
case GL.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
- return("GL FBO: incomplete, incomplete attachment\n");
+ return("FBO incomplete attachment\n");
case GL.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
- return("GL FBO: incomplete, missing attachment");
+ return("FBO missing attachment");
case GL.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
- return("GL FBO: incomplete, attached images must have same dimensions");
+ return("FBO attached images must have same dimensions");
case GL.GL_FRAMEBUFFER_INCOMPLETE_FORMATS:
- return("GL FBO: incomplete, attached images must have same format");
+ return("FBO attached images must have same format");
case GL2GL3.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
- return("GL FBO: incomplete, missing draw buffer");
+ return("FBO missing draw buffer");
case GL2GL3.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
- return("GL FBO: incomplete, missing read buffer");
+ return("FBO missing read buffer");
case GL2GL3.GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
- return("GL FBO: incomplete, missing multisample buffer");
+ return("FBO missing multisample buffer");
case GL3.GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS:
- return("GL FBO: incomplete, layer targets");
+ return("FBO missing layer targets");
case GL.GL_FRAMEBUFFER_UNSUPPORTED:
- return("GL FBO: Unsupported framebuffer format");
+ return("Unsupported FBO format");
case GL2GL3.GL_FRAMEBUFFER_UNDEFINED:
- return("GL FBO: framebuffer undefined");
+ return("FBO undefined");
case 0:
- return("GL FBO: incomplete, implementation fault");
+ return("FBO implementation fault");
default:
- return("GL FBO: incomplete, implementation ERROR 0x"+Integer.toHexString(fbStatus));
+ return("FBO incomplete, implementation ERROR "+toHexString(fbStatus));
}
}
@@ -932,19 +1085,28 @@ public class FBObject {
case 0:
default:
- System.out.println("Framebuffer " + fbName + " is incomplete: status = 0x" + Integer.toHexString(vStatus) +
+ System.err.println("Framebuffer " + fbName + " is incomplete, status = " + toHexString(vStatus) +
" : " + getStatusString(vStatus));
return false;
}
}
+ private static int checkPreGLError(GL gl) {
+ int glerr = gl.glGetError();
+ if(DEBUG && GL.GL_NO_ERROR != glerr) {
+ System.err.println("Pre-existing GL error: "+toHexString(glerr));
+ Thread.dumpStack();
+ }
+ return glerr;
+ }
+
private final boolean checkNoError(GL gl, int err, String exceptionMessage) throws GLException {
if(GL.GL_NO_ERROR != err) {
if(null != gl) {
destroy(gl);
}
if(null != exceptionMessage) {
- throw new GLException(exceptionMessage+" GL Error 0x"+Integer.toHexString(err));
+ throw new GLException(exceptionMessage+" GL Error "+toHexString(err)+" of "+this.toString());
}
return false;
}
@@ -958,7 +1120,7 @@ public class FBObject {
}
/**
- * Attaches a Texture2D Color Buffer to this FBO's instance at the given attachment point,
+ * Attaches a {@link Colorbuffer}, i.e. {@link TextureAttachment}, to this FBO's instance at the given attachment point,
* selecting the texture data type and format automatically.
*
* <p>Using default min/mag filter {@link GL#GL_NEAREST} and default wrapS/wrapT {@link GL#GL_CLAMP_TO_EDGE}.</p>
@@ -970,13 +1132,15 @@ public class FBObject {
* @param alpha set to <code>true</code> if you request alpha channel, otherwise <code>false</code>;
* @return TextureAttachment instance describing the new attached texture colorbuffer if bound and configured successfully, otherwise GLException is thrown
* @throws GLException in case the texture colorbuffer couldn't be allocated or MSAA has been chosen
+ * @see #createColorTextureAttachment(GLProfile, boolean, int, int)
*/
public final TextureAttachment attachTexture2D(GL gl, int attachmentPoint, boolean alpha) throws GLException {
- return attachTexture2D(gl, attachmentPoint, alpha, GL.GL_NEAREST, GL.GL_NEAREST, GL.GL_CLAMP_TO_EDGE, GL.GL_CLAMP_TO_EDGE);
+ return (TextureAttachment)attachColorbuffer(gl, attachmentPoint,
+ createColorTextureAttachment(gl.getGLProfile(), alpha, width, height));
}
/**
- * Attaches a Texture2D Color Buffer to this FBO's instance at the given attachment point,
+ * Attaches a {@link Colorbuffer}, i.e. {@link TextureAttachment}, to this FBO's instance at the given attachment point,
* selecting the texture data type and format automatically.
*
* <p>Leaves the FBO bound.</p>
@@ -990,23 +1154,15 @@ public class FBObject {
* @param wrapT if > 0 value for {@link GL#GL_TEXTURE_WRAP_T}
* @return TextureAttachment instance describing the new attached texture colorbuffer if bound and configured successfully, otherwise GLException is thrown
* @throws GLException in case the texture colorbuffer couldn't be allocated or MSAA has been chosen
+ * @see #createColorTextureAttachment(GLProfile, boolean, int, int, int, int, int, int)
*/
public final TextureAttachment attachTexture2D(GL gl, int attachmentPoint, boolean alpha, int magFilter, int minFilter, int wrapS, int wrapT) throws GLException {
- final int textureInternalFormat, textureDataFormat, textureDataType;
- if(gl.isGLES()) {
- textureInternalFormat = alpha ? GL.GL_RGBA : GL.GL_RGB;
- textureDataFormat = alpha ? GL.GL_RGBA : GL.GL_RGB;
- textureDataType = GL.GL_UNSIGNED_BYTE;
- } else {
- textureInternalFormat = alpha ? GL.GL_RGBA8 : GL.GL_RGB8;
- textureDataFormat = alpha ? GL.GL_BGRA : GL.GL_RGB;
- textureDataType = alpha ? GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV : GL.GL_UNSIGNED_BYTE;
- }
- return attachTexture2D(gl, attachmentPoint, textureInternalFormat, textureDataFormat, textureDataType, magFilter, minFilter, wrapS, wrapT);
+ return (TextureAttachment)attachColorbuffer(gl, attachmentPoint,
+ createColorTextureAttachment(gl.getGLProfile(), alpha, width, height, magFilter, minFilter, wrapS, wrapT));
}
/**
- * Attaches a Texture2D Color Buffer to this FBO's instance at the given attachment point.
+ * Attaches a {@link Colorbuffer}, i.e. {@link TextureAttachment}, to this FBO's instance at the given attachment point.
*
* <p>Leaves the FBO bound.</p>
*
@@ -1021,64 +1177,33 @@ public class FBObject {
* @param wrapT if > 0 value for {@link GL#GL_TEXTURE_WRAP_T}
* @return TextureAttachment instance describing the new attached texture colorbuffer if bound and configured successfully, otherwise GLException is thrown
* @throws GLException in case the texture colorbuffer couldn't be allocated or MSAA has been chosen
+ * @see #createColorTextureAttachment(int, int, int, int, int, int, int, int, int)
*/
public final TextureAttachment attachTexture2D(GL gl, int attachmentPoint,
int internalFormat, int dataFormat, int dataType,
int magFilter, int minFilter, int wrapS, int wrapT) throws GLException {
- return attachTexture2D(gl, attachmentPoint,
- new TextureAttachment(Type.COLOR_TEXTURE, internalFormat, width, height, dataFormat, dataType,
- magFilter, minFilter, wrapS, wrapT, 0 /* name */));
+ return (TextureAttachment)attachColorbuffer(gl, attachmentPoint,
+ createColorTextureAttachment(internalFormat, width, height, dataFormat, dataType, magFilter, minFilter, wrapS, wrapT));
}
/**
- * Attaches a Texture2D Color Buffer to this FBO's instance at the given attachment point.
+ * Creates a {@link ColorAttachment}, selecting the format automatically.
*
- * <p>
- * In case the passed TextureAttachment <code>texA</code> is uninitialized, i.e. it's texture name is <code>zero</code>,
- * a new texture name is generated and setup w/ the texture parameter.<br/>
- * Otherwise, i.e. texture name is not <code>zero</code>, the passed TextureAttachment <code>texA</code> is
- * considered complete and assumed matching this FBO requirement. A GL error may occur is the latter is untrue.
- * </p>
- *
- * <p>Leaves the FBO bound.</p>
- *
- * @param gl the current GL context
- * @param attachmentPoint the color attachment point ranging from [0..{@link #getMaxColorAttachments()}-1]
- * @param texA the to be attached {@link TextureAttachment}. Maybe complete or uninitialized, see above.
- * @return the passed TextureAttachment <code>texA</code> instance describing the new attached texture colorbuffer if bound and configured successfully, otherwise GLException is thrown
- * @throws GLException in case the texture colorbuffer couldn't be allocated or MSAA has been chosen
+ * @param alpha set to <code>true</code> if you request alpha channel, otherwise <code>false</code>;
+ * @return uninitialized ColorAttachment instance describing the new attached colorbuffer
*/
- public final TextureAttachment attachTexture2D(GL gl, int attachmentPoint, TextureAttachment texA) throws GLException {
- validateAddColorAttachment(attachmentPoint, texA);
-
- if(samples>0) {
- removeColorAttachment(attachmentPoint, texA);
- throw new GLException("Texture2D not supported w/ MSAA. If you have enabled MSAA with exisiting texture attachments, you may want to detach them via detachAllTexturebuffer(gl).");
- }
-
- texA.initialize(gl);
- addColorAttachment(attachmentPoint, texA);
-
- bind(gl);
-
- // Set up the color buffer for use as a renderable texture:
- gl.glFramebufferTexture2D(GL.GL_FRAMEBUFFER,
- GL.GL_COLOR_ATTACHMENT0 + attachmentPoint,
- GL.GL_TEXTURE_2D, texA.getName(), 0);
- updateStatus(gl);
-
- if(!isStatusValid()) {
- detachColorbuffer(gl, attachmentPoint);
- throw new GLException("attachTexture2D "+texA+" at "+attachmentPoint+" failed "+getStatusString()+", "+this);
- }
- if(DEBUG) {
- System.err.println("FBObject.attachTexture2D: "+this);
+ public final ColorAttachment createColorAttachment(boolean alpha) {
+ final int internalFormat;
+ if( rgba8Avail ) {
+ internalFormat = alpha ? GL.GL_RGBA8 : GL.GL_RGB8 ;
+ } else {
+ internalFormat = alpha ? GL.GL_RGBA4 : GL.GL_RGB565;
}
- return texA;
+ return new ColorAttachment(internalFormat, samples, width, height, 0);
}
-
+
/**
- * Attaches a Color Buffer to this FBO's instance at the given attachment point,
+ * Attaches a {@link Colorbuffer}, i.e. {@link ColorAttachment}, to this FBO's instance at the given attachment point,
* selecting the format automatically.
*
* <p>Leaves the FBO bound.</p>
@@ -1088,19 +1213,14 @@ public class FBObject {
* @param alpha set to <code>true</code> if you request alpha channel, otherwise <code>false</code>;
* @return ColorAttachment instance describing the new attached colorbuffer if bound and configured successfully, otherwise GLException is thrown
* @throws GLException in case the colorbuffer couldn't be allocated
+ * @see #createColorAttachment(boolean)
*/
public final ColorAttachment attachColorbuffer(GL gl, int attachmentPoint, boolean alpha) throws GLException {
- final int internalFormat;
- if( rgba8Avail ) {
- internalFormat = alpha ? GL.GL_RGBA8 : GL.GL_RGB8 ;
- } else {
- internalFormat = alpha ? GL.GL_RGBA4 : GL.GL_RGB565;
- }
- return attachColorbuffer(gl, attachmentPoint, internalFormat);
+ return (ColorAttachment) attachColorbuffer(gl, attachmentPoint, createColorAttachment(alpha));
}
/**
- * Attaches a Color Buffer to this FBO's instance at the given attachment point.
+ * Attaches a {@link Colorbuffer}, i.e. {@link ColorAttachment}, to this FBO's instance at the given attachment point.
*
* <p>Leaves the FBO bound.</p>
*
@@ -1114,47 +1234,86 @@ public class FBObject {
public final ColorAttachment attachColorbuffer(GL gl, int attachmentPoint, int internalFormat) throws GLException, IllegalArgumentException {
final Attachment.Type atype = Attachment.Type.determine(internalFormat);
if( Attachment.Type.COLOR != atype ) {
- throw new IllegalArgumentException("colorformat invalid: 0x"+Integer.toHexString(internalFormat)+", "+this);
+ throw new IllegalArgumentException("colorformat invalid: "+toHexString(internalFormat)+", "+this);
}
- return attachColorbuffer(gl, attachmentPoint, new ColorAttachment(internalFormat, samples, width, height, 0));
+ return (ColorAttachment) attachColorbuffer(gl, attachmentPoint, new ColorAttachment(internalFormat, samples, width, height, 0));
}
/**
- * Attaches a Color Buffer to this FBO's instance at the given attachment point.
+ * Attaches a {@link Colorbuffer}, i.e. {@link ColorAttachment} or {@link TextureAttachment},
+ * to this FBO's instance at the given attachment point.
*
+ * <p>
+ * If {@link Colorbuffer} is a {@link TextureAttachment} and is uninitialized, i.e. it's texture name is <code>zero</code>,
+ * a new texture name is generated and setup w/ the texture parameter.<br/>
+ * Otherwise, i.e. texture name is not <code>zero</code>, the passed TextureAttachment <code>texA</code> is
+ * considered complete and assumed matching this FBO requirement. A GL error may occur is the latter is untrue.
+ * </p>
+ *
* <p>Leaves the FBO bound.</p>
*
* @param gl
* @param attachmentPoint the color attachment point ranging from [0..{@link #getMaxColorAttachments()}-1]
- * @param colA the template for the new {@link ColorAttachment}
- * @return ColorAttachment instance describing the new attached colorbuffer if bound and configured successfully, otherwise GLException is thrown
- * @throws GLException in case the colorbuffer couldn't be allocated
+ * @param colbuf the to be attached {@link Colorbuffer}
+ * @return newly attached {@link Colorbuffer} instance if bound and configured successfully, otherwise GLException is thrown
+ * @throws GLException in case the colorbuffer couldn't be allocated or MSAA has been chosen in case of a {@link TextureAttachment}
*/
- public final ColorAttachment attachColorbuffer(GL gl, int attachmentPoint, ColorAttachment colA) throws GLException {
- validateAddColorAttachment(attachmentPoint, colA);
-
- colA.initialize(gl);
- addColorAttachment(attachmentPoint, colA);
-
+ public final Colorbuffer attachColorbuffer(GL gl, int attachmentPoint, Colorbuffer colbuf) throws GLException {
bind(gl);
-
- // Attach the color buffer
- gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER,
- GL.GL_COLOR_ATTACHMENT0 + attachmentPoint,
- GL.GL_RENDERBUFFER, colA.getName());
+ return attachColorbufferImpl(gl, attachmentPoint, colbuf);
+ }
- updateStatus(gl);
- if(!isStatusValid()) {
- detachColorbuffer(gl, attachmentPoint);
- throw new GLException("attachColorbuffer "+colA+" at "+attachmentPoint+" failed "+getStatusString()+", "+this);
+ private final Colorbuffer attachColorbufferImpl(GL gl, int attachmentPoint, Colorbuffer colbuf) throws GLException {
+ validateAddColorAttachment(attachmentPoint, colbuf);
+
+ final boolean initializedColorbuf = colbuf.initialize(gl);
+ addColorAttachment(attachmentPoint, colbuf);
+
+ if(colbuf instanceof TextureAttachment) {
+ final TextureAttachment texA = (TextureAttachment) colbuf;
+
+ if(samples>0) {
+ removeColorAttachment(attachmentPoint, texA);
+ if(initializedColorbuf) {
+ texA.free(gl);
+ }
+ throw new GLException("Texture2D not supported w/ MSAA. If you have enabled MSAA with exisiting texture attachments, you may want to detach them via detachAllTexturebuffer(gl).");
+ }
+
+ // Set up the color buffer for use as a renderable texture:
+ gl.glFramebufferTexture2D(GL.GL_FRAMEBUFFER,
+ GL.GL_COLOR_ATTACHMENT0 + attachmentPoint,
+ GL.GL_TEXTURE_2D, texA.getName(), 0);
+
+ if(!ignoreStatus) {
+ updateStatus(gl);
+ if(!isStatusValid()) {
+ detachColorbuffer(gl, attachmentPoint, true);
+ throw new GLException("attachTexture2D "+texA+" at "+attachmentPoint+" failed "+getStatusString()+", "+this);
+ }
+ }
+ } else if(colbuf instanceof ColorAttachment) {
+ final ColorAttachment colA = (ColorAttachment) colbuf;
+
+ // Attach the color buffer
+ gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER,
+ GL.GL_COLOR_ATTACHMENT0 + attachmentPoint,
+ GL.GL_RENDERBUFFER, colA.getName());
+
+ if(!ignoreStatus) {
+ updateStatus(gl);
+ if(!isStatusValid()) {
+ detachColorbuffer(gl, attachmentPoint, true);
+ throw new GLException("attachColorbuffer "+colA+" at "+attachmentPoint+" failed "+getStatusString()+", "+this);
+ }
+ }
}
if(DEBUG) {
- System.err.println("FBObject.attachColorbuffer: "+this);
+ System.err.println("FBObject.attachColorbuffer.X: [attachmentPoint "+attachmentPoint+", colbuf "+colbuf+"]: "+this);
}
- return colA;
+ return colbuf;
}
-
/**
* Attaches one depth, stencil or packed-depth-stencil buffer to this FBO's instance,
@@ -1270,18 +1429,20 @@ public class FBObject {
public final void attachRenderbuffer(GL gl, int internalFormat) throws GLException, IllegalArgumentException {
final Attachment.Type atype = Attachment.Type.determine(internalFormat);
if( Attachment.Type.DEPTH != atype && Attachment.Type.STENCIL != atype && Attachment.Type.DEPTH_STENCIL != atype ) {
- throw new IllegalArgumentException("renderformat invalid: 0x"+Integer.toHexString(internalFormat)+", "+this);
+ throw new IllegalArgumentException("renderformat invalid: "+toHexString(internalFormat)+", "+this);
}
attachRenderbufferImpl(gl, atype, internalFormat);
}
protected final void attachRenderbufferImpl(GL gl, Attachment.Type atype, int internalFormat) throws GLException {
if( null != depth && ( Attachment.Type.DEPTH == atype || Attachment.Type.DEPTH_STENCIL == atype ) ) {
- throw new GLException("FBO depth buffer already attached (rb "+depth+"), type is "+atype+", 0x"+Integer.toHexString(internalFormat)+", "+this);
+ throw new GLException("FBO depth buffer already attached (rb "+depth+"), type is "+atype+", "+toHexString(internalFormat)+", "+this);
}
if( null != stencil && ( Attachment.Type.STENCIL== atype || Attachment.Type.DEPTH_STENCIL == atype ) ) {
- throw new GLException("FBO stencil buffer already attached (rb "+stencil+"), type is "+atype+", 0x"+Integer.toHexString(internalFormat)+", "+this);
+ throw new GLException("FBO stencil buffer already attached (rb "+stencil+"), type is "+atype+", "+toHexString(internalFormat)+", "+this);
}
+ bind(gl);
+
attachRenderbufferImpl2(gl, atype, internalFormat);
}
@@ -1304,24 +1465,19 @@ public class FBObject {
stencil.initialize(gl);
} else if( Attachment.Type.DEPTH_STENCIL == atype ) {
if(null == depth) {
- depth = new RenderAttachment(Type.DEPTH, internalFormat, samples, width, height, 0);
+ if(null != stencil) {
+ throw new InternalError("XXX: DEPTH_STENCIL, depth was null, stencil not: "+this.toString());
+ }
+ depth = new RenderAttachment(Type.DEPTH_STENCIL, internalFormat, samples, width, height, 0);
} else {
depth.setSize(width, height);
depth.setSamples(samples);
}
depth.initialize(gl);
- if(null == stencil) {
- stencil = new RenderAttachment(Type.STENCIL, internalFormat, samples, width, height, depth.getName());
- } else {
- stencil.setName(depth.getName());
- stencil.setSize(width, height);
- stencil.setSamples(samples);
- }
- stencil.initialize(gl);
+ // DEPTH_STENCIL shares buffer w/ depth and stencil
+ stencil = depth;
}
- bind(gl);
-
// Attach the buffer
if( Attachment.Type.DEPTH == atype ) {
gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_DEPTH_ATTACHMENT, GL.GL_RENDERBUFFER, depth.getName());
@@ -1332,40 +1488,50 @@ public class FBObject {
gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_STENCIL_ATTACHMENT, GL.GL_RENDERBUFFER, stencil.getName());
}
- updateStatus(gl);
- if( !isStatusValid() ) {
- detachRenderbuffer(gl, atype);
- throw new GLException("renderbuffer attachment failed: "+this.getStatusString());
+ if(!ignoreStatus) {
+ updateStatus(gl);
+ if( !isStatusValid() ) {
+ detachRenderbuffer(gl, atype, true);
+ throw new GLException("renderbuffer [attachmentType "+atype+", iformat "+toHexString(internalFormat)+"] failed: "+this.getStatusString()+": "+this.toString());
+ }
}
if(DEBUG) {
- System.err.println("FBObject.attachRenderbuffer: "+this);
- }
+ System.err.println("FBObject.attachRenderbuffer.X: [attachmentType "+atype+", iformat "+toHexString(internalFormat)+"]: "+this);
+ }
}
/**
+ * Detaches a {@link Colorbuffer}, i.e. {@link ColorAttachment} or {@link TextureAttachment}.
* <p>Leaves the FBO bound!</p>
+ *
* @param gl
- * @param ca
+ * @param attachmentPoint
+ * @param dispose true if the Colorbuffer shall be disposed
+ * @return the detached Colorbuffer
* @throws IllegalArgumentException
*/
- public final void detachColorbuffer(GL gl, int attachmentPoint) throws IllegalArgumentException {
- if(null == detachColorbufferImpl(gl, attachmentPoint, false)) {
+ public final Colorbuffer detachColorbuffer(GL gl, int attachmentPoint, boolean dispose) throws IllegalArgumentException {
+ bind(gl);
+
+ final Colorbuffer res = detachColorbufferImpl(gl, attachmentPoint, dispose ? DetachAction.DISPOSE : DetachAction.NONE);
+ if(null == res) {
throw new IllegalArgumentException("ColorAttachment at "+attachmentPoint+", not attached, "+this);
}
if(DEBUG) {
- System.err.println("FBObject.detachAll: "+this);
+ System.err.println("FBObject.detachColorbuffer.X: [attachmentPoint "+attachmentPoint+", dispose "+dispose+"]: "+res+", "+this);
}
+ return res;
}
- private final Colorbuffer detachColorbufferImpl(GL gl, int attachmentPoint, boolean recreate) {
- final Colorbuffer colbuf = colorAttachmentPoints[attachmentPoint]; // shortcut, don't validate here
+ private final Colorbuffer detachColorbufferImpl(GL gl, int attachmentPoint, DetachAction detachAction) {
+ Colorbuffer colbuf = colorAttachmentPoints[attachmentPoint]; // shortcut, don't validate here
if(null == colbuf) {
return null;
}
- bind(gl);
+ removeColorAttachment(attachmentPoint, colbuf);
if(colbuf instanceof TextureAttachment) {
final TextureAttachment texA = (TextureAttachment) colbuf;
@@ -1374,12 +1540,23 @@ public class FBObject {
GL.GL_COLOR_ATTACHMENT0 + attachmentPoint,
GL.GL_TEXTURE_2D, 0, 0);
gl.glBindTexture(GL.GL_TEXTURE_2D, 0);
+ switch(detachAction) {
+ case DISPOSE:
+ case RECREATE:
+ texA.free(gl);
+ break;
+ default:
+ }
}
- texA.free(gl);
- removeColorAttachment(attachmentPoint, texA);
- if(recreate) {
- texA.setSize(width, height);
- attachTexture2D(gl, attachmentPoint, texA);
+ if(DetachAction.RECREATE == detachAction) {
+ if(samples == 0) {
+ // stay non MSAA
+ texA.setSize(width, height);
+ } else {
+ // switch to MSAA
+ colbuf = createColorAttachment(hasAlpha(texA.format));
+ }
+ attachColorbufferImpl(gl, attachmentPoint, colbuf);
}
} else if(colbuf instanceof ColorAttachment) {
final ColorAttachment colA = (ColorAttachment) colbuf;
@@ -1387,37 +1564,94 @@ public class FBObject {
gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER,
GL.GL_COLOR_ATTACHMENT0+attachmentPoint,
GL.GL_RENDERBUFFER, 0);
+ switch(detachAction) {
+ case DISPOSE:
+ case RECREATE:
+ colA.free(gl);
+ break;
+ default:
+ }
}
- colA.free(gl);
- removeColorAttachment(attachmentPoint, colbuf);
- if(recreate) {
- colA.setSize(width, height);
- colA.setSamples(samples);
- attachColorbuffer(gl, attachmentPoint, colA);
+ if(DetachAction.RECREATE == detachAction) {
+ if(samples > 0) {
+ // stay MSAA
+ colA.setSize(width, height);
+ colA.setSamples(samples);
+ } else {
+ // switch to non MSAA
+ if(null != samplesSinkTexture) {
+ colbuf = createColorTextureAttachment(samplesSinkTexture.format, width, height,
+ samplesSinkTexture.dataFormat, samplesSinkTexture.dataType,
+ samplesSinkTexture.magFilter, samplesSinkTexture.minFilter,
+ samplesSinkTexture.wrapS, samplesSinkTexture.wrapT);
+ } else {
+ colbuf = createColorTextureAttachment(gl.getGLProfile(), true, width, height);
+ }
+ }
+ attachColorbuffer(gl, attachmentPoint, colbuf);
}
}
return colbuf;
}
+ private final void freeAllColorbufferImpl(GL gl) {
+ for(int i=0; i<maxColorAttachments; i++) {
+ final Colorbuffer colbuf = colorAttachmentPoints[i]; // shortcut, don't validate here
+
+ if(null == colbuf) {
+ return;
+ }
+
+ if(colbuf instanceof TextureAttachment) {
+ final TextureAttachment texA = (TextureAttachment) colbuf;
+ if( 0 != texA.getName() ) {
+ gl.glFramebufferTexture2D(GL.GL_FRAMEBUFFER,
+ GL.GL_COLOR_ATTACHMENT0 + i,
+ GL.GL_TEXTURE_2D, 0, 0);
+ gl.glBindTexture(GL.GL_TEXTURE_2D, 0);
+ }
+ texA.free(gl);
+ } else if(colbuf instanceof ColorAttachment) {
+ final ColorAttachment colA = (ColorAttachment) colbuf;
+ if( 0 != colA.getName() ) {
+ gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER,
+ GL.GL_COLOR_ATTACHMENT0 + i,
+ GL.GL_RENDERBUFFER, 0);
+ }
+ colA.free(gl);
+ }
+ }
+ }
+
/**
*
* @param gl
+ * @param dispose true if the Colorbuffer shall be disposed
* @param reqAType {@link Type#DEPTH}, {@link Type#DEPTH} or {@link Type#DEPTH_STENCIL}
*/
- public final void detachRenderbuffer(GL gl, Attachment.Type atype) throws IllegalArgumentException {
- detachRenderbufferImpl(gl, atype, false);
+ public final void detachRenderbuffer(GL gl, Attachment.Type atype, boolean dispose) throws IllegalArgumentException {
+ bind(gl);
+ detachRenderbufferImpl(gl, atype, dispose ? DetachAction.DISPOSE : DetachAction.NONE);
+ if(DEBUG) {
+ System.err.println("FBObject.detachRenderbuffer.X: [attachmentType "+atype+", dispose "+dispose+"]: "+this);
+ }
}
public final boolean isDepthStencilPackedFormat() {
final boolean res = null != depth && null != stencil &&
depth.format == stencil.format ;
- if(res && depth.getName() != stencil.getName() ) {
- throw new InternalError("depth/stencil packed format not sharing: depth "+depth+", stencil "+stencil);
+ if(res) {
+ if(depth.getName() != stencil.getName() ) {
+ throw new InternalError("depth/stencil packed format not sharing: depth "+depth+", stencil "+stencil);
+ }
+ if(depth != stencil) {
+ throw new InternalError("depth/stencil packed format not a shared reference: depth "+depth+", stencil "+stencil);
+ }
}
return res;
}
- private final void detachRenderbufferImpl(GL gl, Attachment.Type atype, boolean recreate) throws IllegalArgumentException {
+ private final void detachRenderbufferImpl(GL gl, Attachment.Type atype, DetachAction detachAction) throws IllegalArgumentException {
switch ( atype ) {
case DEPTH:
case STENCIL:
@@ -1429,80 +1663,124 @@ public class FBObject {
if( null == depth && null == stencil ) {
return ; // nop
}
- // reduction of possible combinations, create unique atype command(s)
- final ArrayList<Attachment.Type> actions = new ArrayList<Attachment.Type>(2);
- if( isDepthStencilPackedFormat() ) {
- // packed
- actions.add(Attachment.Type.DEPTH_STENCIL);
- } else {
- // individual
- switch ( atype ) {
- case DEPTH:
- if( null != depth ) { actions.add(Attachment.Type.DEPTH); }
- break;
- case STENCIL:
- if( null != stencil ) { actions.add(Attachment.Type.STENCIL); }
- break;
- case DEPTH_STENCIL:
- if( null != depth ) { actions.add(Attachment.Type.DEPTH); }
- if( null != stencil ) { actions.add(Attachment.Type.STENCIL); }
- break;
- default: // handled
- }
+ final boolean packed = isDepthStencilPackedFormat();
+ if( packed ) {
+ // Note: DEPTH_STENCIL shares buffer w/ depth and stencil
+ atype = Attachment.Type.DEPTH_STENCIL;
}
-
- bind(gl);
-
- for(int i = 0; i < actions.size(); i++) {
- final int format;
-
- Attachment.Type action = actions.get(i);
- switch ( action ) {
- case DEPTH:
- format = depth.format;
+ switch ( atype ) {
+ case DEPTH:
+ if( null != depth ) {
+ final int format = depth.format;
if( 0 != depth.getName() ) {
gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_DEPTH_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
+ switch(detachAction) {
+ case DISPOSE:
+ case RECREATE:
+ depth.free(gl);
+ break;
+ default:
+ }
}
- depth.free(gl);
- if(!recreate) {
+ if(DetachAction.RECREATE == detachAction) {
+ attachRenderbufferImpl2(gl, atype, format);
+ } else {
depth = null;
}
- break;
- case STENCIL:
- format = stencil.format;
+ }
+ break;
+ case STENCIL:
+ if( null != stencil ) {
+ final int format = stencil.format;
if(0 != stencil.getName()) {
gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_STENCIL_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
+ switch(detachAction) {
+ case DISPOSE:
+ case RECREATE:
+ stencil.free(gl);
+ break;
+ default:
+ }
}
- stencil.free(gl);
- if(!recreate) {
+ if(DetachAction.RECREATE == detachAction) {
+ attachRenderbufferImpl2(gl, atype, format);
+ } else {
stencil = null;
}
- break;
- case DEPTH_STENCIL:
- format = depth.format;
+ }
+ break;
+ case DEPTH_STENCIL:
+ if( null != depth ) {
+ final int format = depth.format;
if(0 != depth.getName()) {
gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_DEPTH_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
- gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_STENCIL_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
+ if(packed) {
+ gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_STENCIL_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
+ }
+ switch(detachAction) {
+ case DISPOSE:
+ case RECREATE:
+ depth.free(gl);
+ break;
+ default:
+ }
}
- depth.free(gl);
- stencil.free(gl);
- if(!recreate) {
+ if(DetachAction.RECREATE == detachAction) {
+ attachRenderbufferImpl2(gl, packed ? Attachment.Type.DEPTH_STENCIL : Attachment.Type.DEPTH, format);
+ } else {
depth = null;
+ if(packed) {
+ stencil = null;
+ }
+ }
+ }
+ if( !packed && null != stencil ) {
+ final int format = stencil.format;
+ if(0 != stencil.getName()) {
+ gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_STENCIL_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
+ switch(detachAction) {
+ case DISPOSE:
+ case RECREATE:
+ stencil.free(gl);
+ break;
+ default:
+ }
+ }
+ if(DetachAction.RECREATE == detachAction) {
+ attachRenderbufferImpl2(gl, Attachment.Type.STENCIL, format);
+ } else {
stencil = null;
}
- break;
- default:
- throw new InternalError("XXX");
- }
- if(recreate) {
- attachRenderbufferImpl2(gl, action, format);
- }
+ }
+ break;
+ default: // handled
}
}
+ private final void freeAllRenderbufferImpl(GL gl) throws IllegalArgumentException {
+ // Note: DEPTH_STENCIL shares buffer w/ depth and stencil
+ final boolean packed = isDepthStencilPackedFormat();
+ if( null != depth ) {
+ if(0 != depth.getName()) {
+ gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_DEPTH_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
+ if(packed) {
+ gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_STENCIL_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
+ }
+ depth.free(gl);
+ }
+ }
+ if( !packed && null != stencil ) {
+ if(0 != stencil.getName()) {
+ gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_STENCIL_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
+ stencil.free(gl);
+ }
+ }
+ }
+
/**
- * Detaches all {@link ColorAttachment}s, {@link TextureAttachment}s and {@link RenderAttachment}s.
- * <p>Leaves the FBO bound!</p>
+ * Detaches all {@link ColorAttachment}s, {@link TextureAttachment}s and {@link RenderAttachment}s
+ * and disposes them.
+ * <p>Leaves the FBO bound, if initialized!</p>
* <p>
* An attached sampling sink texture will be detached as well, see {@link #getSamplingSink()}.
* </p>
@@ -1516,8 +1794,9 @@ public class FBObject {
}
/**
- * Detaches all {@link ColorAttachment}s and {@link TextureAttachment}s.
- * <p>Leaves the FBO bound!</p>
+ * Detaches all {@link ColorAttachment}s and {@link TextureAttachment}s
+ * and disposes them.
+ * <p>Leaves the FBO bound, if initialized!</p>
* <p>
* An attached sampling sink texture will be detached as well, see {@link #getSamplingSink()}.
* </p>
@@ -1531,45 +1810,80 @@ public class FBObject {
}
/**
- * Detaches all {@link TextureAttachment}s
- * <p>Leaves the FBO bound!</p>
+ * Detaches all {@link TextureAttachment}s and disposes them.
+ * <p>Leaves the FBO bound, if initialized!</p>
* <p>
* An attached sampling sink texture will be detached as well, see {@link #getSamplingSink()}.
* </p>
* @param gl the current GL context
*/
public final void detachAllTexturebuffer(GL gl) {
+ if( !isInitialized() ) {
+ return;
+ }
if(null != samplesSink) {
samplesSink.detachAllTexturebuffer(gl);
}
+ bind(gl);
for(int i=0; i<maxColorAttachments; i++) {
if(colorAttachmentPoints[i] instanceof TextureAttachment) {
- detachColorbufferImpl(gl, i, false);
+ detachColorbufferImpl(gl, i, DetachAction.DISPOSE);
}
}
+ if(DEBUG) {
+ System.err.println("FBObject.detachAllTexturebuffer.X: "+this);
+ }
}
public final void detachAllRenderbuffer(GL gl) {
+ if( !isInitialized() ) {
+ return;
+ }
if(null != samplesSink) {
samplesSink.detachAllRenderbuffer(gl);
}
- detachRenderbufferImpl(gl, Attachment.Type.DEPTH_STENCIL, false);
+ bind(gl);
+ detachRenderbufferImpl(gl, Attachment.Type.DEPTH_STENCIL, DetachAction.DISPOSE);
}
private final void detachAllImpl(GL gl, boolean detachNonColorbuffer, boolean recreate) {
- for(int i=0; i<maxColorAttachments; i++) {
- detachColorbufferImpl(gl, i, recreate);
- }
- if( !recreate && colorAttachmentCount>0 ) {
- throw new InternalError("Non zero ColorAttachments "+this);
+ if( !isInitialized() ) {
+ return;
}
-
- if(detachNonColorbuffer) {
- detachRenderbufferImpl(gl, Attachment.Type.DEPTH_STENCIL, recreate);
+ ignoreStatus = recreate; // ignore status on single calls only if recreate -> reset
+ try {
+ bind(gl);
+ if(FBOResizeQuirk) {
+ if(detachNonColorbuffer && recreate) {
+ // free all colorbuffer & renderbuffer 1st
+ freeAllColorbufferImpl(gl);
+ freeAllRenderbufferImpl(gl);
+ }
+ }
+ for(int i=0; i<maxColorAttachments; i++) {
+ detachColorbufferImpl(gl, i, recreate ? DetachAction.RECREATE : DetachAction.DISPOSE);
+ }
+ if( !recreate && colorAttachmentCount>0 ) {
+ throw new InternalError("Non zero ColorAttachments "+this);
+ }
+
+ if(detachNonColorbuffer) {
+ detachRenderbufferImpl(gl, Attachment.Type.DEPTH_STENCIL, recreate ? DetachAction.RECREATE : DetachAction.DISPOSE);
+ }
+ if(ignoreStatus) { // post validate
+ /* if(true) {
+ throw new GLException("Simulating bug 617, reset FBO failure");
+ } */
+ updateStatus(gl);
+ if(!isStatusValid()) {
+ throw new GLException("detachAllImpl failed "+getStatusString()+", "+this);
+ }
+ }
+ } finally {
+ ignoreStatus = false;
}
-
if(DEBUG) {
- System.err.println("FBObject.detachAll: [resetNonColorbuffer "+detachNonColorbuffer+", recreate "+recreate+"]: "+this);
+ System.err.println("FBObject.detachAll.X: [resetNonColorbuffer "+detachNonColorbuffer+", recreate "+recreate+"]: "+this);
}
}
@@ -1577,7 +1891,14 @@ public class FBObject {
* @param gl the current GL context
*/
public final void destroy(GL gl) {
- if(null != samplesSink) {
+ if(!initialized) {
+ return;
+ }
+ if(DEBUG) {
+ System.err.println("FBObject.destroy.0: "+this);
+ // Thread.dumpStack();
+ }
+ if( null != samplesSink && samplesSink.isInitialized() ) {
samplesSink.destroy(gl);
}
@@ -1596,7 +1917,7 @@ public class FBObject {
initialized = false;
bound = false;
if(DEBUG) {
- System.err.println("FBObject.destroy: "+this);
+ System.err.println("FBObject.destroy.X: "+this);
}
}
@@ -1618,21 +1939,42 @@ public class FBObject {
return depthMismatch || stencilMismatch;
}
- private final void resetMSAATexture2DSink(GL gl) throws GLException {
+ /**
+ * Manually reset the MSAA sampling sink, if used.
+ * <p>
+ * Automatically called by {@link #reset(GL, int, int, int, boolean)}
+ * and {@link #syncSamplingSink(GL)}.
+ * </p>
+ * <p>
+ * It is recommended to call this method after initializing the FBO and attaching renderbuffer etc for the 1st time
+ * if access to sampling sink resources is required.
+ * </p>
+ * @param gl the current GL context
+ * @throws GLException in case of an error, i.e. size too big, etc ..
+ */
+ public final void resetSamplingSink(GL gl) throws GLException {
+ if(null == samplesSink ) {
+ return; // this is the sample sink!
+ }
if(0 == samples) {
// MSAA off
- if(null != samplesSink) {
+ if(samplesSink.initialized) {
+ // cleanup
samplesSink.detachAll(gl);
}
return;
}
+ if(!samplesSink.initialized) {
+ samplesSink.init(gl, width, height, 0);
+ }
+
boolean sampleSinkSizeMismatch = sampleSinkSizeMismatch();
boolean sampleSinkTexMismatch = sampleSinkTexMismatch();
boolean sampleSinkDepthStencilMismatch = sampleSinkDepthStencilMismatch();
/** if(DEBUG) {
- System.err.println("FBObject.resetMSAATexture2DSink.0: \n\tTHIS "+this+",\n\tSINK "+samplesSink+
+ System.err.println("FBObject.resetSamplingSink.0: \n\tTHIS "+this+",\n\tSINK "+samplesSink+
"\n\t size "+sampleSinkSizeMismatch +", tex "+sampleSinkTexMismatch +", depthStencil "+sampleSinkDepthStencilMismatch);
} */
@@ -1644,7 +1986,7 @@ public class FBObject {
unbind(gl);
if(DEBUG) {
- System.err.println("FBObject.resetMSAATexture2DSink: BEGIN\n\tTHIS "+this+",\n\tSINK "+samplesSink+
+ System.err.println("FBObject.resetSamplingSink: BEGIN\n\tTHIS "+this+",\n\tSINK "+samplesSink+
"\n\t size "+sampleSinkSizeMismatch +", tex "+sampleSinkTexMismatch +", depthStencil "+sampleSinkDepthStencilMismatch);
}
@@ -1660,7 +2002,7 @@ public class FBObject {
samplesSinkTexture = samplesSink.attachTexture2D(gl, 0, true);
} else if( 0 == samplesSinkTexture.getName() ) {
samplesSinkTexture.setSize(width, height);
- samplesSink.attachTexture2D(gl, 0, samplesSinkTexture);
+ samplesSink.attachColorbuffer(gl, 0, samplesSinkTexture);
}
if( sampleSinkDepthStencilMismatch ) {
@@ -1679,7 +2021,7 @@ public class FBObject {
}
if(DEBUG) {
- System.err.println("FBObject.resetMSAATexture2DSink: END\n\tTHIS "+this+",\n\tSINK "+samplesSink+
+ System.err.println("FBObject.resetSamplingSink: END\n\tTHIS "+this+",\n\tSINK "+samplesSink+
"\n\t size "+sampleSinkSizeMismatch +", tex "+sampleSinkTexMismatch +", depthStencil "+sampleSinkDepthStencilMismatch);
}
}
@@ -1709,7 +2051,6 @@ public class FBObject {
gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, getWriteFramebuffer());
}
- checkNoError(null, gl.glGetError(), "FBObject post-bind"); // throws GLException if error
bound = true;
samplesSinkDirty = true;
}
@@ -1734,10 +2075,20 @@ public class FBObject {
} else {
gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, 0); // default draw buffer
}
- checkNoError(null, gl.glGetError(), "FBObject post-unbind"); // throws GLException if error
bound = false;
}
}
+
+ /**
+ * Method simply marks this FBO unbound w/o interfering w/ the bound framebuffer as perfomed by {@link #unbind(GL)}.
+ * <p>
+ * Only use this method if a subsequent {@link #unbind(GL)}, {@link #use(GL, TextureAttachment)} or {@link #bind(GL)}
+ * follows on <i>any</i> FBO.
+ * </p>
+ */
+ public final void markUnbound() {
+ bound = false;
+ }
/**
* Returns <code>true</code> if framebuffer object is bound via {@link #bind(GL)}, otherwise <code>false</code>.
@@ -1755,49 +2106,57 @@ public class FBObject {
public final boolean isBound() { return bound; }
/**
- * Samples the multisampling colorbuffer (msaa-buffer) to it's sink {@link #getSamplingSink()}.
- *
- * <p>The operation is skipped, if no multisampling is used or
- * the msaa-buffer has not been flagged dirty by a previous call of {@link #bind(GL)},
- * see {@link #isSamplingBufferDirty()} </p>
- *
- * <p>If full FBO is supported, sets the read and write framebuffer individually to default after sampling, hence not disturbing
- * an optional operating MSAA FBO, see {@link GLBase#getDefaultReadFramebuffer()} and {@link GLBase#getDefaultDrawFramebuffer()}</p>
- *
- * <p>In case you intend to employ {@link GL#glReadPixels(int, int, int, int, int, int, java.nio.Buffer) glReadPixels(..)}
+ * If multisampling is being used and flagged dirty by a previous call of {@link #bind(GL)} or after initialization,
+ * the msaa-buffers are sampled to it's sink {@link #getSamplingSink()}.
+ * <p>
+ * Method also resets the sampling sink configuration via {@link #resetSamplingSink(GL)} if used and required.
+ * </p>
+ * <p>
+ * Method is called automatically by {@link #use(GL, TextureAttachment)}.
+ * </p>
+ * <p>
+ * Method always resets the framebuffer binding to default in the end.
+ * If full FBO is supported, sets the read and write framebuffer individually to default after sampling, hence not disturbing
+ * an optional operating MSAA FBO, see {@link GLBase#getDefaultReadFramebuffer()} and {@link GLBase#getDefaultDrawFramebuffer()}
+ * </p>
+ * <p>
+ * In case you use this FBO w/o the {@link GLFBODrawable} and intend to employ {@link GL#glReadPixels(int, int, int, int, int, int, java.nio.Buffer) glReadPixels(..)}
* you may want to call {@link GL#glBindFramebuffer(int, int) glBindFramebuffer}({@link GL2GL3#GL_READ_FRAMEBUFFER}, {@link #getReadFramebuffer()});
* </p>
- *
* <p>Leaves the FBO unbound.</p>
*
* @param gl the current GL context
* @param ta {@link TextureAttachment} to use, prev. attached w/ {@link #attachTexture2D(GL, int, boolean, int, int, int, int) attachTexture2D(..)}
* @throws IllegalArgumentException
*/
- public final void syncSamplingBuffer(GL gl) {
- unbind(gl);
+ public final void syncSamplingSink(GL gl) {
+ markUnbound();
if(samples>0 && samplesSinkDirty) {
samplesSinkDirty = false;
- resetMSAATexture2DSink(gl);
+ resetSamplingSink(gl);
+ checkPreGLError(gl);
gl.glBindFramebuffer(GL2GL3.GL_READ_FRAMEBUFFER, fbName);
gl.glBindFramebuffer(GL2GL3.GL_DRAW_FRAMEBUFFER, samplesSink.getWriteFramebuffer());
- ((GL2GL3)gl).glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, // since MSAA is supported, ugly cast is OK
+ ((GL2GL3)gl).glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, // since MSAA is supported, casting to GL2GL3 is OK
GL.GL_COLOR_BUFFER_BIT, GL.GL_NEAREST);
- if(fullFBOSupport) {
- // default read/draw buffers, may utilize GLContext/GLDrawable override of
- // GLContext.getDefaultDrawFramebuffer() and GLContext.getDefaultReadFramebuffer()
- gl.glBindFramebuffer(GL2GL3.GL_DRAW_FRAMEBUFFER, 0);
- gl.glBindFramebuffer(GL2GL3.GL_READ_FRAMEBUFFER, 0);
- } else {
- gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, 0); // default draw buffer
- }
+ checkNoError(null, gl.glGetError(), "FBObject syncSampleSink"); // throws GLException if error
+ }
+ if(fullFBOSupport) {
+ // default read/draw buffers, may utilize GLContext/GLDrawable override of
+ // GLContext.getDefaultDrawFramebuffer() and GLContext.getDefaultReadFramebuffer()
+ gl.glBindFramebuffer(GL2GL3.GL_DRAW_FRAMEBUFFER, 0);
+ gl.glBindFramebuffer(GL2GL3.GL_READ_FRAMEBUFFER, 0);
+ } else {
+ gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, 0); // default draw buffer
}
}
/**
* Bind the given texture colorbuffer.
*
- * <p>If multisampling is being used, {@link #syncSamplingBuffer(GL)} is being called.</p>
+ * <p>If using multiple texture units, ensure you call {@link GL#glActiveTexture(int)} first!</p>
+ *
+ * <p>{@link #syncSamplingSink(GL)} is being called</p>
*
* <p>Leaves the FBO unbound!</p>
*
@@ -1806,12 +2165,8 @@ public class FBObject {
* @throws IllegalArgumentException
*/
public final void use(GL gl, TextureAttachment ta) throws IllegalArgumentException {
- if(null == ta) { throw new IllegalArgumentException("null TextureAttachment"); }
- if(samples > 0 && samplesSinkTexture == ta) {
- syncSamplingBuffer(gl);
- } else {
- unbind(gl);
- }
+ if(null == ta) { throw new IllegalArgumentException("Null TextureAttachment, this: "+toString()); }
+ syncSamplingSink(gl);
gl.glBindTexture(GL.GL_TEXTURE_2D, ta.getName()); // use it ..
}
@@ -1825,14 +2180,8 @@ public class FBObject {
gl.glBindTexture(GL.GL_TEXTURE_2D, 0); // don't use it
}
- /**
- * Returns <code>true</code> if <i>basic</i> or <i>full</i> FBO is supported, otherwise <code>false</code>.
- * @param full <code>true</code> for <i>full</i> FBO supported query, otherwise <code>false</code> for <i>basic</i> FBO support query.
- * @see #supportsFullFBO(GL)
- * @see #supportsBasicFBO(GL)
- * @throws GLException if {@link #init(GL)} hasn't been called.
- */
- public final boolean supportsFBO(boolean full) throws GLException { checkInitialized(); return full ? fullFBOSupport : basicFBOSupport; }
+ /** @see GL#hasFullFBOSupport() */
+ public final boolean hasFullFBOSupport() throws GLException { checkInitialized(); return this.fullFBOSupport; }
/**
* Returns <code>true</code> if renderbuffer accepts internal format {@link GL#GL_RGB8} and {@link GL#GL_RGBA8}, otherwise <code>false</code>.
@@ -1848,7 +2197,7 @@ public class FBObject {
public final boolean supportsDepth(int bits) throws GLException {
checkInitialized();
switch(bits) {
- case 16: return basicFBOSupport;
+ case 16: return true;
case 24: return depth24Avail;
case 32: return depth32Avail;
default: return false;
@@ -1883,15 +2232,15 @@ public class FBObject {
*/
public final int getMaxColorAttachments() throws GLException { checkInitialized(); return maxColorAttachments; }
- /**
- * Returns the maximum number of samples for multisampling. Maybe zero if multisampling is not supported.
- * @throws GLException if {@link #init(GL)} hasn't been called.
- */
- public final int getMaxSamples() throws GLException { checkInitialized(); return maxSamples; }
+ public final int getMaxTextureSize() throws GLException { checkInitialized(); return this.maxTextureSize; }
+ public final int getMaxRenderbufferSize() throws GLException { checkInitialized(); return this.maxRenderbufferSize; }
+
+ /** @see GL#getMaxRenderbufferSamples() */
+ public final int getMaxSamples() throws GLException { checkInitialized(); return this.maxSamples; }
/**
* Returns <code>true</code> if this instance has been initialized with {@link #reset(GL, int, int)}
- * or {@link #reset(GL, int, int, int)}, otherwise <code>false</code>
+ * or {@link #reset(GL, int, int, int, boolean)}, otherwise <code>false</code>
*/
public final boolean isInitialized() { return initialized; }
/** Returns the width */
@@ -1927,10 +2276,11 @@ public class FBObject {
public final String toString() {
final String caps = null != colorAttachmentPoints ? Arrays.asList(colorAttachmentPoints).toString() : null ;
- return "FBO[name r/w "+fbName+"/"+getReadFramebuffer()+", init "+initialized+", bound "+bound+", size "+width+"x"+height+", samples "+samples+"/"+maxSamples+
- ", depth "+depth+", stencil "+stencil+", color attachments: "+colorAttachmentCount+"/"+maxColorAttachments+
+ return "FBO[name r/w "+fbName+"/"+getReadFramebuffer()+", init "+initialized+", bound "+bound+", size "+width+"x"+height+
+ ", samples "+samples+"/"+maxSamples+", depth "+depth+", stencil "+stencil+
+ ", color attachments: "+colorAttachmentCount+"/"+maxColorAttachments+
": "+caps+", msaa-sink "+samplesSinkTexture+", isSamplesSink "+(null == samplesSink)+
- ", obj 0x"+Integer.toHexString(objectHashCode())+"]";
+ ", state "+getStatusString()+", obj "+toHexString(objectHashCode())+"]";
}
private final void updateStatus(GL gl) {
diff --git a/src/jogl/classes/com/jogamp/opengl/FloatUtil.java b/src/jogl/classes/com/jogamp/opengl/FloatUtil.java
index 93543ea..ffd2344 100644
--- a/src/jogl/classes/com/jogamp/opengl/FloatUtil.java
+++ b/src/jogl/classes/com/jogamp/opengl/FloatUtil.java
@@ -29,6 +29,8 @@ package com.jogamp.opengl;
import java.nio.FloatBuffer;
+import com.jogamp.common.os.Platform;
+
/**
* Basic Float math utility functions.
* <p>
@@ -71,7 +73,7 @@ public class FloatUtil {
* Make matrix an identity matrix
*/
public static final void makeIdentityf(FloatBuffer m) {
- int oldPos = m.position();
+ final int oldPos = m.position();
m.put(IDENTITY_MATRIX);
m.position(oldPos);
}
@@ -89,7 +91,7 @@ public class FloatUtil {
* Make matrix an zero matrix
*/
public static final void makeZero(FloatBuffer m) {
- int oldPos = m.position();
+ final int oldPos = m.position();
m.put(ZERO_MATRIX);
m.position(oldPos);
}
@@ -244,10 +246,10 @@ public class FloatUtil {
* @param v_in 4-component column-vector
* @param v_out m_in * v_in
*/
- public static final void multMatrixVecf(float[] m_in, int m_in_off, float[] v_in, int v_in_off, float[] v_out) {
+ public static final void multMatrixVecf(float[] m_in, int m_in_off, float[] v_in, int v_in_off, float[] v_out, int v_out_off) {
for (int i = 0; i < 4; i++) {
// (one matrix row in column-major order) X (column vector)
- v_out[i] =
+ v_out[i + v_out_off] =
v_in[0+v_in_off] * m_in[0*4+i+m_in_off] +
v_in[1+v_in_off] * m_in[1*4+i+m_in_off] +
v_in[2+v_in_off] * m_in[2*4+i+m_in_off] +
@@ -277,10 +279,44 @@ public class FloatUtil {
* @param v_in 4-component column-vector
* @param v_out m_in * v_in
*/
+ public static final void multMatrixVecf(FloatBuffer m_in, float[] v_in, int v_in_off, float[] v_out, int v_out_off) {
+ final int matrixPos = m_in.position();
+ for (int i = 0; i < 4; i++) {
+ // (one matrix row in column-major order) X (column vector)
+ v_out[i+v_out_off] =
+ v_in[0+v_in_off] * m_in.get(0*4+i+matrixPos) +
+ v_in[1+v_in_off] * m_in.get(1*4+i+matrixPos) +
+ v_in[2+v_in_off] * m_in.get(2*4+i+matrixPos) +
+ v_in[3+v_in_off] * m_in.get(3*4+i+matrixPos);
+ }
+ }
+
+ /**
+ * @param m_in 4x4 matrix in column-major order
+ * @param v_in 4-component column-vector
+ * @param v_out m_in * v_in
+ */
+ public static final void multMatrixVecf(FloatBuffer m_in, float[] v_in, float[] v_out) {
+ final int matrixPos = m_in.position();
+ for (int i = 0; i < 4; i++) {
+ // (one matrix row in column-major order) X (column vector)
+ v_out[i] =
+ v_in[0] * m_in.get(0*4+i+matrixPos) +
+ v_in[1] * m_in.get(1*4+i+matrixPos) +
+ v_in[2] * m_in.get(2*4+i+matrixPos) +
+ v_in[3] * m_in.get(3*4+i+matrixPos);
+ }
+ }
+
+ /**
+ * @param m_in 4x4 matrix in column-major order
+ * @param v_in 4-component column-vector
+ * @param v_out m_in * v_in
+ */
public static final void multMatrixVecf(FloatBuffer m_in, FloatBuffer v_in, FloatBuffer v_out) {
- int inPos = v_in.position();
- int outPos = v_out.position();
- int matrixPos = m_in.position();
+ final int inPos = v_in.position();
+ final int outPos = v_out.position();
+ final int matrixPos = m_in.position();
for (int i = 0; i < 4; i++) {
// (one matrix row in column-major order) X (column vector)
v_out.put(i + outPos,
@@ -291,4 +327,84 @@ public class FloatUtil {
}
}
+ /**
+ * @param sb optional passed StringBuilder instance to be used
+ * @param f the format string of one floating point, i.e. "%10.5f", see {@link java.util.Formatter}
+ * @param a mxn matrix (rows x columns)
+ * @param aOffset offset to <code>a</code>'s current position
+ * @param rows
+ * @param columns
+ * @param rowMajorOrder if true floats are layed out in row-major-order, otherwise column-major-order (OpenGL)
+ * @param row row number to print
+ * @return matrix row string representation
+ */
+ public static StringBuilder matrixRowToString(StringBuilder sb, String f, FloatBuffer a, int aOffset, int rows, int columns, boolean rowMajorOrder, int row) {
+ if(null == sb) {
+ sb = new StringBuilder();
+ }
+ final int a0 = aOffset + a.position();
+ if(rowMajorOrder) {
+ for(int c=0; c<columns; c++) {
+ sb.append( String.format( f+" ", a.get( a0 + row*columns + c ) ) );
+ }
+ } else {
+ for(int r=0; r<columns; r++) {
+ sb.append( String.format( f+" ", a.get( a0 + row + r*rows ) ) );
+ }
+ }
+ return sb;
+ }
+
+ /**
+ * @param sb optional passed StringBuilder instance to be used
+ * @param rowPrefix optional prefix for each row
+ * @param f the format string of one floating point, i.e. "%10.5f", see {@link java.util.Formatter}
+ * @param a mxn matrix (rows x columns)
+ * @param aOffset offset to <code>a</code>'s current position
+ * @param rows
+ * @param columns
+ * @param rowMajorOrder if true floats are layed out in row-major-order, otherwise column-major-order (OpenGL)
+ * @return matrix string representation
+ */
+ public static StringBuilder matrixToString(StringBuilder sb, String rowPrefix, String f, FloatBuffer a, int aOffset, int rows, int columns, boolean rowMajorOrder) {
+ if(null == sb) {
+ sb = new StringBuilder();
+ }
+ final String prefix = ( null == rowPrefix ) ? "" : rowPrefix;
+ for(int i=0; i<rows; i++) {
+ sb.append(prefix).append("[ ");
+ matrixRowToString(sb, f, a, aOffset, rows, columns, rowMajorOrder, i);
+ sb.append("]").append(Platform.getNewline());
+ }
+ return sb;
+ }
+
+ /**
+ * @param sb optional passed StringBuilder instance to be used
+ * @param rowPrefix optional prefix for each row
+ * @param f the format string of one floating point, i.e. "%10.5f", see {@link java.util.Formatter}
+ * @param a 4x4 matrix in column major order (OpenGL)
+ * @param aOffset offset to <code>a</code>'s current position
+ * @param b 4x4 matrix in column major order (OpenGL)
+ * @param bOffset offset to <code>a</code>'s current position
+ * @param rows
+ * @param columns
+ * @param rowMajorOrder if true floats are layed out in row-major-order, otherwise column-major-order (OpenGL)
+ * @return side by side representation
+ */
+ public static StringBuilder matrixToString(StringBuilder sb, String rowPrefix, String f, FloatBuffer a, int aOffset, FloatBuffer b, int bOffset, int rows, int columns, boolean rowMajorOrder) {
+ if(null == sb) {
+ sb = new StringBuilder();
+ }
+ final String prefix = ( null == rowPrefix ) ? "" : rowPrefix;
+ for(int i=0; i<rows; i++) {
+ sb.append(prefix).append("[ ");
+ matrixRowToString(sb, f, a, aOffset, rows, columns, rowMajorOrder, i);
+ sb.append("=?= ");
+ matrixRowToString(sb, f, b, bOffset, rows, columns, rowMajorOrder, i);
+ sb.append("]").append(Platform.getNewline());
+ }
+ return sb;
+ }
+
}
\ No newline at end of file
diff --git a/src/jogl/classes/javax/media/opengl/GLAutoDrawableDelegate.java b/src/jogl/classes/com/jogamp/opengl/GLAutoDrawableDelegate.java
similarity index 63%
rename from src/jogl/classes/javax/media/opengl/GLAutoDrawableDelegate.java
rename to src/jogl/classes/com/jogamp/opengl/GLAutoDrawableDelegate.java
index 67e8127..38a8dee 100644
--- a/src/jogl/classes/javax/media/opengl/GLAutoDrawableDelegate.java
+++ b/src/jogl/classes/com/jogamp/opengl/GLAutoDrawableDelegate.java
@@ -26,14 +26,21 @@
* or implied, of JogAmp Community.
*/
-package javax.media.opengl;
+package com.jogamp.opengl;
import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.WindowClosingProtocol;
+import javax.media.nativewindow.WindowClosingProtocol.WindowClosingMode;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLException;
import com.jogamp.common.util.locks.LockFactory;
import com.jogamp.common.util.locks.RecursiveLock;
-import jogamp.opengl.Debug;
import jogamp.opengl.GLAutoDrawableBase;
import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLDrawableImpl;
@@ -46,44 +53,64 @@ import jogamp.opengl.GLDrawableImpl;
* Since no native windowing system events are being processed, it is recommended
* to handle at least:
* <ul>
- * <li>{@link com.jogamp.newt.event.WindowListener#windowRepaint(com.jogamp.newt.event.WindowUpdateEvent) repaint} using {@link #defaultWindowRepaintOp()}</li>
- * <li>{@link com.jogamp.newt.event.WindowListener#windowResized(com.jogamp.newt.event.WindowEvent) resize} using {@link #defaultWindowResizedOp()}</li>
- * <li>{@link com.jogamp.newt.event.WindowListener#windowDestroyNotify(com.jogamp.newt.event.WindowEvent) destroy-notify} using {@link #defaultWindowDestroyNotifyOp()}</li>
+ * <li>{@link com.jogamp.newt.event.WindowListener#windowRepaint(com.jogamp.newt.event.WindowUpdateEvent) repaint} using {@link #windowRepaintOp()}</li>
+ * <li>{@link com.jogamp.newt.event.WindowListener#windowResized(com.jogamp.newt.event.WindowEvent) resize} using {@link #windowResizedOp()}</li>
+ * <li>{@link com.jogamp.newt.event.WindowListener#windowDestroyNotify(com.jogamp.newt.event.WindowEvent) destroy-notify} using {@link #windowDestroyNotifyOp()}</li>
* </ul>
* </p>
* <p>
* See example {@link com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableDelegateNEWT TestGLAutoDrawableDelegateNEWT}.
* </p>
*/
-public class GLAutoDrawableDelegate extends GLAutoDrawableBase {
- public static final boolean DEBUG = Debug.debug("GLAutoDrawableDelegate");
-
+public class GLAutoDrawableDelegate extends GLAutoDrawableBase implements GLAutoDrawable {
/**
- * @param drawable a valid {@link GLDrawable}, may not be realized yet.
+ * @param drawable a valid and already realized {@link GLDrawable}
* @param context a valid {@link GLContext}, may not be made current (created) yet.
* @param upstreamWidget optional UI element holding this instance, see {@link #getUpstreamWidget()}.
* @param ownDevice pass <code>true</code> if {@link AbstractGraphicsDevice#close()} shall be issued,
* otherwise pass <code>false</code>. Closing the device is required in case
* the drawable is created w/ it's own new instance, e.g. offscreen drawables,
* and no further lifecycle handling is applied.
+ * @param lock optional custom {@link RecursiveLock}.
*/
- public GLAutoDrawableDelegate(GLDrawable drawable, GLContext context, Object upstreamWidget, boolean ownDevice) {
+ public GLAutoDrawableDelegate(GLDrawable drawable, GLContext context, Object upstreamWidget, boolean ownDevice, RecursiveLock lock) {
super((GLDrawableImpl)drawable, (GLContextImpl)context, ownDevice);
- this.upstreamWidget = null;
+ if(null == drawable) {
+ throw new IllegalArgumentException("null drawable");
+ }
+ if(null == context) {
+ throw new IllegalArgumentException("null context");
+ }
+ if(!drawable.isRealized()) {
+ throw new IllegalArgumentException("drawable not realized");
+ }
+ this.upstreamWidget = upstreamWidget;
+ this.lock = ( null != lock ) ? lock : LockFactory.createRecursiveLock() ;
}
//
// expose default methods
//
-
+
+ /** Default implementation to handle repaint events from the windowing system */
public final void windowRepaintOp() {
super.defaultWindowRepaintOp();
}
- public final void windowResizedOp() {
- super.defaultWindowResizedOp();
+ /** Implementation to handle resize events from the windowing system. All required locks are being claimed. */
+ public final void windowResizedOp(int newWidth, int newHeight) {
+ super.defaultWindowResizedOp(newWidth, newHeight);
}
+ /**
+ * Implementation to handle destroy notifications from the windowing system.
+ *
+ * <p>
+ * If the {@link NativeSurface} does not implement {@link WindowClosingProtocol}
+ * or {@link WindowClosingMode#DISPOSE_ON_CLOSE} is enabled (default),
+ * a thread safe destruction is being induced.
+ * </p>
+ */
public final void windowDestroyNotifyOp() {
super.defaultWindowDestroyNotifyOp();
}
@@ -92,8 +119,8 @@ public class GLAutoDrawableDelegate extends GLAutoDrawableBase {
// Complete GLAutoDrawable
//
- private final RecursiveLock lock = LockFactory.createRecursiveLock(); // instance wide lock
- private final Object upstreamWidget;
+ private Object upstreamWidget;
+ private final RecursiveLock lock;
@Override
protected final RecursiveLock getLock() { return lock; }
@@ -104,6 +131,14 @@ public class GLAutoDrawableDelegate extends GLAutoDrawableBase {
}
/**
+ * Set the upstream UI toolkit object.
+ * @see #getUpstreamWidget()
+ */
+ public final void setUpstreamWidget(Object newUpstreamWidget) {
+ upstreamWidget = newUpstreamWidget;
+ }
+
+ /**
* {@inheritDoc}
* <p>
* This implementation calls {@link #defaultDestroy()}.
@@ -119,7 +154,12 @@ public class GLAutoDrawableDelegate extends GLAutoDrawableBase {
}
@Override
- public void display() {
+ protected void destroyImplInLock() {
+ super.destroyImplInLock();
+ }
+
+ @Override
+ public void display() {
defaultDisplay();
}
@@ -140,5 +180,10 @@ public class GLAutoDrawableDelegate extends GLAutoDrawableBase {
public final void swapBuffers() throws GLException {
defaultSwapBuffers();
}
-
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName()+"[ \n\tHelper: " + helper + ", \n\tDrawable: " + drawable +
+ ", \n\tContext: " + context + ", \n\tUpstreamWidget: "+upstreamWidget+ /** ", \n\tFactory: "+factory+ */ "]";
+ }
}
diff --git a/src/jogl/classes/com/jogamp/opengl/GLExtensions.java b/src/jogl/classes/com/jogamp/opengl/GLExtensions.java
index f7e25fa..cf81b85 100644
--- a/src/jogl/classes/com/jogamp/opengl/GLExtensions.java
+++ b/src/jogl/classes/com/jogamp/opengl/GLExtensions.java
@@ -72,6 +72,9 @@ public class GLExtensions {
public static final String OES_EGL_image_external = "GL_OES_EGL_image_external";
+ public static final String ARB_gpu_shader_fp64 = "GL_ARB_gpu_shader_fp64";
+ public static final String ARB_shader_objects = "GL_ARB_shader_objects";
+
//
// Aliased GLX/WGL/.. extensions
//
diff --git a/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java b/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java
new file mode 100644
index 0000000..2f453a4
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java
@@ -0,0 +1,144 @@
+/**
+ * Copyright 2012 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community OR
+ * CONTRIBUTORS 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.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+package com.jogamp.opengl;
+
+/**
+ * GLRendererQuirks contains information of known bugs of various GL renderer.
+ * This information allows us to workaround them.
+ * <p>
+ * Using centralized quirk identifier enables us to
+ * locate code dealing w/ it and hence eases it's maintenance.
+ * </p>
+ */
+public class GLRendererQuirks {
+ /**
+ * Crashes XServer when using double buffered PBuffer with:
+ * <ul>
+ * <li>Mesa DRI Intel(R) Sandybridge Desktop</li>
+ * <li>Mesa DRI Intel(R) Ivybridge Mobile - 3.0 Mesa 8.0.4</li>
+ * <li>Gallium 0.4 on AMD CYPRESS</li>
+ * </ul>
+ * For now, it is safe to disable it w/ hw-acceleration.
+ */
+ public static final int NoDoubleBufferedPBuffer = 0;
+
+ /** On Windows no double buffered bitmaps are guaranteed to be available. */
+ public static final int NoDoubleBufferedBitmap = 1;
+
+ /** Crashes application when trying to set EGL swap interval on Android 4.0.3 / Pandaboard ES / PowerVR SGX 540 */
+ public static final int NoSetSwapInterval = 2;
+
+ /** No offscreen bitmap available, currently true for JOGL's OSX implementation. */
+ public static final int NoOffscreenBitmap = 3;
+
+ /** SIGSEGV on setSwapInterval() after changing the context's drawable w/ 'Mesa 8.0.4' dri2SetSwapInterval/DRI2 (soft & intel) */
+ public static final int NoSetSwapIntervalPostRetarget = 4;
+
+ /** GLSL <code>discard</code> command leads to undefined behavior or won't get compiled if being used. Appears to happen on Nvidia Tegra2. FIXME: Constrain version. */
+ public static final int GLSLBuggyDiscard = 5;
+
+ /** Number of quirks known. */
+ public static final int COUNT = 6;
+
+ private static final String[] _names = new String[] { "NoDoubleBufferedPBuffer", "NoDoubleBufferedBitmap", "NoSetSwapInterval",
+ "NoOffscreenBitmap", "NoSetSwapIntervalPostRetarget", "GLSLBuggyDiscard"
+ };
+
+ private final int _bitmask;
+
+ /**
+ * @param quirks an array of valid quirks
+ * @param offset offset in quirks array to start reading
+ * @param len number of quirks to read from offset within quirks array
+ * @throws IllegalArgumentException if one of the quirks is out of range
+ */
+ public GLRendererQuirks(int[] quirks, int offset, int len) throws IllegalArgumentException {
+ int bitmask = 0;
+ if( !( 0 <= offset + len && offset + len < quirks.length ) ) {
+ throw new IllegalArgumentException("offset and len out of bounds: offset "+offset+", len "+len+", array-len "+quirks.length);
+ }
+ for(int i=offset; i<offset+len; i++) {
+ final int quirk = quirks[i];
+ validateQuirk(quirk);
+ bitmask |= 1 << quirk;
+ }
+ _bitmask = bitmask;
+ }
+
+ /**
+ * @param quirk the quirk to be tested
+ * @return true if quirk exist, otherwise false
+ * @throws IllegalArgumentException if quirk is out of range
+ */
+ public final boolean exist(int quirk) throws IllegalArgumentException {
+ validateQuirk(quirk);
+ return 0 != ( ( 1 << quirk ) & _bitmask );
+ }
+
+ public final StringBuilder toString(StringBuilder sb) {
+ if(null == sb) {
+ sb = new StringBuilder();
+ }
+ sb.append("[");
+ boolean first=true;
+ for(int i=0; i<COUNT; i++) {
+ final int testmask = 1 << i;
+ if( 0 != ( _bitmask & testmask ) ) {
+ if(!first) { sb.append(", "); }
+ sb.append(toString(i));
+ first=false;
+ }
+ }
+ sb.append("]");
+ return sb;
+ }
+
+ public final String toString() {
+ return toString(null).toString();
+ }
+
+ /**
+ * @param quirk the quirk to be validated, i.e. whether it is out of range
+ * @throws IllegalArgumentException if quirk is out of range
+ */
+ public static void validateQuirk(int quirk) throws IllegalArgumentException {
+ if( !( 0 <= quirk && quirk < COUNT ) ) {
+ throw new IllegalArgumentException("Quirks must be in range [0.."+COUNT+"[, but quirk: "+quirk);
+ }
+ }
+
+ /**
+ * @param quirk the quirk to be converted to String
+ * @return the String equivalent of this quirk
+ * @throws IllegalArgumentException if quirk is out of range
+ */
+ public static final String toString(int quirk) throws IllegalArgumentException {
+ validateQuirk(quirk);
+ return _names[quirk];
+ }
+}
diff --git a/src/newt/classes/com/jogamp/newt/event/WindowUpdateEvent.java b/src/jogl/classes/com/jogamp/opengl/GenericGLCapabilitiesChooser.java
similarity index 67%
copy from src/newt/classes/com/jogamp/newt/event/WindowUpdateEvent.java
copy to src/jogl/classes/com/jogamp/opengl/GenericGLCapabilitiesChooser.java
index 505939d..73ec108 100644
--- a/src/newt/classes/com/jogamp/newt/event/WindowUpdateEvent.java
+++ b/src/jogl/classes/com/jogamp/opengl/GenericGLCapabilitiesChooser.java
@@ -1,5 +1,5 @@
/**
- * Copyright 2010 JogAmp Community. All rights reserved.
+ * Copyright 2012 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
@@ -25,25 +25,24 @@
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of JogAmp Community.
*/
-
-package com.jogamp.newt.event;
-import javax.media.nativewindow.util.Rectangle;
+package com.jogamp.opengl;
-public class WindowUpdateEvent extends WindowEvent {
- final Rectangle bounds;
+import java.util.List;
+import javax.media.nativewindow.CapabilitiesImmutable;
+import javax.media.opengl.DefaultGLCapabilitiesChooser;
- public WindowUpdateEvent(int eventType, Object source, long when, Rectangle bounds)
- {
- super(eventType, source, when);
- this.bounds = bounds;
- }
-
- public Rectangle getBounds() {
- return bounds;
- }
+/**
+ * Ignores windowSystemRecommendedChoice parameter,
+ * otherwise uses {@link DefaultGLCapabilitiesChooser} implementation.
+ */
+public class GenericGLCapabilitiesChooser extends DefaultGLCapabilitiesChooser {
+
+ @Override
+ public int chooseCapabilities(final CapabilitiesImmutable desired,
+ final List<? extends CapabilitiesImmutable> available,
+ final int windowSystemRecommendedChoice) {
+ return super.chooseCapabilities(desired, available, -1);
+ }
- public String toString() {
- return "WindowUpdateEvent["+super.toString()+", "+bounds+"]";
- }
}
diff --git a/src/jogl/classes/com/jogamp/opengl/JoglVersion.java b/src/jogl/classes/com/jogamp/opengl/JoglVersion.java
index cdb4b82..52721e3 100644
--- a/src/jogl/classes/com/jogamp/opengl/JoglVersion.java
+++ b/src/jogl/classes/com/jogamp/opengl/JoglVersion.java
@@ -169,6 +169,23 @@ public class JoglVersion extends JogampVersion {
return sb;
}
+ public StringBuilder getBriefOSGLBuildInfo(GL gl, StringBuilder sb) {
+ if(null==sb) {
+ sb = new StringBuilder();
+ }
+ sb.append("OS: ").append(Platform.getOSName()).append(", version ").append(Platform.getOSVersion()).append(", arch ").append(Platform.getArchName());
+ sb.append(Platform.getNewline());
+ sb.append("GL_VENDOR ").append(gl.glGetString(GL.GL_VENDOR));
+ sb.append(Platform.getNewline());
+ sb.append("GL_RENDERER ").append(gl.glGetString(GL.GL_RENDERER));
+ sb.append(Platform.getNewline());
+ sb.append("GL_VERSION ").append(gl.glGetString(GL.GL_VERSION));
+ sb.append(Platform.getNewline());
+ sb.append("JOGL GIT sha1 ").append(getImplementationCommit());
+ sb.append(Platform.getNewline());
+ return sb;
+ }
+
public static void main(String args[]) {
System.err.println(VersionUtil.getPlatformInfo());
System.err.println(GlueGenVersion.getInstance());
diff --git a/src/jogl/classes/com/jogamp/opengl/OffscreenAutoDrawable.java b/src/jogl/classes/com/jogamp/opengl/OffscreenAutoDrawable.java
deleted file mode 100644
index 8450ffd..0000000
--- a/src/jogl/classes/com/jogamp/opengl/OffscreenAutoDrawable.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/**
- * Copyright 2012 JogAmp Community. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are
- * permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- *
- * 2. 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.
- *
- * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community OR
- * CONTRIBUTORS 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.
- *
- * The views and conclusions contained in the software and documentation are those of the
- * authors and should not be interpreted as representing official policies, either expressed
- * or implied, of JogAmp Community.
- */
-
-package com.jogamp.opengl;
-
-import javax.media.nativewindow.AbstractGraphicsDevice;
-import javax.media.opengl.GLAutoDrawableDelegate;
-import javax.media.opengl.GLContext;
-import javax.media.opengl.GLDrawable;
-import javax.media.opengl.GLException;
-
-import jogamp.opengl.GLFBODrawableImpl;
-
-/**
- * Platform-independent class exposing FBO offscreen functionality to
- * applications.
- * <p>
- * This class distinguishes itself from {@link GLAutoDrawableDelegate}
- * with it's {@link #setSize(int, int)} functionality.
- * </p>
- */
-public class OffscreenAutoDrawable extends GLAutoDrawableDelegate {
-
- /**
- * @param drawable a valid {@link GLDrawable}, may not be realized yet.
- * @param context a valid {@link GLContext}, may not be made current (created) yet.
- * @param ownDevice pass <code>true</code> if {@link AbstractGraphicsDevice#close()} shall be issued,
- * otherwise pass <code>false</code>. Closing the device is required in case
- * the drawable is created w/ it's own new instance, e.g. offscreen drawables,
- * and no further lifecycle handling is applied.
- */
- public OffscreenAutoDrawable(GLDrawable drawable, GLContext context, boolean ownDevice) {
- super(drawable, context, null, ownDevice);
- }
-
- /**
- * Attempts to resize this offscreen auto drawable, if supported
- * by the underlying {@link GLDrawable).
- * @param newWidth
- * @param newHeight
- * @return <code>true</code> if resize was executed, otherwise <code>false</code>.
- * @throws GLException in case of an error during the resize operation
- */
- public boolean setSize(int newWidth, int newHeight) throws GLException {
- boolean done = false;
- if(drawable instanceof GLFBODrawableImpl) {
- context.makeCurrent();
- try {
- ((GLFBODrawableImpl)drawable).setSize(context.getGL(), newWidth, newHeight);
- done = true;
- } finally {
- context.release();
- }
- }
- if(done) {
- this.defaultWindowResizedOp();
- return true;
- }
- return false;
- }
-
- /**
- * If the underlying {@link GLDrawable} is an FBO implementation
- * and contains an {#link FBObject}, the same is returned.
- * Otherwise returns <code>null</code>.
- */
- public FBObject getFBObject() {
- if(drawable instanceof GLFBODrawableImpl) {
- return ((GLFBODrawableImpl)drawable).getFBObject();
- }
- return null;
- }
-}
diff --git a/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java b/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
index 8d23716..3332262 100644
--- a/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
+++ b/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
@@ -30,6 +30,7 @@ package com.jogamp.opengl.swt;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
import javax.media.opengl.GL;
import javax.media.opengl.GLAnimatorControl;
import javax.media.opengl.GLAutoDrawable;
@@ -48,6 +49,7 @@ import javax.media.opengl.Threading;
import jogamp.opengl.Debug;
import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLDrawableHelper;
+import jogamp.opengl.GLDrawableImpl;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ControlAdapter;
@@ -97,8 +99,8 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
private final GLCapabilitiesImmutable capsRequested;
private final GLCapabilitiesChooser capsChooser;
- private volatile GLDrawable drawable; // volatile: avoid locking for read-only access
- private GLContext context;
+ private volatile GLDrawableImpl drawable; // volatile: avoid locking for read-only access
+ private GLContextImpl context;
/* Native window surface */
private AbstractGraphicsDevice device;
@@ -116,7 +118,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
private final Runnable initAction = new Runnable() {
@Override
public void run() {
- helper.init(GLCanvas.this);
+ helper.init(GLCanvas.this, !sendReshape);
}
};
@@ -151,24 +153,18 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
};
/* Swaps buffers, assuming the GLContext is current */
- private final Runnable swapBuffersAction = new Runnable() {
+ private final Runnable swapBuffersOnEDTAction = new Runnable() {
@Override
public void run() {
- drawable.swapBuffers();
- }
- };
-
- /* Swaps buffers, making the GLContext current first */
- private final Runnable makeCurrentAndSwapBuffersOnEDTAction = new Runnable() {
- @Override
- public void run() {
- final RecursiveLock _lock = lock;
- _lock.lock();
- try {
- helper.invokeGL(drawable, context, swapBuffersAction, initAction);
- } finally {
- _lock.unlock();
- }
+ final RecursiveLock _lock = lock;
+ _lock.lock();
+ try {
+ if(null != drawable) {
+ drawable.swapBuffers();
+ }
+ } finally {
+ _lock.unlock();
+ }
}
};
@@ -286,7 +282,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
clientArea = GLCanvas.this.getClientArea();
/* Get the nativewindow-Graphics Device associated with this control (which is determined by the parent Composite).
- * Note: SWT is owner of the native handle, hence no closing operation will be a NOP. */
+ * Note: SWT is owner of the native handle, hence closing operation will be a NOP. */
device = SWTAccessor.getDevice(this);
/* Select default GLCapabilities if none was provided, otherwise clone provided caps to ensure safety */
@@ -319,7 +315,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
}
});
}
- private final ProxySurface.UpstreamSurfaceHook swtCanvasUpStreamHook = new ProxySurface.UpstreamSurfaceHook() {
+ private final UpstreamSurfaceHook swtCanvasUpStreamHook = new UpstreamSurfaceHook() {
@Override
public final void create(ProxySurface s) { /* nop */ }
@@ -349,7 +345,27 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
( nClientArea.width != oClientArea.width || nClientArea.height != oClientArea.height )
) {
clientArea = nClientArea; // write back new value
- sendReshape = true; // Mark for OpenGL reshape next time the control is painted
+
+ GLDrawableImpl _drawable = drawable;
+ if( null != _drawable ) {
+ if(DEBUG) {
+ System.err.println("GLCanvas.sizeChanged: ("+Thread.currentThread().getName()+"): "+nClientArea.width+"x"+nClientArea.height+" - surfaceHandle 0x"+Long.toHexString(getNativeSurface().getSurfaceHandle()));
+ }
+ if( ! _drawable.getChosenGLCapabilities().isOnscreen() ) {
+ final RecursiveLock _lock = lock;
+ _lock.lock();
+ try {
+ final GLDrawableImpl _drawableNew = GLDrawableHelper.resizeOffscreenDrawable(_drawable, context, nClientArea.width, nClientArea.height);
+ if(_drawable != _drawableNew) {
+ // write back
+ drawable = _drawableNew;
+ }
+ } finally {
+ _lock.unlock();
+ }
+ sendReshape = true; // async if display() doesn't get called below, but avoiding deadlock
+ }
+ }
}
}
@@ -367,7 +383,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
return false;
}
final Rectangle nClientArea = clientArea;
- if(0 == nClientArea.width * nClientArea.height) {
+ if(0 >= nClientArea.width || 0 >= nClientArea.height) {
return false;
}
@@ -391,10 +407,10 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
if(null != proxySurface) {
/* Associate a GL surface with the proxy */
- drawable = glFactory.createGLDrawable(proxySurface);
+ drawable = (GLDrawableImpl) glFactory.createGLDrawable(proxySurface);
drawable.setRealized(true);
- context = drawable.createContext(shareWith);
+ context = (GLContextImpl) drawable.createContext(shareWith);
}
} finally {
_lock.unlock();
@@ -456,6 +472,11 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
}
@Override
+ public final GLDrawable getDelegatedDrawable() {
+ return drawable;
+ }
+
+ @Override
public GLContext getContext() {
return null != drawable ? context : null;
}
@@ -502,7 +523,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
_lock.lock();
try {
final GLContext oldCtx = context;
- final boolean newCtxCurrent = helper.switchContext(drawable, oldCtx, newCtx, additionalCtxCreationFlags);
+ final boolean newCtxCurrent = GLDrawableHelper.switchContext(drawable, oldCtx, newCtx, additionalCtxCreationFlags);
context=(GLContextImpl)newCtx;
if(newCtxCurrent) {
context.makeCurrent();
@@ -600,7 +621,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
@Override
public void swapBuffers() throws GLException {
- runInGLThread(makeCurrentAndSwapBuffersOnEDTAction);
+ runInGLThread(swapBuffersOnEDTAction);
}
@Override
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataClient.java b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataClient.java
index 134dd96..88cb330 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataClient.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataClient.java
@@ -124,33 +124,41 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
// Data read access
//
+ @Override
public final boolean isVBOWritten() { return bufferWritten; }
+ @Override
public final boolean sealed() { return sealed; }
+ @Override
public final boolean enabled() { return bufferEnabled; }
//
// Data and GL state modification ..
//
+ @Override
public final void setVBOWritten(boolean written) { bufferWritten=written; }
+ @Override
public void destroy(GL gl) {
reset(gl);
super.destroy(gl);
}
+ @Override
public void reset(GL gl) {
enableBuffer(gl, false);
reset();
}
+ @Override
public void seal(GL gl, boolean seal) {
seal(seal);
enableBuffer(gl, seal);
}
+ @Override
public void enableBuffer(GL gl, boolean enable) {
if( enableBufferAlways || bufferEnabled != enable ) {
if(enable) {
@@ -167,17 +175,22 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
} else {
ext = null;
}
- if(enable) {
- glArrayHandler.syncData(gl, true, ext);
- glArrayHandler.enableState(gl, true, ext);
- } else {
- glArrayHandler.enableState(gl, false, ext);
- glArrayHandler.syncData(gl, false, ext);
- }
+ glArrayHandler.enableState(gl, enable, ext);
bufferEnabled = enable;
}
}
-
+
+ @Override
+ public boolean bindBuffer(GL gl, boolean bind) {
+ if(bind) {
+ checkSeal(true);
+ // init/generate VBO name if not done yet
+ init_vbo(gl);
+ }
+ return glArrayHandler.bindBuffer(gl, bind);
+ }
+
+ @Override
public void setEnableAlways(boolean always) {
enableBufferAlways = always;
}
@@ -186,6 +199,7 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
// Data modification ..
//
+ @Override
public void reset() {
if(buffer!=null) {
buffer.clear();
@@ -195,6 +209,7 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
this.bufferWritten=false;
}
+ @Override
public void seal(boolean seal)
{
if(sealed==seal) return;
@@ -211,12 +226,14 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
}
+ @Override
public void rewind() {
if(buffer!=null) {
buffer.rewind();
}
}
+ @Override
public void padding(int doneInByteSize) {
if ( buffer==null || sealed ) return;
while(doneInByteSize<strideB) {
@@ -231,6 +248,7 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
* This class buffer Class must match the arguments buffer class.
* The arguments remaining elements must be a multiple of this arrays element stride.
*/
+ @Override
public void put(Buffer v) {
if ( sealed ) return;
/** FIXME: isn't true for interleaved arrays !
@@ -241,28 +259,33 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
Buffers.put(buffer, v);
}
+ @Override
public void putb(byte v) {
if ( sealed ) return;
growBufferIfNecessary(1);
Buffers.putb(buffer, v);
}
+ @Override
public void puts(short v) {
if ( sealed ) return;
growBufferIfNecessary(1);
Buffers.puts(buffer, v);
}
+ @Override
public void puti(int v) {
if ( sealed ) return;
growBufferIfNecessary(1);
Buffers.puti(buffer, v);
}
+ @Override
public void putx(int v) {
puti(v);
}
+ @Override
public void putf(float v) {
if ( sealed ) return;
growBufferIfNecessary(1);
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataEditable.java b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataEditable.java
index bb22a4b..9b04a48 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataEditable.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataEditable.java
@@ -14,7 +14,7 @@ import java.nio.*;
public interface GLArrayDataEditable extends GLArrayData {
public boolean sealed();
-
+
public boolean enabled();
/**
@@ -45,9 +45,14 @@ public interface GLArrayDataEditable extends GLArrayData {
public void seal(GL gl, boolean seal);
/**
- * <p>Enables/disables the buffer,
- * sets the client state, binds the VBO if used
- * and transfers the data if necessary.</p>
+ * Enables the buffer if <code>enable</code> is <code>true</code>,
+ * and transfers the data if required.
+ * In case {@link #isVBO() VBO is used}, it is bound accordingly for the data transfer and association,
+ * i.e. it issued {@link #bindBuffer(GL, boolean)}.
+ * The VBO buffer is unbound when the method returns.
+ * <p>
+ * Disables the buffer if <code>enable</code> is <code>false</code>.
+ * </p>
*
* <p>The action will only be executed,
* if the internal enable state differs,
@@ -63,6 +68,26 @@ public interface GLArrayDataEditable extends GLArrayData {
public void enableBuffer(GL gl, boolean enable);
/**
+ * if <code>bind</code> is true and the data uses {@link #isVBO() VBO},
+ * the latter will be bound and data written to the GPU if required.
+ * <p>
+ * If <code>bind</code> is false and the data uses {@link #isVBO() VBO},
+ * the latter will be unbound.
+ * </p>
+ * <p>
+ * This method is exposed to allow data VBO arrays, i.e. {@link GL#GL_ELEMENT_ARRAY_BUFFER},
+ * to be bounded and written while keeping the VBO bound. The latter is in contrast to {@link #enableBuffer(GL, boolean)},
+ * which leaves the VBO unbound, since it's not required for vertex attributes or pointers.
+ * </p>
+ *
+ * @param gl current GL object
+ * @param bind true if VBO shall be bound and data written,
+ * otherwise clear VBO binding.
+ * @return true if data uses VBO and action was performed, otherwise false
+ */
+ public boolean bindBuffer(GL gl, boolean bind);
+
+ /**
* Affects the behavior of 'enableBuffer'.
*
* The default is 'false'
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataWrapper.java b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataWrapper.java
index bade0a3..f4a197b 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataWrapper.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataWrapper.java
@@ -253,16 +253,10 @@ public class GLArrayDataWrapper implements GLArrayData {
this.componentType = componentType;
componentClazz = getBufferClass(componentType);
- switch(componentType) {
- case GL.GL_BYTE:
- case GL.GL_UNSIGNED_BYTE:
- case GL.GL_SHORT:
- case GL.GL_UNSIGNED_SHORT:
- case GL.GL_FIXED:
- this.normalized = normalized;
- break;
- default:
- this.normalized = false;
+ if( GLBuffers.isGLTypeFixedPoint(componentType) ) {
+ this.normalized = normalized;
+ } else {
+ this.normalized = false;
}
componentByteSize = GLBuffers.sizeOfGLType(componentType);
if(0 > componentByteSize) {
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLBuffers.java b/src/jogl/classes/com/jogamp/opengl/util/GLBuffers.java
index 331d6fa..174935d 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/GLBuffers.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLBuffers.java
@@ -38,7 +38,8 @@
*/
package com.jogamp.opengl.util;
-import com.jogamp.common.nio.Buffers;
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
import javax.media.opengl.GL;
import javax.media.opengl.GL2;
@@ -47,7 +48,7 @@ import javax.media.opengl.GL2GL3;
import javax.media.opengl.GLES2;
import javax.media.opengl.GLException;
-import java.nio.*;
+import com.jogamp.common.nio.Buffers;
/**
* Utility routines for dealing with direct buffers.
@@ -57,6 +58,47 @@ import java.nio.*;
public class GLBuffers extends Buffers {
/**
+ * @param glType GL primitive type
+ * @return false if one of GL primitive unsigned types, otherwise true
+ * GL_UNSIGNED_BYTE, <br/>
+ * GL_UNSIGNED_SHORT, <br/>
+ * GL_UNSIGNED_INT, <br/>
+ * GL_HILO16_NV <br/>
+ */
+ public static final boolean isSignedGLType(int glType) {
+ switch (glType) { // 29
+ case GL.GL_UNSIGNED_BYTE:
+ case GL.GL_UNSIGNED_SHORT:
+ case GL.GL_UNSIGNED_INT:
+ case GL2.GL_HILO16_NV:
+ return false;
+
+ }
+ return true;
+ }
+
+ /**
+ * @param glType GL primitive type
+ * @return false if one of GL primitive floating point types, otherwise true
+ * GL_FLOAT, <br/>
+ * GL_HALF_FLOAT, <br/>
+ * GL_HALF_FLOAT_OES, <br/>
+ * GL_DOUBLE <br/>
+ */
+ public static final boolean isGLTypeFixedPoint(int glType) {
+ switch(glType) {
+ case GL.GL_FLOAT:
+ case GL.GL_HALF_FLOAT:
+ case GLES2.GL_HALF_FLOAT_OES:
+ case GL2GL3.GL_DOUBLE:
+ return false;
+
+ default:
+ return true;
+ }
+ }
+
+ /**
* @param glType shall be one of (29) <br/>
* GL_BYTE, GL_UNSIGNED_BYTE, <br/>
* GL_UNSIGNED_BYTE_3_3_2, GL_UNSIGNED_BYTE_2_3_3_REV, <br/>
@@ -224,15 +266,20 @@ public class GLBuffers extends Buffers {
if (parent == null || byteLen == 0) {
return null;
}
+ final int parentPos = parent.position();
+ final int parentLimit = parent.limit();
+
parent.position(bytePos);
parent.limit(bytePos + byteLen);
-
+ Buffer res = null;
+
switch (glType) { // 29
case GL.GL_BYTE:
case GL.GL_UNSIGNED_BYTE:
case GL2GL3.GL_UNSIGNED_BYTE_3_3_2:
case GL2GL3.GL_UNSIGNED_BYTE_2_3_3_REV:
- return parent.slice();
+ res = parent.slice().order(parent.order()); // slice and duplicate may change byte order
+ break;
case GL.GL_SHORT:
case GL.GL_UNSIGNED_SHORT:
@@ -244,7 +291,8 @@ public class GLBuffers extends Buffers {
case GL2GL3.GL_UNSIGNED_SHORT_1_5_5_5_REV:
case GL.GL_HALF_FLOAT:
case GLES2.GL_HALF_FLOAT_OES:
- return parent.asShortBuffer();
+ res = parent.slice().order(parent.order()).asShortBuffer(); // slice and duplicate may change byte order
+ break;
case GL.GL_FIXED:
case GL2GL3.GL_INT:
@@ -258,18 +306,23 @@ public class GLBuffers extends Buffers {
case GL2GL3.GL_UNSIGNED_INT_5_9_9_9_REV:
case GL2.GL_HILO16_NV:
case GL2.GL_SIGNED_HILO16_NV:
- return parent.asIntBuffer();
+ res = parent.slice().order(parent.order()).asIntBuffer(); // slice and duplicate may change byte order
+ break;
case GL2GL3.GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
- return parent.asLongBuffer();
+ res = parent.slice().order(parent.order()).asLongBuffer(); // slice and duplicate may change byte order
+ break;
case GL.GL_FLOAT:
- return parent.asFloatBuffer();
+ res = parent.slice().order(parent.order()).asFloatBuffer(); // slice and duplicate may change byte order
+ break;
case GL2.GL_DOUBLE:
- return parent.asDoubleBuffer();
+ res = parent.slice().order(parent.order()).asDoubleBuffer(); // slice and duplicate may change byte order
+ break;
}
- return null;
+ parent.position(parentPos).limit(parentLimit);
+ return res;
}
private static final int glGetInteger(GL gl, int pname, int[] tmp) {
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLReadBufferUtil.java b/src/jogl/classes/com/jogamp/opengl/util/GLReadBufferUtil.java
index b0fae8a..b8709f3 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/GLReadBufferUtil.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLReadBufferUtil.java
@@ -116,6 +116,10 @@ public class GLReadBufferUtil {
* @see #GLReadBufferUtil(boolean, boolean)
*/
public boolean readPixels(GL gl, boolean flip) {
+ final int glerr0 = gl.glGetError();
+ if(GL.GL_NO_ERROR != glerr0) {
+ System.err.println("Info: GLReadBufferUtil.readPixels: pre-exisiting GL error 0x"+Integer.toHexString(glerr0));
+ }
final GLDrawable drawable = gl.getContext().getGLReadDrawable();
final int textureInternalFormat, textureDataFormat, textureDataType;
final int[] glImplColorReadVals = new int[] { 0, 0 };
@@ -175,7 +179,9 @@ public class GLReadBufferUtil {
if(res) {
psm.setAlignment(gl, alignment, alignment);
readPixelBuffer.clear();
- gl.glReadPixels(0, 0, drawable.getWidth(), drawable.getHeight(), textureDataFormat, textureDataType, readPixelBuffer);
+ try {
+ gl.glReadPixels(0, 0, drawable.getWidth(), drawable.getHeight(), textureDataFormat, textureDataType, readPixelBuffer);
+ } catch(GLException gle) { res = false; gle.printStackTrace(); }
readPixelBuffer.position(readPixelSize);
readPixelBuffer.flip();
final int glerr1 = gl.glGetError();
diff --git a/src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java b/src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java
index cf03730..f01896b 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java
@@ -3,6 +3,7 @@ package com.jogamp.opengl.util;
import java.nio.Buffer;
import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
import java.nio.ShortBuffer;
import java.util.ArrayList;
import java.util.Iterator;
@@ -13,52 +14,112 @@ import javax.media.opengl.GL2ES2;
import javax.media.opengl.GLException;
import javax.media.opengl.fixedfunc.GLPointerFunc;
-import com.jogamp.common.util.ReflectionUtil;
+import jogamp.opengl.Debug;
+
+import com.jogamp.common.nio.Buffers;
+import com.jogamp.common.os.Platform;
import com.jogamp.opengl.util.glsl.ShaderState;
+/**
+ * <p>
+ * Immediate mode sink, implementing OpenGL fixed function subset of immediate mode operations, i.e.
+ * <pre>
+ * glBegin();
+ * glVertex3f(1f, 1f, 1f);
+ * glColor4f(1f, 1f, 1f, 1f);
+ * ...
+ * glEnd();
+ * </pre>
+ * Implementation buffers all vertex, colors, normal and texture-coord elements in their respective buffers
+ * to be either rendered directly via {@link #glEnd(GL)} or to be added to an internal display list
+ * via {@link #glEnd(GL, boolean) glEnd(gl, false)} for deferred rendering via {@link #draw(GL, boolean)}.
+ * </p>
+ * <a name="storageDetails"><h5>Buffer storage and it's creation via {@link #createFixed(int, int, int, int, int, int, int, int, int, int) createFixed(..)}
+ * and {@link #createGLSL(int, int, int, int, int, int, int, int, int, int) createGLSL(..)}</h5></a>
+ * <p>
+ * If unsure whether <i>colors</i>, <i>normals</i> and <i>textures</i> will be used,
+ * simply add them with an expected component count.
+ * This implementation will only render buffers which are being filled.<br/>
+ * The buffer growing implementation will only grow the exceeded buffers, unused buffers are not resized.
+ * </p>
+ * <p>
+ * Note: Optional types, i.e. color, must be either not used or used w/ the same element count as vertex, etc.
+ * This is a semantic constraint, same as in the original OpenGL spec.
+ * </p>
+ */
public class ImmModeSink {
+ protected static final boolean DEBUG_BEGIN_END = Debug.isPropertyDefined("jogl.debug.ImmModeSink.BeginEnd", true);
+ protected static final boolean DEBUG_DRAW = Debug.isPropertyDefined("jogl.debug.ImmModeSink.Draw", true);
+ protected static final boolean DEBUG_BUFFER = Debug.isPropertyDefined("jogl.debug.ImmModeSink.Buffer", true);
- public static final boolean DEBUG_BEGIN_END = false;
- public static final boolean DEBUG_DRAW = false;
-
- // public static final int GL_QUADS = 0x0007; // Needs data manipulation
+ public static final int GL_QUADS = 0x0007; // Needs data manipulation on ES1/ES2
public static final int GL_QUAD_STRIP = 0x0008;
public static final int GL_POLYGON = 0x0009;
/**
* Uses a GL2ES1, or ES2 fixed function emulation immediate mode sink
+ * <p>
+ * See <a href="#storageDetails"> buffer storage details</a>.
+ * </p>
+ *
+ * @param initialElementCount initial buffer size, if subsequent mutable operations are about to exceed the buffer size, the buffer will grow about the initial size.
+ * @param vComps mandatory vertex component count, should be 2, 3 or 4.
+ * @param vDataType mandatory vertex data type, e.g. {@link GL#GL_FLOAT}
+ * @param cComps optional color component count, may be 0, 3 or 4
+ * @param cDataType optional color data type, e.g. {@link GL#GL_FLOAT}
+ * @param nComps optional normal component count, may be 0, 3 or 4
+ * @param nDataType optional normal data type, e.g. {@link GL#GL_FLOAT}
+ * @param tComps optional texture-coordinate component count, may be 0, 2 or 3
+ * @param tDataType optional texture-coordinate data type, e.g. {@link GL#GL_FLOAT}
+ * @param glBufferUsage VBO <code>usage</code> parameter for {@link GL#glBufferData(int, long, Buffer, int)}, e.g. {@link GL#GL_STATIC_DRAW},
+ * set to <code>0</code> for no VBO usage
*/
- public static ImmModeSink createFixed(GL gl, int glBufferUsage, int initialElementCount,
+ public static ImmModeSink createFixed(int initialElementCount,
int vComps, int vDataType,
- int cComps, int cDataType,
+ int cComps, int cDataType,
int nComps, int nDataType,
- int tComps, int tDataType) {
- return new ImmModeSink(gl, glBufferUsage, initialElementCount,
- vComps, vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType, false);
+ int tComps, int tDataType,
+ int glBufferUsage) {
+ return new ImmModeSink(initialElementCount,
+ vComps, vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType,
+ false, glBufferUsage);
}
/**
* Uses a GL2ES2 GLSL shader immediate mode sink.
* To issue the draw() command,
* a ShaderState must be current, using ShaderState.glUseProgram().
- *
+ * <p>
+ * See <a href="#storageDetails"> buffer storage details</a>.
+ * </p>
+ *
+ * @param initialElementCount initial buffer size, if subsequent mutable operations are about to exceed the buffer size, the buffer will grow about the initial size.
+ * @param vComps mandatory vertex component count, should be 2, 3 or 4.
+ * @param vDataType mandatory vertex data type, e.g. {@link GL#GL_FLOAT}
+ * @param cComps optional color component count, may be 0, 3 or 4
+ * @param cDataType optional color data type, e.g. {@link GL#GL_FLOAT}
+ * @param nComps optional normal component count, may be 0, 3 or 4
+ * @param nDataType optional normal data type, e.g. {@link GL#GL_FLOAT}
+ * @param tComps optional texture-coordinate component count, may be 0, 2 or 3
+ * @param tDataType optional texture-coordinate data type, e.g. {@link GL#GL_FLOAT}
+ * @param glBufferUsage VBO <code>usage</code> parameter for {@link GL#glBufferData(int, long, Buffer, int)}, e.g. {@link GL#GL_STATIC_DRAW},
+ * set to <code>0</code> for no VBO usage
+ *
* @see #draw(GL, boolean)
* @see com.jogamp.opengl.util.glsl.ShaderState#useProgram(GL2ES2, boolean)
* @see com.jogamp.opengl.util.glsl.ShaderState#getCurrentShaderState()
*/
- public static ImmModeSink createGLSL(GL gl, int glBufferUsage, int initialElementCount,
+ public static ImmModeSink createGLSL(int initialElementCount,
int vComps, int vDataType,
- int cComps, int cDataType,
+ int cComps, int cDataType,
int nComps, int nDataType,
- int tComps, int tDataType) {
- return new ImmModeSink(gl, glBufferUsage, initialElementCount,
- vComps, vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType, true);
+ int tComps, int tDataType,
+ int glBufferUsage) {
+ return new ImmModeSink(initialElementCount,
+ vComps, vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType,
+ true, glBufferUsage);
}
- public static boolean usesVBO() { return vboUsage; }
-
- public static void setVBOUsage(boolean v) { vboUsage = v; }
-
public void destroy(GL gl) {
destroyList(gl);
@@ -93,45 +154,38 @@ public class ImmModeSink {
public void draw(GL gl, boolean disableBufferAfterDraw) {
if(DEBUG_DRAW) {
- Exception e = new Exception("Info: ImmModeSink.draw(disableBufferAfterDraw: "+disableBufferAfterDraw+"):\n\t"+this);
- e.printStackTrace();
+ System.err.println("ImmModeSink.draw(disableBufferAfterDraw: "+disableBufferAfterDraw+"):\n\t"+this);
}
int n=0;
- for(Iterator<VBOSet> i=vboSetList.iterator(); i.hasNext() ; n++) {
- i.next().draw(gl, null, disableBufferAfterDraw, n);
+ for(int i=0; i<vboSetList.size(); i++, n++) {
+ vboSetList.get(i).draw(gl, null, disableBufferAfterDraw, n);
}
}
public void draw(GL gl, Buffer indices, boolean disableBufferAfterDraw) {
if(DEBUG_DRAW) {
- Exception e = new Exception("Info: ImmModeSink.draw(disableBufferAfterDraw: "+disableBufferAfterDraw+"):\n\t"+this);
- e.printStackTrace();
+ System.err.println("ImmModeSink.draw(disableBufferAfterDraw: "+disableBufferAfterDraw+"):\n\t"+this);
}
int n=0;
- for(Iterator<VBOSet> i=vboSetList.iterator(); i.hasNext() ; n++) {
- i.next().draw(gl, indices, disableBufferAfterDraw, n);
+ for(int i=0; i<vboSetList.size(); i++, n++) {
+ vboSetList.get(i).draw(gl, indices, disableBufferAfterDraw, n);
}
}
public void glBegin(int mode) {
- if(DEBUG_BEGIN_END) {
- Exception e = new Exception("Info: ImmModeSink.glBegin("+vboSet.mode+"):\n\t"+this);
- e.printStackTrace();
- }
vboSet.modeOrig = mode;
switch(mode) {
- // Needs data manipulation ..
- //case GL_QUADS:
- // mode=GL.GL_LINES;
- // break;
case GL_QUAD_STRIP:
mode=GL.GL_TRIANGLE_STRIP;
break;
case GL_POLYGON:
- mode=GL.GL_LINES;
+ mode=GL.GL_TRIANGLE_FAN;
break;
}
vboSet.mode = mode;
+ if(DEBUG_BEGIN_END) {
+ System.err.println("ImmModeSink.glBegin("+vboSet.modeOrig+" -> "+vboSet.mode+")");
+ }
vboSet.checkSeal(false);
}
@@ -149,8 +203,7 @@ public class ImmModeSink {
private void glEnd(GL gl, Buffer indices, boolean immediateDraw) {
if(DEBUG_BEGIN_END) {
- Exception e = new Exception("Info: ImmModeSink START glEnd(immediate: "+immediateDraw+"):\n\t"+this);
- e.printStackTrace();
+ System.err.println("ImmModeSink START glEnd(immediate: "+immediateDraw+")");
}
if(immediateDraw) {
vboSet.seal(gl, true);
@@ -160,7 +213,10 @@ public class ImmModeSink {
vboSet.seal(gl, true);
vboSet.enableBuffer(gl, false);
vboSetList.add(vboSet);
- vboSet = vboSet.regenerate();
+ vboSet = vboSet.regenerate(gl);
+ }
+ if(DEBUG_BEGIN_END) {
+ System.err.println("ImmModeSink END glEnd(immediate: "+immediateDraw+")");
}
}
@@ -249,10 +305,18 @@ public class ImmModeSink {
vboSet.glColor3b(x,y,z);
}
+ public final void glColor3ub(byte x, byte y, byte z) {
+ vboSet.glColor3ub(x,y,z);
+ }
+
public final void glColor4b(byte x, byte y, byte z, byte a) {
vboSet.glColor4b(x,y,z,a);
}
+ public final void glColor4ub(byte x, byte y, byte z, byte a) {
+ vboSet.glColor4ub(x,y,z,a);
+ }
+
public final void glTexCoord2b(byte x, byte y) {
vboSet.glTexCoord2b(x,y);
}
@@ -261,50 +325,86 @@ public class ImmModeSink {
vboSet.glTexCoord3b(x,y,z);
}
- protected ImmModeSink(GL gl, int glBufferUsage, int initialElementCount,
- int vComps, int vDataType,
+ protected ImmModeSink(int initialElementCount,
+ int vComps, int vDataType,
int cComps, int cDataType,
int nComps, int nDataType,
- int tComps, int tDataType, boolean useGLSL) {
- if(useGLSL && !gl.hasGLSL()) {
- throw new GLException("ImmModeSink GLSL usage not supported: "+gl);
- }
- vboSet = new VBOSet(gl, glBufferUsage, initialElementCount,
- vComps, vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType, useGLSL);
+ int tComps, int tDataType,
+ boolean useGLSL, int glBufferUsage) {
+ vboSet = new VBOSet(initialElementCount,
+ vComps, vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType,
+ useGLSL, glBufferUsage);
this.vboSetList = new ArrayList<VBOSet>();
}
-
+
+ public boolean getUseVBO() { return vboSet.getUseVBO(); }
+
+ /**
+ * Returns the additional element count if buffer resize is required.
+ * @see #setResizeElementCount(int)
+ */
+ public int getResizeElementCount() { return vboSet.getResizeElementCount(); }
+
+ /**
+ * Sets the additional element count if buffer resize is required,
+ * defaults to <code>initialElementCount</code> of factory method.
+ * @see #createFixed(int, int, int, int, int, int, int, int, int, int)
+ * @see #createGLSL(int, int, int, int, int, int, int, int, int, int)
+ */
+ public void setResizeElementCount(int v) { vboSet.setResizeElementCount(v); }
+
private void destroyList(GL gl) {
- for(Iterator<VBOSet> i=vboSetList.iterator(); i.hasNext() ; ) {
- i.next().destroy(gl);
+ for(int i=0; i<vboSetList.size(); i++) {
+ vboSetList.get(i).destroy(gl);
}
vboSetList.clear();
}
private VBOSet vboSet;
- private ArrayList<VBOSet> vboSetList;
- private static boolean vboUsage = true;
+ private final ArrayList<VBOSet> vboSetList;
protected static class VBOSet {
- protected VBOSet (GL gl, int glBufferUsage, int initialElementCount,
- int vComps, int vDataType,
+ protected VBOSet (int initialElementCount,
+ int vComps, int vDataType,
int cComps, int cDataType,
int nComps, int nDataType,
- int tComps, int tDataType, boolean useGLSL) {
- this.gl=gl;
+ int tComps, int tDataType,
+ boolean useGLSL, int glBufferUsage) {
this.glBufferUsage=glBufferUsage;
this.initialElementCount=initialElementCount;
+ this.resizeElementCount=initialElementCount;
this.vDataType=vDataType;
+ this.vDataTypeSigned=GLBuffers.isSignedGLType(vDataType);
this.vComps=vComps;
+ this.vCompsBytes=vComps * GLBuffers.sizeOfGLType(vDataType);
this.cDataType=cDataType;
+ this.cDataTypeSigned=GLBuffers.isSignedGLType(cDataType);
this.cComps=cComps;
+ this.cCompsBytes=cComps * GLBuffers.sizeOfGLType(cDataType);
this.nDataType=nDataType;
+ this.nDataTypeSigned=GLBuffers.isSignedGLType(nDataType);
this.nComps=nComps;
+ this.nCompsBytes=nComps * GLBuffers.sizeOfGLType(nDataType);
this.tDataType=tDataType;
+ this.tDataTypeSigned=GLBuffers.isSignedGLType(tDataType);
this.tComps=tComps;
+ this.tCompsBytes=tComps * GLBuffers.sizeOfGLType(tDataType);
this.useGLSL=useGLSL;
-
- allocateBuffer(initialElementCount);
+ this.useVBO = 0 != glBufferUsage;
+ this.vboName = 0;
+
+ this.vCount=0;
+ this.cCount=0;
+ this.nCount=0;
+ this.tCount=0;
+ this.vElems=0;
+ this.cElems=0;
+ this.nElems=0;
+ this.tElems=0;
+
+ this.pageSize = Platform.getMachineDescription().pageSizeInBytes();
+
+ reallocateBuffer(initialElementCount);
rewind();
this.sealed=false;
@@ -313,11 +413,17 @@ public class ImmModeSink {
this.modeOrig = 0;
this.bufferEnabled=false;
this.bufferWritten=false;
+ this.bufferWrittenOnce=false;
}
- protected final VBOSet regenerate() {
- return new VBOSet(gl, glBufferUsage, initialElementCount,
- vComps, vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType, useGLSL);
+ protected int getResizeElementCount() { return resizeElementCount; }
+ protected void setResizeElementCount(int v) { resizeElementCount=v; }
+
+ protected boolean getUseVBO() { return useVBO; }
+
+ protected final VBOSet regenerate(GL gl) {
+ return new VBOSet(initialElementCount, vComps,
+ vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType, useGLSL, glBufferUsage);
}
protected void checkSeal(boolean test) throws GLException {
@@ -335,280 +441,336 @@ public class ImmModeSink {
protected void draw(GL gl, Buffer indices, boolean disableBufferAfterDraw, int i)
{
- if(DEBUG_DRAW) {
- Exception e = new Exception("Info: ImmModeSink.draw["+i+"](disableBufferAfterDraw: "+disableBufferAfterDraw+"):\n\t"+this);
- e.printStackTrace();
- }
enableBuffer(gl, true);
+ if(DEBUG_DRAW) {
+ System.err.println("ImmModeSink.draw["+i+"].0 (disableBufferAfterDraw: "+disableBufferAfterDraw+"):\n\t"+this);
+ }
+
if (buffer!=null) {
if(null==indices) {
- gl.glDrawArrays(mode, 0, count);
+ if ( GL_QUADS == mode && !gl.isGL2() ) {
+ for (int j = 0; j < vElems - 3; j += 4) {
+ gl.glDrawArrays(GL.GL_TRIANGLE_FAN, j, 4);
+ }
+ } else {
+ gl.glDrawArrays(mode, 0, vElems);
+ }
} else {
- Class<?> clazz = indices.getClass();
- int type=-1;
- if(ReflectionUtil.instanceOf(clazz, ByteBuffer.class.getName())) {
+ final int type;
+ if(indices instanceof ByteBuffer) {
type = GL.GL_UNSIGNED_BYTE;
- } else if(ReflectionUtil.instanceOf(clazz, ShortBuffer.class.getName())) {
+ } else if(indices instanceof ShortBuffer) {
type = GL.GL_UNSIGNED_SHORT;
+ } else if(indices instanceof IntBuffer) {
+ type = GL.GL_UNSIGNED_INT;
+ } else {
+ throw new GLException("Given Buffer Class not supported: "+indices.getClass()+", should be ubyte, ushort or uint:\n\t"+this);
}
- if(0>type) {
- throw new GLException("Given Buffer Class not supported: "+clazz+", should be ubyte or ushort:\n\t"+this);
+ final int idxLen = indices.remaining();
+ final int idx0 = indices.position();
+
+ if ( GL_QUADS == mode && !gl.isGL2() ) {
+ if( GL.GL_UNSIGNED_BYTE == type ) {
+ final ByteBuffer b = (ByteBuffer) indices;
+ for (int j = 0; j < idxLen; j++) {
+ gl.glDrawArrays(GL.GL_TRIANGLE_FAN, (int)(0x000000ff & b.get(idx0+j)), 4);
+ }
+ } else if( GL.GL_UNSIGNED_SHORT == type ){
+ final ShortBuffer b = (ShortBuffer) indices;
+ for (int j = 0; j < idxLen; j++) {
+ gl.glDrawArrays(GL.GL_TRIANGLE_FAN, (int)(0x0000ffff & b.get(idx0+j)), 4);
+ }
+ } else {
+ final IntBuffer b = (IntBuffer) indices;
+ for (int j = 0; j < idxLen; j++) {
+ gl.glDrawArrays(GL.GL_TRIANGLE_FAN, (int)(0xffffffff & b.get(idx0+j)), 4);
+ }
+ }
+ } else {
+ gl.glDrawElements(mode, idxLen, type, indices);
+ // GL2: gl.glDrawRangeElements(mode, 0, idxLen-1, idxLen, type, indices);
}
- gl.glDrawElements(mode, indices.remaining(), type, indices);
- // GL2: gl.glDrawRangeElements(mode, 0, indices.remaining()-1, indices.remaining(), type, indices);
}
}
if(disableBufferAfterDraw) {
enableBuffer(gl, false);
}
+
+ if(DEBUG_DRAW) {
+ System.err.println("ImmModeSink.draw["+i+"].X (disableBufferAfterDraw: "+disableBufferAfterDraw+")");
+ }
}
public void glVertexv(Buffer v) {
checkSeal(false);
- GLBuffers.put(vertexArray, v);
+ Buffers.put(vertexArray, v);
}
public void glNormalv(Buffer v) {
checkSeal(false);
- GLBuffers.put(normalArray, v);
+ Buffers.put(normalArray, v);
}
public void glColorv(Buffer v) {
checkSeal(false);
- GLBuffers.put(colorArray, v);
+ Buffers.put(colorArray, v);
}
public void glTexCoordv(Buffer v) {
checkSeal(false);
- GLBuffers.put(textCoordArray, v);
+ Buffers.put(textCoordArray, v);
}
public void glVertex2b(byte x, byte y) {
checkSeal(false);
- growBufferIfNecessary(VERTEX, 2);
+ growBuffer(VERTEX);
if(vComps>0)
- GLBuffers.putb(vertexArray, x);
- if(vComps>1)
- GLBuffers.putb(vertexArray, y);
- padding(VERTEX, vComps-2);
+ Buffers.putNb(vertexArray, vDataTypeSigned, x, true);
+ if(vComps>1)
+ Buffers.putNb(vertexArray, vDataTypeSigned, y, true);
+ countAndPadding(VERTEX, vComps-2);
}
public void glVertex3b(byte x, byte y, byte z) {
checkSeal(false);
- growBufferIfNecessary(VERTEX, 3);
- if(vComps>0)
- GLBuffers.putb(vertexArray, x);
- if(vComps>1)
- GLBuffers.putb(vertexArray, y);
- if(vComps>2)
- GLBuffers.putb(vertexArray, z);
- padding(VERTEX, vComps-3);
+ growBuffer(VERTEX);
+ if(vComps>0)
+ Buffers.putNb(vertexArray, vDataTypeSigned, x, true);
+ if(vComps>1)
+ Buffers.putNb(vertexArray, vDataTypeSigned, y, true);
+ if(vComps>2)
+ Buffers.putNb(vertexArray, vDataTypeSigned, z, true);
+ countAndPadding(VERTEX, vComps-3);
}
public void glVertex2s(short x, short y) {
checkSeal(false);
- growBufferIfNecessary(VERTEX, 2);
- if(vComps>0)
- GLBuffers.puts(vertexArray, x);
+ growBuffer(VERTEX);
+ if(vComps>0)
+ Buffers.putNs(vertexArray, vDataTypeSigned, x, true);
if(vComps>1)
- GLBuffers.puts(vertexArray, y);
- padding(VERTEX, vComps-2);
+ Buffers.putNs(vertexArray, vDataTypeSigned, y, true);
+ countAndPadding(VERTEX, vComps-2);
}
public void glVertex3s(short x, short y, short z) {
checkSeal(false);
- growBufferIfNecessary(VERTEX, 3);
- if(vComps>0)
- GLBuffers.puts(vertexArray, x);
+ growBuffer(VERTEX);
+ if(vComps>0)
+ Buffers.putNs(vertexArray, vDataTypeSigned, x, true);
if(vComps>1)
- GLBuffers.puts(vertexArray, y);
+ Buffers.putNs(vertexArray, vDataTypeSigned, y, true);
if(vComps>2)
- GLBuffers.puts(vertexArray, z);
- padding(VERTEX, vComps-3);
+ Buffers.putNs(vertexArray, vDataTypeSigned, z, true);
+ countAndPadding(VERTEX, vComps-3);
}
public void glVertex2f(float x, float y) {
checkSeal(false);
- growBufferIfNecessary(VERTEX, 2);
+ growBuffer(VERTEX);
if(vComps>0)
- GLBuffers.putf(vertexArray, x);
- if(vComps>1)
- GLBuffers.putf(vertexArray, y);
- padding(VERTEX, vComps-2);
+ Buffers.putNf(vertexArray, vDataTypeSigned, x);
+ if(vComps>1)
+ Buffers.putNf(vertexArray, vDataTypeSigned, y);
+ countAndPadding(VERTEX, vComps-2);
}
public void glVertex3f(float x, float y, float z) {
checkSeal(false);
- growBufferIfNecessary(VERTEX, 3);
+ growBuffer(VERTEX);
if(vComps>0)
- GLBuffers.putf(vertexArray, x);
- if(vComps>1)
- GLBuffers.putf(vertexArray, y);
+ Buffers.putNf(vertexArray, vDataTypeSigned, x);
+ if(vComps>1)
+ Buffers.putNf(vertexArray, vDataTypeSigned, y);
if(vComps>2)
- GLBuffers.putf(vertexArray, z);
- padding(VERTEX, vComps-3);
+ Buffers.putNf(vertexArray, vDataTypeSigned, z);
+ countAndPadding(VERTEX, vComps-3);
}
public void glNormal3b(byte x, byte y, byte z) {
checkSeal(false);
- growBufferIfNecessary(NORMAL, 3);
- if(nComps>0)
- GLBuffers.putb(normalArray, x);
+ growBuffer(NORMAL);
+ if(nComps>0)
+ Buffers.putNb(normalArray, nDataTypeSigned, x, true);
if(nComps>1)
- GLBuffers.putb(normalArray, y);
+ Buffers.putNb(normalArray, nDataTypeSigned, y, true);
if(nComps>2)
- GLBuffers.putb(normalArray, z);
- padding(NORMAL, nComps-3);
+ Buffers.putNb(normalArray, nDataTypeSigned, z, true);
+ countAndPadding(NORMAL, nComps-3);
}
public void glNormal3s(short x, short y, short z) {
checkSeal(false);
- growBufferIfNecessary(NORMAL, 3);
+ growBuffer(NORMAL);
if(nComps>0)
- GLBuffers.puts(normalArray, x);
+ Buffers.putNs(normalArray, nDataTypeSigned, x, true);
if(nComps>1)
- GLBuffers.puts(normalArray, y);
+ Buffers.putNs(normalArray, nDataTypeSigned, y, true);
if(nComps>2)
- GLBuffers.puts(normalArray, z);
- padding(NORMAL, nComps-3);
+ Buffers.putNs(normalArray, nDataTypeSigned, z, true);
+ countAndPadding(NORMAL, nComps-3);
}
public void glNormal3f(float x, float y, float z) {
checkSeal(false);
- growBufferIfNecessary(NORMAL, 3);
+ growBuffer(NORMAL);
if(nComps>0)
- GLBuffers.putf(normalArray, x);
- if(nComps>1)
- GLBuffers.putf(normalArray, y);
+ Buffers.putNf(normalArray, nDataTypeSigned, x);
+ if(nComps>1)
+ Buffers.putNf(normalArray, nDataTypeSigned, y);
if(nComps>2)
- GLBuffers.putf(normalArray, z);
- padding(NORMAL, nComps-3);
+ Buffers.putNf(normalArray, nDataTypeSigned, z);
+ countAndPadding(NORMAL, nComps-3);
}
public void glColor3b(byte r, byte g, byte b) {
checkSeal(false);
- growBufferIfNecessary(COLOR, 3);
+ growBuffer(COLOR);
+ if(cComps>0)
+ Buffers.putNb(colorArray, cDataTypeSigned, r, true);
+ if(cComps>1)
+ Buffers.putNb(colorArray, cDataTypeSigned, g, true);
+ if(cComps>2)
+ Buffers.putNb(colorArray, cDataTypeSigned, b, true);
+ countAndPadding(COLOR, cComps-3);
+ }
+ public void glColor3ub(byte r, byte g, byte b) {
+ checkSeal(false);
+ growBuffer(COLOR);
if(cComps>0)
- GLBuffers.putb(colorArray, r);
+ Buffers.putNb(colorArray, cDataTypeSigned, r, false);
if(cComps>1)
- GLBuffers.putb(colorArray, g);
+ Buffers.putNb(colorArray, cDataTypeSigned, g, false);
if(cComps>2)
- GLBuffers.putb(colorArray, b);
- padding(COLOR, cComps-3);
+ Buffers.putNb(colorArray, cDataTypeSigned, b, false);
+ countAndPadding(COLOR, cComps-3);
}
public void glColor4b(byte r, byte g, byte b, byte a) {
checkSeal(false);
- growBufferIfNecessary(COLOR, 4);
+ growBuffer(COLOR);
if(cComps>0)
- GLBuffers.putb(colorArray, r);
+ Buffers.putNb(colorArray, cDataTypeSigned, r, true);
if(cComps>1)
- GLBuffers.putb(colorArray, g);
+ Buffers.putNb(colorArray, cDataTypeSigned, g, true);
if(cComps>2)
- GLBuffers.putb(colorArray, b);
+ Buffers.putNb(colorArray, cDataTypeSigned, b, true);
if(cComps>3)
- GLBuffers.putb(colorArray, a);
- padding(COLOR, cComps-4);
+ Buffers.putNb(colorArray, cDataTypeSigned, a, true);
+ countAndPadding(COLOR, cComps-4);
+ }
+ public void glColor4ub(byte r, byte g, byte b, byte a) {
+ checkSeal(false);
+ growBuffer(COLOR);
+ if(cComps>0)
+ Buffers.putNb(colorArray, cDataTypeSigned, r, false);
+ if(cComps>1)
+ Buffers.putNb(colorArray, cDataTypeSigned, g, false);
+ if(cComps>2)
+ Buffers.putNb(colorArray, cDataTypeSigned, b, false);
+ if(cComps>3)
+ Buffers.putNb(colorArray, cDataTypeSigned, a, false);
+ countAndPadding(COLOR, cComps-4);
}
public void glColor3s(short r, short g, short b) {
checkSeal(false);
- growBufferIfNecessary(COLOR, 3);
+ growBuffer(COLOR);
if(cComps>0)
- GLBuffers.puts(colorArray, r);
+ Buffers.putNs(colorArray, cDataTypeSigned, r, true);
if(cComps>1)
- GLBuffers.puts(colorArray, g);
+ Buffers.putNs(colorArray, cDataTypeSigned, g, true);
if(cComps>2)
- GLBuffers.puts(colorArray, b);
- padding(COLOR, cComps-3);
+ Buffers.putNs(colorArray, cDataTypeSigned, b, true);
+ countAndPadding(COLOR, cComps-3);
}
public void glColor4s(short r, short g, short b, short a) {
checkSeal(false);
- growBufferIfNecessary(COLOR, 4);
+ growBuffer(COLOR);
if(cComps>0)
- GLBuffers.puts(colorArray, r);
+ Buffers.putNs(colorArray, cDataTypeSigned, r, true);
if(cComps>1)
- GLBuffers.puts(colorArray, g);
+ Buffers.putNs(colorArray, cDataTypeSigned, g, true);
if(cComps>2)
- GLBuffers.puts(colorArray, b);
+ Buffers.putNs(colorArray, cDataTypeSigned, b, true);
if(cComps>3)
- GLBuffers.puts(colorArray, a);
- padding(COLOR, cComps-4);
+ Buffers.putNs(colorArray, cDataTypeSigned, a, true);
+ countAndPadding(COLOR, cComps-4);
}
public void glColor3f(float r, float g, float b) {
checkSeal(false);
- growBufferIfNecessary(COLOR, 3);
+ growBuffer(COLOR);
if(cComps>0)
- GLBuffers.putf(colorArray, r);
+ Buffers.putNf(colorArray, cDataTypeSigned, r);
if(cComps>1)
- GLBuffers.putf(colorArray, g);
+ Buffers.putNf(colorArray, cDataTypeSigned, g);
if(cComps>2)
- GLBuffers.putf(colorArray, b);
- padding(COLOR, cComps-3);
+ Buffers.putNf(colorArray, cDataTypeSigned, b);
+ countAndPadding(COLOR, cComps-3);
}
public void glColor4f(float r, float g, float b, float a) {
checkSeal(false);
- growBufferIfNecessary(COLOR, 4);
+ growBuffer(COLOR);
if(cComps>0)
- GLBuffers.putf(colorArray, r);
+ Buffers.putNf(colorArray, cDataTypeSigned, r);
if(cComps>1)
- GLBuffers.putf(colorArray, g);
+ Buffers.putNf(colorArray, cDataTypeSigned, g);
if(cComps>2)
- GLBuffers.putf(colorArray, b);
+ Buffers.putNf(colorArray, cDataTypeSigned, b);
if(cComps>3)
- GLBuffers.putf(colorArray, a);
- padding(COLOR, cComps-4);
+ Buffers.putNf(colorArray, cDataTypeSigned, a);
+ countAndPadding(COLOR, cComps-4);
}
public void glTexCoord2b(byte x, byte y) {
checkSeal(false);
- growBufferIfNecessary(TEXTCOORD, 2);
+ growBuffer(TEXTCOORD);
if(tComps>0)
- GLBuffers.putb(textCoordArray, x);
+ Buffers.putNb(textCoordArray, tDataTypeSigned, x, true);
if(tComps>1)
- GLBuffers.putb(textCoordArray, y);
- padding(TEXTCOORD, tComps-2);
+ Buffers.putNb(textCoordArray, tDataTypeSigned, y, true);
+ countAndPadding(TEXTCOORD, tComps-2);
}
public void glTexCoord3b(byte x, byte y, byte z) {
checkSeal(false);
- growBufferIfNecessary(TEXTCOORD, 3);
+ growBuffer(TEXTCOORD);
if(tComps>0)
- GLBuffers.putb(textCoordArray, x);
+ Buffers.putNb(textCoordArray, tDataTypeSigned, x, true);
if(tComps>1)
- GLBuffers.putb(textCoordArray, y);
+ Buffers.putNb(textCoordArray, tDataTypeSigned, y, true);
if(tComps>2)
- GLBuffers.putb(textCoordArray, z);
- padding(TEXTCOORD, tComps-3);
+ Buffers.putNb(textCoordArray, tDataTypeSigned, z, true);
+ countAndPadding(TEXTCOORD, tComps-3);
}
public void glTexCoord2s(short x, short y) {
checkSeal(false);
- growBufferIfNecessary(TEXTCOORD, 2);
+ growBuffer(TEXTCOORD);
if(tComps>0)
- GLBuffers.puts(textCoordArray, x);
+ Buffers.putNs(textCoordArray, tDataTypeSigned, x, true);
if(tComps>1)
- GLBuffers.puts(textCoordArray, y);
- padding(TEXTCOORD, tComps-2);
+ Buffers.putNs(textCoordArray, tDataTypeSigned, y, true);
+ countAndPadding(TEXTCOORD, tComps-2);
}
public void glTexCoord3s(short x, short y, short z) {
checkSeal(false);
- growBufferIfNecessary(TEXTCOORD, 3);
+ growBuffer(TEXTCOORD);
if(tComps>0)
- GLBuffers.puts(textCoordArray, x);
+ Buffers.putNs(textCoordArray, tDataTypeSigned, x, true);
if(tComps>1)
- GLBuffers.puts(textCoordArray, y);
+ Buffers.putNs(textCoordArray, tDataTypeSigned, y, true);
if(tComps>2)
- GLBuffers.puts(textCoordArray, z);
- padding(TEXTCOORD, tComps-3);
+ Buffers.putNs(textCoordArray, tDataTypeSigned, z, true);
+ countAndPadding(TEXTCOORD, tComps-3);
}
public void glTexCoord2f(float x, float y) {
checkSeal(false);
- growBufferIfNecessary(TEXTCOORD, 2);
+ growBuffer(TEXTCOORD);
if(tComps>0)
- GLBuffers.putf(textCoordArray, x);
+ Buffers.putNf(textCoordArray, tDataTypeSigned, x);
if(tComps>1)
- GLBuffers.putf(textCoordArray, y);
- padding(TEXTCOORD, tComps-2);
+ Buffers.putNf(textCoordArray, tDataTypeSigned, y);
+ countAndPadding(TEXTCOORD, tComps-2);
}
public void glTexCoord3f(float x, float y, float z) {
checkSeal(false);
- growBufferIfNecessary(TEXTCOORD, 3);
+ growBuffer(TEXTCOORD);
if(tComps>0)
- GLBuffers.putf(textCoordArray, x);
+ Buffers.putNf(textCoordArray, tDataTypeSigned, x);
if(tComps>1)
- GLBuffers.putf(textCoordArray, y);
+ Buffers.putNf(textCoordArray, tDataTypeSigned, y);
if(tComps>2)
- GLBuffers.putf(textCoordArray, z);
- padding(TEXTCOORD, tComps-3);
+ Buffers.putNf(textCoordArray, tDataTypeSigned, z);
+ countAndPadding(TEXTCOORD, tComps-3);
}
public void rewind() {
@@ -629,10 +791,10 @@ public class ImmModeSink {
public void destroy(GL gl) {
reset(gl);
+ vCount=0; cCount=0; nCount=0; tCount=0;
vertexArray=null; colorArray=null; normalArray=null; textCoordArray=null;
vArrayData=null; cArrayData=null; nArrayData=null; tArrayData=null;
buffer=null;
- bSize=0; count=0;
}
public void reset(GL gl) {
@@ -649,8 +811,13 @@ public class ImmModeSink {
this.mode = 0;
this.modeOrig = 0;
this.sealed=false;
+ this.sealedGL=false;
this.bufferEnabled=false;
this.bufferWritten=false;
+ this.vElems=0;
+ this.cElems=0;
+ this.nElems=0;
+ this.tElems=0;
}
public void seal(GL glObj, boolean seal)
@@ -660,19 +827,25 @@ public class ImmModeSink {
sealedGL = seal;
GL gl = glObj.getGL();
if(seal) {
- if(vboUsage && vboName==0) {
- int[] tmp = new int[1];
- gl.glGenBuffers(1, tmp, 0);
- vboName = tmp[0];
+ if(useVBO) {
+ if(0 == vboName) {
+ int[] tmp = new int[1];
+ gl.glGenBuffers(1, tmp, 0);
+ vboName = tmp[0];
+ }
+ if(null!=vArrayData) {
+ vArrayData.setVBOName(vboName);
+ }
+ if(null!=cArrayData) {
+ cArrayData.setVBOName(vboName);
+ }
+ if(null!=nArrayData) {
+ nArrayData.setVBOName(vboName);
+ }
+ if(null!=tArrayData) {
+ tArrayData.setVBOName(vboName);
+ }
}
- if(null!=vArrayData)
- vArrayData.setVBOName(vboName);
- if(null!=cArrayData)
- cArrayData.setVBOName(vboName);
- if(null!=nArrayData)
- nArrayData.setVBOName(vboName);
- if(null!=tArrayData)
- tArrayData.setVBOName(vboName);
enableBuffer(gl, true);
} else {
enableBuffer(gl, false);
@@ -685,68 +858,114 @@ public class ImmModeSink {
sealed = seal;
if(seal) {
bufferWritten=false;
+ rewind();
}
}
public void enableBuffer(GL gl, boolean enable) {
- /* if(enableBufferAlways && enable) {
- bufferEnabled = false;
- } */
- if( bufferEnabled != enable && count>0 ) {
+ if( bufferEnabled != enable && vElems>0 ) {
if(enable) {
checkSeal(true);
}
+ bufferEnabled = enable;
if(useGLSL) {
enableBufferGLSL(gl, enable);
} else {
enableBufferFixed(gl, enable);
}
- bufferEnabled = enable;
}
}
+ private final void writeBuffer(GL gl) {
+ final int vBytes = vElems * vCompsBytes;
+ final int cBytes = cElems * cCompsBytes;
+ final int nBytes = nElems * nCompsBytes;
+ final int tBytes = tElems * tCompsBytes;
+ final int delta = buffer.limit() - (vBytes+cBytes+nBytes+tBytes);
+ if( bufferWrittenOnce && delta > pageSize ) {
+ if(0 < vBytes) {
+ gl.glBufferSubData(GL.GL_ARRAY_BUFFER, vOffset, vBytes, vertexArray);
+ }
+ if(0 < cBytes) {
+ gl.glBufferSubData(GL.GL_ARRAY_BUFFER, cOffset, cBytes, colorArray);
+ }
+ if(0 < nBytes) {
+ gl.glBufferSubData(GL.GL_ARRAY_BUFFER, nOffset, nBytes, normalArray);
+ }
+ if(0 < tBytes) {
+ gl.glBufferSubData(GL.GL_ARRAY_BUFFER, tOffset, tBytes, textCoordArray);
+ }
+ } else {
+ gl.glBufferData(GL.GL_ARRAY_BUFFER, buffer.limit(), buffer, glBufferUsage);
+ bufferWrittenOnce = true;
+ }
+ }
+
public void enableBufferFixed(GL gl, boolean enable) {
GL2ES1 glf = gl.getGL2ES1();
+
+ final boolean useV = vComps>0 && vElems>0 ;
+ final boolean useC = cComps>0 && cElems>0 ;
+ final boolean useN = nComps>0 && nElems>0 ;
+ final boolean useT = tComps>0 && tElems>0 ;
+
+ if(DEBUG_DRAW) {
+ System.err.println("ImmModeSink.enableFixed.0 "+enable+": use [ v "+useV+", c "+useC+", n "+useN+", t "+useT+"], "+getElemUseCountStr()+", "+buffer);
+ }
if(enable) {
- gl.glBindBuffer(GL.GL_ARRAY_BUFFER, vboName);
-
- if(!bufferWritten) {
- gl.glBufferData(GL.GL_ARRAY_BUFFER, buffer.limit(), buffer, GL.GL_STATIC_DRAW);
- bufferWritten=true;
+ if(useVBO) {
+ if(0 == vboName) {
+ throw new InternalError("Using VBO but no vboName");
+ }
+ glf.glBindBuffer(GL.GL_ARRAY_BUFFER, vboName);
+
+ if(!bufferWritten) {
+ writeBuffer(gl);
+ }
}
+ bufferWritten=true;
+ }
- if(vComps>0) {
+ if(useV) {
+ if(enable) {
glf.glEnableClientState(GLPointerFunc.GL_VERTEX_ARRAY);
glf.glVertexPointer(vArrayData);
- }
- if(cComps>0) {
+ } else {
+ glf.glDisableClientState(GLPointerFunc.GL_VERTEX_ARRAY);
+ }
+ }
+ if(useC) {
+ if(enable) {
glf.glEnableClientState(GLPointerFunc.GL_COLOR_ARRAY);
glf.glColorPointer(cArrayData);
- }
- if(nComps>0) {
+ } else {
+ glf.glDisableClientState(GLPointerFunc.GL_COLOR_ARRAY);
+ }
+ }
+ if(useN) {
+ if(enable) {
glf.glEnableClientState(GLPointerFunc.GL_NORMAL_ARRAY);
glf.glNormalPointer(nArrayData);
- }
- if(tComps>0) {
+ } else {
+ glf.glDisableClientState(GLPointerFunc.GL_NORMAL_ARRAY);
+ }
+ }
+ if(useT) {
+ if(enable) {
glf.glEnableClientState(GLPointerFunc.GL_TEXTURE_COORD_ARRAY);
glf.glTexCoordPointer(tArrayData);
- }
+ } else {
+ glf.glDisableClientState(GLPointerFunc.GL_TEXTURE_COORD_ARRAY);
+ }
+ }
+ if(enable && useVBO) {
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
- } else {
- if(vComps>0) {
- glf.glDisableClientState(GLPointerFunc.GL_VERTEX_ARRAY);
- }
- if(cComps>0) {
- glf.glDisableClientState(GLPointerFunc.GL_COLOR_ARRAY);
- }
- if(nComps>0) {
- glf.glDisableClientState(GLPointerFunc.GL_NORMAL_ARRAY);
- }
- if(tComps>0) {
- glf.glDisableClientState(GLPointerFunc.GL_TEXTURE_COORD_ARRAY);
- }
+ }
+
+ if(DEBUG_DRAW) {
+ System.err.println("ImmModeSink.enableFixed.X ");
}
}
@@ -757,54 +976,79 @@ public class ImmModeSink {
}
GL2ES2 glsl = gl.getGL2ES2();
+ final boolean useV = vComps>0 && vElems>0 ;
+ final boolean useC = cComps>0 && cElems>0 ;
+ final boolean useN = nComps>0 && nElems>0 ;
+ final boolean useT = tComps>0 && tElems>0 ;
+
+ if(DEBUG_DRAW) {
+ System.err.println("ImmModeSink.enableGLSL.0 "+enable+": use [ v "+useV+", c "+useC+", n "+useN+", t "+useT+"], "+getElemUseCountStr()+", "+buffer);
+ }
+
if(enable) {
- glsl.glBindBuffer(GL.GL_ARRAY_BUFFER, vboName);
-
- if(!bufferWritten) {
- glsl.glBufferData(GL.GL_ARRAY_BUFFER, buffer.limit(), buffer, GL.GL_STATIC_DRAW);
- bufferWritten=true;
+ if(useVBO) {
+ if(0 == vboName) {
+ throw new InternalError("Using VBO but no vboName");
+ }
+ glsl.glBindBuffer(GL.GL_ARRAY_BUFFER, vboName);
+ if(!bufferWritten) {
+ writeBuffer(gl);
+ }
}
+ bufferWritten=true;
+ }
- if(vComps>0) {
+ if(useV) {
+ if(enable) {
st.enableVertexAttribArray(glsl, vArrayData);
st.vertexAttribPointer(glsl, vArrayData);
- }
- if(cComps>0) {
+ } else {
+ st.disableVertexAttribArray(glsl, vArrayData);
+ }
+ }
+ if(useC) {
+ if(enable) {
st.enableVertexAttribArray(glsl, cArrayData);
st.vertexAttribPointer(glsl, cArrayData);
- }
- if(nComps>0) {
+ } else {
+ st.disableVertexAttribArray(glsl, cArrayData);
+ }
+ }
+ if(useN) {
+ if(enable) {
st.enableVertexAttribArray(glsl, nArrayData);
st.vertexAttribPointer(glsl, nArrayData);
- }
- if(tComps>0) {
+ } else {
+ st.disableVertexAttribArray(glsl, nArrayData);
+ }
+ }
+ if(useT) {
+ if(enable) {
st.enableVertexAttribArray(glsl, tArrayData);
st.vertexAttribPointer(glsl, tArrayData);
- }
-
- glsl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
- } else {
- if(vComps>0) {
- st.disableVertexAttribArray(glsl, vArrayData);
- }
- if(cComps>0) {
- st.disableVertexAttribArray(glsl, cArrayData);
- }
- if(nComps>0) {
- st.disableVertexAttribArray(glsl, nArrayData);
- }
- if(tComps>0) {
+ } else {
st.disableVertexAttribArray(glsl, tArrayData);
- }
+ }
+ }
+
+ if(enable && useVBO) {
+ glsl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
+ }
+
+ if(DEBUG_DRAW) {
+ System.err.println("ImmModeSink.enableGLSL.X ");
}
}
public String toString() {
return "VBOSet[mode "+mode+
", modeOrig "+modeOrig+
+ ", use/count "+getElemUseCountStr()+
", sealed "+sealed+
+ ", sealedGL "+sealedGL+
", bufferEnabled "+bufferEnabled+
- ", bufferWritten "+bufferWritten+
+ ", bufferWritten "+bufferWritten+" (once "+bufferWrittenOnce+")"+
+ ", useVBO "+useVBO+", vboName "+vboName+
",\n\t"+vArrayData+
",\n\t"+cArrayData+
",\n\t"+nArrayData+
@@ -814,165 +1058,236 @@ public class ImmModeSink {
// non public matters
- protected void allocateBuffer(int elementCount) {
- int vWidth = vComps * GLBuffers.sizeOfGLType(vDataType);
- int cWidth = cComps * GLBuffers.sizeOfGLType(cDataType);
- int nWidth = nComps * GLBuffers.sizeOfGLType(nDataType);
- int tWidth = tComps * GLBuffers.sizeOfGLType(tDataType);
-
- count = elementCount;
- bSize = count * ( vWidth + cWidth + nWidth + tWidth ) ;
-
- buffer = GLBuffers.newDirectByteBuffer(bSize);
-
- int pos = 0;
- int size= count * vWidth ;
- if(size>0) {
- vertexArray = GLBuffers.sliceGLBuffer(buffer, pos, size, vDataType);
+ protected String getElemUseCountStr() {
+ return "[v "+vElems+"/"+vCount+", c "+cElems+"/"+cCount+", n "+nElems+"/"+nCount+", t "+tElems+"/"+tCount+"]";
+ }
+
+ protected boolean fitElementInBuffer(int type) {
+ final int addElems = 1;
+ switch (type) {
+ case VERTEX:
+ return ( vCount - vElems ) >= addElems ;
+ case COLOR:
+ return ( cCount - cElems ) >= addElems ;
+ case NORMAL:
+ return ( nCount - nElems ) >= addElems ;
+ case TEXTCOORD:
+ return ( tCount - tElems ) >= addElems ;
+ default:
+ throw new InternalError("XXX");
+ }
+ }
+
+ protected boolean reallocateBuffer(int addElems) {
+ final int vAdd = addElems - ( vCount - vElems );
+ final int cAdd = addElems - ( cCount - cElems );
+ final int nAdd = addElems - ( nCount - nElems );
+ final int tAdd = addElems - ( tCount - tElems );
+
+ if( 0>=vAdd && 0>=cAdd && 0>=nAdd && 0>=tAdd) {
+ if(DEBUG_BUFFER) {
+ System.err.println("ImmModeSink.realloc: "+getElemUseCountStr()+" + "+addElems+" -> NOP");
+ }
+ return false;
+ }
+
+ if(DEBUG_BUFFER) {
+ System.err.println("ImmModeSink.realloc: "+getElemUseCountStr()+" + "+addElems);
+ }
+ vCount += vAdd;
+ cCount += cAdd;
+ nCount += nAdd;
+ tCount += tAdd;
+
+ final int vBytes = vCount * vCompsBytes;
+ final int cBytes = cCount * cCompsBytes;
+ final int nBytes = nCount * nCompsBytes;
+ final int tBytes = tCount * tCompsBytes;
+
+ buffer = Buffers.newDirectByteBuffer( vBytes + cBytes + nBytes + tBytes );
+ vOffset = 0;
+
+ if(vBytes>0) {
+ vertexArray = GLBuffers.sliceGLBuffer(buffer, vOffset, vBytes, vDataType);
} else {
vertexArray = null;
- }
- vOffset = pos;
- pos+=size;
+ }
+ cOffset=vOffset+vBytes;
- size= count * cWidth ;
- if(size>0) {
- colorArray = GLBuffers.sliceGLBuffer(buffer, pos, size, cDataType);
+ if(cBytes>0) {
+ colorArray = GLBuffers.sliceGLBuffer(buffer, cOffset, cBytes, cDataType);
} else {
colorArray = null;
}
- cOffset = pos;
- pos+=size;
+ nOffset=cOffset+cBytes;
- size= count * nWidth ;
- if(size>0) {
- normalArray = GLBuffers.sliceGLBuffer(buffer, pos, size, nDataType);
+ if(nBytes>0) {
+ normalArray = GLBuffers.sliceGLBuffer(buffer, nOffset, nBytes, nDataType);
} else {
normalArray = null;
}
- nOffset = pos;
- pos+=size;
+ tOffset=nOffset+nBytes;
- size= count * tWidth ;
- if(size>0) {
- textCoordArray = GLBuffers.sliceGLBuffer(buffer, pos, size, tDataType);
+ if(tBytes>0) {
+ textCoordArray = GLBuffers.sliceGLBuffer(buffer, tOffset, tBytes, tDataType);
} else {
textCoordArray = null;
}
- tOffset = pos;
- pos+=size;
- buffer.position(pos);
+ buffer.position(tOffset+tBytes);
buffer.flip();
if(vComps>0) {
- vArrayData = GLArrayDataWrapper.createFixed(GLPointerFunc.GL_VERTEX_ARRAY, vComps, vDataType, false, 0,
+ vArrayData = GLArrayDataWrapper.createFixed(GLPointerFunc.GL_VERTEX_ARRAY, vComps,
+ vDataType, GLBuffers.isGLTypeFixedPoint(vDataType), 0,
vertexArray, 0, vOffset, GL.GL_STATIC_DRAW, GL.GL_ARRAY_BUFFER);
} else {
vArrayData = null;
}
if(cComps>0) {
- cArrayData = GLArrayDataWrapper.createFixed(GLPointerFunc.GL_COLOR_ARRAY, cComps, cDataType, false, 0,
+ cArrayData = GLArrayDataWrapper.createFixed(GLPointerFunc.GL_COLOR_ARRAY, cComps,
+ cDataType, GLBuffers.isGLTypeFixedPoint(cDataType), 0,
colorArray, 0, cOffset, GL.GL_STATIC_DRAW, GL.GL_ARRAY_BUFFER);
} else {
cArrayData = null;
}
if(nComps>0) {
- nArrayData = GLArrayDataWrapper.createFixed(GLPointerFunc.GL_NORMAL_ARRAY, nComps, nDataType, false, 0,
+ nArrayData = GLArrayDataWrapper.createFixed(GLPointerFunc.GL_NORMAL_ARRAY, nComps,
+ nDataType, GLBuffers.isGLTypeFixedPoint(nDataType), 0,
normalArray, 0, nOffset, GL.GL_STATIC_DRAW, GL.GL_ARRAY_BUFFER);
} else {
nArrayData = null;
}
if(tComps>0) {
- tArrayData = GLArrayDataWrapper.createFixed(GLPointerFunc.GL_TEXTURE_COORD_ARRAY, tComps, tDataType, false, 0,
+ tArrayData = GLArrayDataWrapper.createFixed(GLPointerFunc.GL_TEXTURE_COORD_ARRAY, tComps,
+ tDataType, GLBuffers.isGLTypeFixedPoint(tDataType), 0,
textCoordArray, 0, tOffset, GL.GL_STATIC_DRAW, GL.GL_ARRAY_BUFFER);
} else {
tArrayData = null;
}
-
- }
-
- protected final boolean growBufferIfNecessary(int type, int spare) {
- if(buffer==null || count < spare) {
- growBuffer(type, initialElementCount);
- return true;
+
+ bufferWrittenOnce = false; // new buffer data storage size!
+
+ if(DEBUG_BUFFER) {
+ System.err.println("ImmModeSink.realloc.X: "+this.toString());
+ Thread.dumpStack();
}
- return false;
+ return true;
}
- protected final void growBuffer(int type, int additional) {
- if(sealed || 0==additional) return;
-
- // save olde values ..
- Buffer _vertexArray=vertexArray, _colorArray=colorArray, _normalArray=normalArray, _textCoordArray=textCoordArray;
-
- allocateBuffer(count+additional);
-
- if(null!=_vertexArray) {
- _vertexArray.flip();
- GLBuffers.put(vertexArray, _vertexArray);
- }
- if(null!=_colorArray) {
- _colorArray.flip();
- GLBuffers.put(colorArray, _colorArray);
- }
- if(null!=_normalArray) {
- _normalArray.flip();
- GLBuffers.put(normalArray, _normalArray);
- }
- if(null!=_textCoordArray) {
- _textCoordArray.flip();
- GLBuffers.put(textCoordArray, _textCoordArray);
+ /** grow buffer by initialElementCount if there is no space for one more element in the designated buffer */
+ protected final boolean growBuffer(int type) {
+ if( null !=buffer && !sealed ) {
+ if( !fitElementInBuffer(type) ) {
+ // save olde values ..
+ final Buffer _vertexArray=vertexArray, _colorArray=colorArray, _normalArray=normalArray, _textCoordArray=textCoordArray;
+
+ if ( reallocateBuffer(resizeElementCount) ) {
+ if(null!=_vertexArray) {
+ _vertexArray.flip();
+ Buffers.put(vertexArray, _vertexArray);
+ }
+ if(null!=_colorArray) {
+ _colorArray.flip();
+ Buffers.put(colorArray, _colorArray);
+ }
+ if(null!=_normalArray) {
+ _normalArray.flip();
+ Buffers.put(normalArray, _normalArray);
+ }
+ if(null!=_textCoordArray) {
+ _textCoordArray.flip();
+ Buffers.put(textCoordArray, _textCoordArray);
+ }
+ return true;
+ }
+ }
}
+ return false;
}
- protected void padding(int type, int fill) {
+ /**
+ * Fourth element default value for color (alpha), vertex (w) is '1',
+ * as specified w/ VertexAttributes (ES2/GL3).
+ * <p>
+ * vec4 v = vec4(0, 0, 0, 1);
+ * vec4 c = vec4(0, 0, 0, 1);
+ * </p>
+ *
+ * @param type
+ * @param fill
+ */
+ private void countAndPadding(int type, int fill) {
if ( sealed ) return;
- Buffer dest = null;
-
+ final Buffer dest;
+ final boolean dSigned;
+ final int e; // either 0 or 1
+
switch (type) {
case VERTEX:
dest = vertexArray;
+ dSigned = vDataTypeSigned;
+ e = 4 == vComps ? 1 : 0;
+ vElems++;
break;
case COLOR:
dest = colorArray;
+ dSigned = cDataTypeSigned;
+ e = 4 == cComps ? 1 : 0;
+ cElems++;
break;
case NORMAL:
dest = normalArray;
+ dSigned = nDataTypeSigned;
+ e = 0;
+ nElems++;
break;
case TEXTCOORD:
dest = textCoordArray;
+ dSigned = tDataTypeSigned;
+ e = 0;
+ tElems++;
break;
+ default: throw new InternalError("Invalid type "+type);
}
if ( null==dest ) return;
- while((fill--)>0) {
- GLBuffers.putb(dest, (byte)0);
+ while( fill > e ) {
+ fill--;
+ Buffers.putNf(dest, dSigned, 0f);
+ }
+ if( fill > 0 ) { // e == 1, add missing '1f end component'
+ Buffers.putNf(dest, dSigned, 1f);
}
}
- protected int mode, modeOrig;
- protected int glBufferUsage, initialElementCount;
-
- protected ByteBuffer buffer;
- protected int bSize, count, vboName;
-
- public static final int VERTEX = 0;
- public static final int COLOR = 1;
- public static final int NORMAL = 2;
- public static final int TEXTCOORD = 3;
-
- protected int vOffset, cOffset, nOffset, tOffset;
- protected int vComps, cComps, nComps, tComps;
- protected int vDataType, cDataType, nDataType, tDataType;
- protected Buffer vertexArray, colorArray, normalArray, textCoordArray;
- protected GLArrayDataWrapper vArrayData, cArrayData, nArrayData, tArrayData;
-
- protected boolean sealed, sealedGL, useGLSL;
- protected boolean bufferEnabled, bufferWritten;
- protected GL gl;
+ final private int glBufferUsage, initialElementCount;
+ final private boolean useVBO;
+ private int mode, modeOrig, resizeElementCount;
+
+ private ByteBuffer buffer;
+ private int vboName;
+
+ private static final int VERTEX = 0;
+ private static final int COLOR = 1;
+ private static final int NORMAL = 2;
+ private static final int TEXTCOORD = 3;
+
+ private int vCount, cCount, nCount, tCount; // number of elements fit in each buffer
+ private int vOffset, cOffset, nOffset, tOffset; // offset of specific array in common buffer
+ private int vElems, cElems, nElems, tElems; // number of used elements in each buffer
+ private final int vComps, cComps, nComps, tComps; // number of components for each elements [2, 3, 4]
+ private final int vCompsBytes, cCompsBytes, nCompsBytes, tCompsBytes; // byte size of all components
+ private final int vDataType, cDataType, nDataType, tDataType;
+ private final boolean vDataTypeSigned, cDataTypeSigned, nDataTypeSigned, tDataTypeSigned;
+ private final int pageSize;
+ private Buffer vertexArray, colorArray, normalArray, textCoordArray;
+ private GLArrayDataWrapper vArrayData, cArrayData, nArrayData, tArrayData;
+
+ private boolean sealed, sealedGL, useGLSL;
+ private boolean bufferEnabled, bufferWritten, bufferWrittenOnce;
}
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java b/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java
index fc6ef3e..80df9cd 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java
@@ -48,12 +48,146 @@ import jogamp.opengl.ProjectFloat;
import com.jogamp.opengl.FloatUtil;
import com.jogamp.common.nio.Buffers;
-
+import com.jogamp.common.os.Platform;
+
+/**
+ * PMVMatrix implements a subset of the fixed function pipeline
+ * regarding the projection (P), modelview (Mv) matrix operation
+ * which is specified in {@link GLMatrixFunc}.
+ * <p>
+ * Further more, PMVMatrix provides the {@link #glGetMviMatrixf() inverse modelview matrix (Mvi)} and
+ * {@link #glGetMvitMatrixf() inverse transposed modelview matrix (Mvit)}.
+ * To keep both synchronized after mutable Mv operations like {@link #glRotatef(float, float, float, float) glRotatef(..)}
+ * in {@link #glMatrixMode(int) glMatrixMode}({@link GLMatrixFunc#GL_MODELVIEW GL_MODELVIEW}),
+ * users have to call {@link #update()} before using Mvi and Mvit.
+ * </p>
+ * <p>
+ * All matrices are provided in column-major order,
+ * as specified in the OpenGL fixed function pipeline, i.e. compatibility profile.
+ * </p>
+ * <p>
+ * PMVMatrix can supplement {@link GL2ES2} applications w/ the
+ * lack of the described matrix functionality.
+ * </p>
+ * <a name="storageDetails"><h5>Matrix storage details</h5></a>
+ * <p>
+ * All matrices use a common FloatBuffer storage
+ * and are a {@link Buffers#slice2Float(Buffer, float[], int, int) sliced} representation of it.
+ * The common FloatBuffer and hence all matrices may use NIO direct storage or a {@link #usesBackingArray() backing float array},
+ * depending how the instance if {@link #PMVMatrix(boolean) being constructed}.
+ * </p>
+ * <p>
+ * <b>Note:</b>
+ * <ul>
+ * <li>The matrix is a {@link Buffers#slice2Float(Buffer, float[], int, int) sliced part } of a host matrix and it's start position has been {@link FloatBuffer#mark() marked}.</li>
+ * <li>Use {@link FloatBuffer#reset() reset()} to rewind it to it's start position after relative operations, like {@link FloatBuffer#get() get()}.</li>
+ * <li>If using absolute operations like {@link FloatBuffer#get(int) get(int)}, use it's {@link FloatBuffer#reset() reset} {@link FloatBuffer#position() position} as it's offset.</li>
+ * </ul>
+ * </p>
+ */
public class PMVMatrix implements GLMatrixFunc {
- protected final float[] matrixBufferArray;
+ /** Bit value stating a modified {@link #glGetPMatrixf() projection matrix (P)}, since last {@link #update()} call. */
+ public static final int MODIFIED_PROJECTION = 1 << 0;
+ /** Bit value stating a modified {@link #glGetMvMatrixf() modelview matrix (Mv)}, since last {@link #update()} call. */
+ public static final int MODIFIED_MODELVIEW = 1 << 1;
+ /** Bit value stating a modified {@link #glGetTMatrixf() texture matrix (T)}, since last {@link #update()} call. */
+ public static final int MODIFIED_TEXTURE = 1 << 2;
+ /** Bit value stating all is modified */
+ public static final int MODIFIED_ALL = MODIFIED_PROJECTION | MODIFIED_MODELVIEW | MODIFIED_TEXTURE ;
+
+ /** Bit value stating a dirty {@link #glGetMviMatrixf() inverse modelview matrix (Mvi)}. */
+ public static final int DIRTY_INVERSE_MODELVIEW = 1 << 0;
+ /** Bit value stating a dirty {@link #glGetMvitMatrixf() inverse transposed modelview matrix (Mvit)}. */
+ public static final int DIRTY_INVERSE_TRANSPOSED_MODELVIEW = 1 << 1;
+ /** Bit value stating all is dirty */
+ public static final int DIRTY_ALL = DIRTY_INVERSE_MODELVIEW | DIRTY_INVERSE_TRANSPOSED_MODELVIEW ;
+
+ /**
+ * @param matrixModeName One of {@link GLMatrixFunc#GL_MODELVIEW GL_MODELVIEW}, {@link GLMatrixFunc#GL_PROJECTION GL_PROJECTION} or {@link GL#GL_TEXTURE GL_TEXTURE}
+ * @return true if the given matrix-mode name is valid, otherwise false.
+ */
+ public static final boolean isMatrixModeName(final int matrixModeName) {
+ switch(matrixModeName) {
+ case GL_MODELVIEW_MATRIX:
+ case GL_PROJECTION_MATRIX:
+ case GL_TEXTURE_MATRIX:
+ return true;
+ }
+ return false;
+ }
/**
+ * @param matrixModeName One of {@link GLMatrixFunc#GL_MODELVIEW GL_MODELVIEW}, {@link GLMatrixFunc#GL_PROJECTION GL_PROJECTION} or {@link GL#GL_TEXTURE GL_TEXTURE}
+ * @return The corresponding matrix-get name, one of {@link GLMatrixFunc#GL_MODELVIEW_MATRIX GL_MODELVIEW_MATRIX}, {@link GLMatrixFunc#GL_PROJECTION_MATRIX GL_PROJECTION_MATRIX} or {@link GLMatrixFunc#GL_TEXTURE_MATRIX GL_TEXTURE_MATRIX}
+ */
+ public static final int matrixModeName2MatrixGetName(final int matrixModeName) {
+ switch(matrixModeName) {
+ case GL_MODELVIEW:
+ return GL_MODELVIEW_MATRIX;
+ case GL_PROJECTION:
+ return GL_PROJECTION_MATRIX;
+ case GL.GL_TEXTURE:
+ return GL_TEXTURE_MATRIX;
+ default:
+ throw new GLException("unsupported matrixName: "+matrixModeName);
+ }
+ }
+
+ /**
+ * @param matrixGetName One of {@link GLMatrixFunc#GL_MODELVIEW_MATRIX GL_MODELVIEW_MATRIX}, {@link GLMatrixFunc#GL_PROJECTION_MATRIX GL_PROJECTION_MATRIX} or {@link GLMatrixFunc#GL_TEXTURE_MATRIX GL_TEXTURE_MATRIX}
+ * @return true if the given matrix-get name is valid, otherwise false.
+ */
+ public static final boolean isMatrixGetName(final int matrixGetName) {
+ switch(matrixGetName) {
+ case GL_MATRIX_MODE:
+ case GL_MODELVIEW_MATRIX:
+ case GL_PROJECTION_MATRIX:
+ case GL_TEXTURE_MATRIX:
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * @param matrixGetName One of {@link GLMatrixFunc#GL_MODELVIEW_MATRIX GL_MODELVIEW_MATRIX}, {@link GLMatrixFunc#GL_PROJECTION_MATRIX GL_PROJECTION_MATRIX} or {@link GLMatrixFunc#GL_TEXTURE_MATRIX GL_TEXTURE_MATRIX}
+ * @return The corresponding matrix-mode name, one of {@link GLMatrixFunc#GL_MODELVIEW GL_MODELVIEW}, {@link GLMatrixFunc#GL_PROJECTION GL_PROJECTION} or {@link GL#GL_TEXTURE GL_TEXTURE}
+ */
+ public static final int matrixGetName2MatrixModeName(final int matrixGetName) {
+ switch(matrixGetName) {
+ case GL_MODELVIEW_MATRIX:
+ return GL_MODELVIEW;
+ case GL_PROJECTION_MATRIX:
+ return GL_PROJECTION;
+ case GL_TEXTURE_MATRIX:
+ return GL.GL_TEXTURE;
+ default:
+ throw new GLException("unsupported matrixGetName: "+matrixGetName);
+ }
+ }
+
+ /**
+ * @param sb optional passed StringBuilder instance to be used
+ * @param f the format string of one floating point, i.e. "%10.5f", see {@link java.util.Formatter}
+ * @param a 4x4 matrix in column major order (OpenGL)
+ * @return matrix string representation
+ */
+ public static StringBuilder matrixToString(StringBuilder sb, String f, FloatBuffer a) {
+ return FloatUtil.matrixToString(sb, null, f, a, 0, 4, 4, false);
+ }
+
+ /**
+ * @param sb optional passed StringBuilder instance to be used
+ * @param f the format string of one floating point, i.e. "%10.5f", see {@link java.util.Formatter}
+ * @param a 4x4 matrix in column major order (OpenGL)
+ * @param b 4x4 matrix in column major order (OpenGL)
+ * @return side by side representation
+ */
+ public static StringBuilder matrixToString(StringBuilder sb, String f, FloatBuffer a, FloatBuffer b) {
+ return FloatUtil.matrixToString(sb, null, f, a, 0, b, 0, 4, 4, false);
+ }
+
+ /**
* Creates an instance of PMVMatrix {@link #PMVMatrix(boolean) PMVMatrix(boolean useBackingArray)},
* with <code>useBackingArray = true</code>.
*/
@@ -132,13 +266,16 @@ public class PMVMatrix implements GLMatrixFunc {
glLoadIdentity();
glMatrixMode(GL.GL_TEXTURE);
glLoadIdentity();
- setDirty();
- update();
+ modifiedBits = MODIFIED_ALL;
+ dirtyBits = DIRTY_ALL;
+ requestMask = 0;
+ matrixMode = GL_MODELVIEW;
}
+ /** @see #PMVMatrix(boolean) */
public final boolean usesBackingArray() { return usesBackingArray; }
- public void destroy() {
+ public final void destroy() {
if(null!=projectFloat) {
projectFloat.destroy(); projectFloat=null;
}
@@ -169,170 +306,156 @@ public class PMVMatrix implements GLMatrixFunc {
}
}
-
- public static final boolean isMatrixModeName(final int matrixModeName) {
- switch(matrixModeName) {
- case GL_MODELVIEW_MATRIX:
- case GL_PROJECTION_MATRIX:
- case GL_TEXTURE_MATRIX:
- return true;
- }
- return false;
- }
-
- public static final int matrixModeName2MatrixGetName(final int matrixModeName) {
- switch(matrixModeName) {
- case GL_MODELVIEW:
- return GL_MODELVIEW_MATRIX;
- case GL_PROJECTION:
- return GL_PROJECTION_MATRIX;
- case GL.GL_TEXTURE:
- return GL_TEXTURE_MATRIX;
- default:
- throw new GLException("unsupported matrixName: "+matrixModeName);
- }
- }
-
- public static final boolean isMatrixGetName(final int matrixGetName) {
- switch(matrixGetName) {
- case GL_MATRIX_MODE:
- case GL_MODELVIEW_MATRIX:
- case GL_PROJECTION_MATRIX:
- case GL_TEXTURE_MATRIX:
- return true;
- }
- return false;
- }
-
- public static final int matrixGetName2MatrixModeName(final int matrixGetName) {
- switch(matrixGetName) {
- case GL_MODELVIEW_MATRIX:
- return GL_MODELVIEW;
- case GL_PROJECTION_MATRIX:
- return GL_PROJECTION;
- case GL_TEXTURE_MATRIX:
- return GL.GL_TEXTURE;
- default:
- throw new GLException("unsupported matrixGetName: "+matrixGetName);
- }
- }
-
- public void setDirty() {
- modified = DIRTY_MODELVIEW | DIRTY_PROJECTION | DIRTY_TEXTURE ;
- matrixMode = GL_MODELVIEW;
- }
-
- public int getDirtyBits() {
- return modified;
- }
-
- public boolean isDirty(final int matrixName) {
- boolean res;
- switch(matrixName) {
- case GL_MODELVIEW:
- res = (modified&DIRTY_MODELVIEW)!=0 ;
- break;
- case GL_PROJECTION:
- res = (modified&DIRTY_PROJECTION)!=0 ;
- break;
- case GL.GL_TEXTURE:
- res = (modified&DIRTY_TEXTURE)!=0 ;
- break;
- default:
- throw new GLException("unsupported matrixName: "+matrixName);
- }
- return res;
- }
-
- public boolean isDirty() {
- return modified!=0;
- }
-
- /**
- * Update the derived Mvi, Mvit and Pmv matrices
- * in case Mv or P has changed.
- *
- * @return
- */
- public boolean update() {
- if(0==modified) return false;
-
- final int res = modified;
- if( (res&DIRTY_MODELVIEW)!=0 ) {
- setMviMvit();
- }
- modified=0;
- return res!=0;
- }
-
+
+ /** Returns the current matrix-mode, one of {@link GLMatrixFunc#GL_MODELVIEW GL_MODELVIEW}, {@link GLMatrixFunc#GL_PROJECTION GL_PROJECTION} or {@link GL#GL_TEXTURE GL_TEXTURE}. */
public final int glGetMatrixMode() {
return matrixMode;
}
+ /**
+ * Returns the {@link GLMatrixFunc#GL_TEXTURE_MATRIX texture matrix} (T).
+ * <p>
+ * See <a href="#storageDetails"> matrix storage details</a>.
+ * </p>
+ */
public final FloatBuffer glGetTMatrixf() {
return matrixTex;
}
+ /**
+ * Returns the {@link GLMatrixFunc#GL_PROJECTION_MATRIX projection matrix} (P).
+ * <p>
+ * See <a href="#storageDetails"> matrix storage details</a>.
+ * </p>
+ */
public final FloatBuffer glGetPMatrixf() {
return matrixP;
}
+ /**
+ * Returns the {@link GLMatrixFunc#GL_MODELVIEW_MATRIX modelview matrix} (Mv).
+ * <p>
+ * See <a href="#storageDetails"> matrix storage details</a>.
+ * </p>
+ */
public final FloatBuffer glGetMvMatrixf() {
return matrixMv;
}
- public final FloatBuffer glGetPMvMviMatrixf() {
- usesMviMvit |= 1;
- return matrixPMvMvi;
+ /**
+ * Returns the inverse {@link GLMatrixFunc#GL_MODELVIEW_MATRIX modelview matrix} (Mvi).
+ * <p>
+ * Method enables the Mvi matrix update, and performs it's update w/o clearing the modified bits.
+ * </p>
+ * <p>
+ * See {@link #update()} and <a href="#storageDetails"> matrix storage details</a>.
+ * </p>
+ * @see #update()
+ * @see #disableMviMvitUpdate()
+ */
+ public final FloatBuffer glGetMviMatrixf() {
+ requestMask |= DIRTY_INVERSE_MODELVIEW ;
+ updateImpl(false);
+ return matrixMvi;
}
+ /**
+ * Returns the inverse transposed {@link GLMatrixFunc#GL_MODELVIEW_MATRIX modelview matrix} (Mvit).
+ * <p>
+ * Method enables the Mvit matrix update, and performs it's update w/o clearing the modified bits.
+ * </p>
+ * <p>
+ * See {@link #update()} and <a href="#storageDetails"> matrix storage details</a>.
+ * </p>
+ * @see #update()
+ * @see #disableMviMvitUpdate()
+ */
+ public final FloatBuffer glGetMvitMatrixf() {
+ requestMask |= DIRTY_INVERSE_TRANSPOSED_MODELVIEW ;
+ updateImpl(false);
+ return matrixMvit;
+ }
+
+ /**
+ * Returns 2 matrices within one FloatBuffer: {@link #glGetPMatrixf() P} and {@link #glGetMvMatrixf() Mv}.
+ * <p>
+ * See <a href="#storageDetails"> matrix storage details</a>.
+ * </p>
+ */
public final FloatBuffer glGetPMvMatrixf() {
return matrixPMv;
}
- public final FloatBuffer glGetMviMatrixf() {
- usesMviMvit |= 1;
- return matrixMvi;
+ /**
+ * Returns 3 matrices within one FloatBuffer: {@link #glGetPMatrixf() P}, {@link #glGetMvMatrixf() Mv} and {@link #glGetMviMatrixf() Mvi}.
+ * <p>
+ * Method enables the Mvi matrix update, and performs it's update w/o clearing the modified bits.
+ * </p>
+ * <p>
+ * See {@link #update()} and <a href="#storageDetails"> matrix storage details</a>.
+ * </p>
+ * @see #update()
+ * @see #disableMviMvitUpdate()
+ */
+ public final FloatBuffer glGetPMvMviMatrixf() {
+ requestMask |= DIRTY_INVERSE_MODELVIEW ;
+ updateImpl(false);
+ return matrixPMvMvi;
}
-
+
+ /**
+ * Returns 4 matrices within one FloatBuffer: {@link #glGetPMatrixf() P}, {@link #glGetMvMatrixf() Mv}, {@link #glGetMviMatrixf() Mvi} and {@link #glGetMvitMatrixf() Mvit}.
+ * <p>
+ * Method enables the Mvi and Mvit matrix update, and performs it's update w/o clearing the modified bits.
+ * </p>
+ * <p>
+ * See {@link #update()} and <a href="#storageDetails"> matrix storage details</a>.
+ * </p>
+ * @see #update()
+ * @see #disableMviMvitUpdate()
+ */
public final FloatBuffer glGetPMvMvitMatrixf() {
- usesMviMvit |= 1 | 2;
+ requestMask |= DIRTY_INVERSE_MODELVIEW | DIRTY_INVERSE_TRANSPOSED_MODELVIEW ;
+ updateImpl(false);
return matrixPMvMvit;
}
- public final FloatBuffer glGetMvitMatrixf() {
- usesMviMvit |= 1 | 2;
- return matrixMvit;
- }
-
- /*
- * @return the current matrix
- */
+ /*
+ * @return the matrix of the current matrix-mode
+ */
public final FloatBuffer glGetMatrixf() {
return glGetMatrixf(matrixMode);
}
- /**
- * @param matrixName GL_MODELVIEW, GL_PROJECTION or GL.GL_TEXTURE
- * @return the given matrix
- */
+ /**
+ * @param matrixName Either a matrix-get-name, i.e.
+ * {@link GLMatrixFunc#GL_MODELVIEW_MATRIX GL_MODELVIEW_MATRIX}, {@link GLMatrixFunc#GL_PROJECTION_MATRIX GL_PROJECTION_MATRIX} or {@link GLMatrixFunc#GL_TEXTURE_MATRIX GL_TEXTURE_MATRIX},
+ * or a matrix-mode-name, i.e.
+ * {@link GLMatrixFunc#GL_MODELVIEW GL_MODELVIEW}, {@link GLMatrixFunc#GL_PROJECTION GL_PROJECTION} or {@link GL#GL_TEXTURE GL_TEXTURE}
+ * @return the named matrix
+ */
public final FloatBuffer glGetMatrixf(final int matrixName) {
- if(matrixName==GL_MODELVIEW) {
- return matrixMv;
- } else if(matrixName==GL_PROJECTION) {
- return matrixP;
- } else if(matrixName==GL.GL_TEXTURE) {
- return matrixTex;
- } else {
- throw new GLException("unsupported matrixName: "+matrixName);
- }
+ switch(matrixName) {
+ case GL_MODELVIEW_MATRIX:
+ case GL_MODELVIEW:
+ return matrixMv;
+ case GL_PROJECTION_MATRIX:
+ case GL_PROJECTION:
+ return matrixP;
+ case GL_TEXTURE_MATRIX:
+ case GL.GL_TEXTURE:
+ return matrixTex;
+ default:
+ throw new GLException("unsupported matrixName: "+matrixName);
+ }
}
//
- // MatrixIf
+ // GLMatrixFunc implementation
//
- public void glMatrixMode(final int matrixName) {
+ @Override
+ public final void glMatrixMode(final int matrixName) {
switch(matrixName) {
case GL_MODELVIEW:
case GL_PROJECTION:
@@ -344,27 +467,32 @@ public class PMVMatrix implements GLMatrixFunc {
matrixMode = matrixName;
}
- public void glGetFloatv(int matrixGetName, FloatBuffer params) {
+ @Override
+ public final void glGetFloatv(int matrixGetName, FloatBuffer params) {
int pos = params.position();
if(matrixGetName==GL_MATRIX_MODE) {
params.put((float)matrixMode);
} else {
- FloatBuffer matrix = glGetMatrixf(matrixGetName2MatrixModeName(matrixGetName));
+ FloatBuffer matrix = glGetMatrixf(matrixGetName);
params.put(matrix); // matrix -> params
matrix.reset();
}
params.position(pos);
}
- public void glGetFloatv(int matrixGetName, float[] params, int params_offset) {
+
+ @Override
+ public final void glGetFloatv(int matrixGetName, float[] params, int params_offset) {
if(matrixGetName==GL_MATRIX_MODE) {
params[params_offset]=(float)matrixMode;
} else {
- FloatBuffer matrix = glGetMatrixf(matrixGetName2MatrixModeName(matrixGetName));
+ FloatBuffer matrix = glGetMatrixf(matrixGetName);
matrix.get(params, params_offset, 16); // matrix -> params
matrix.reset();
}
}
- public void glGetIntegerv(int pname, IntBuffer params) {
+
+ @Override
+ public final void glGetIntegerv(int pname, IntBuffer params) {
int pos = params.position();
if(pname==GL_MATRIX_MODE) {
params.put(matrixMode);
@@ -373,7 +501,9 @@ public class PMVMatrix implements GLMatrixFunc {
}
params.position(pos);
}
- public void glGetIntegerv(int pname, int[] params, int params_offset) {
+
+ @Override
+ public final void glGetIntegerv(int pname, int[] params, int params_offset) {
if(pname==GL_MATRIX_MODE) {
params[params_offset]=matrixMode;
} else {
@@ -381,41 +511,46 @@ public class PMVMatrix implements GLMatrixFunc {
}
}
+ @Override
public final void glLoadMatrixf(final float[] values, final int offset) {
int len = values.length-offset;
if(matrixMode==GL_MODELVIEW) {
matrixMv.put(values, offset, len);
matrixMv.reset();
- modified |= DIRTY_MODELVIEW ;
+ dirtyBits |= DIRTY_INVERSE_MODELVIEW | DIRTY_INVERSE_TRANSPOSED_MODELVIEW ;
+ modifiedBits |= MODIFIED_MODELVIEW;
} else if(matrixMode==GL_PROJECTION) {
matrixP.put(values, offset, len);
matrixP.reset();
- modified |= DIRTY_PROJECTION ;
+ modifiedBits |= MODIFIED_PROJECTION;
} else if(matrixMode==GL.GL_TEXTURE) {
matrixTex.put(values, offset, len);
matrixTex.reset();
- modified |= DIRTY_TEXTURE ;
+ modifiedBits |= MODIFIED_TEXTURE;
}
}
+ @Override
public final void glLoadMatrixf(java.nio.FloatBuffer m) {
int spos = m.position();
if(matrixMode==GL_MODELVIEW) {
matrixMv.put(m);
matrixMv.reset();
- modified |= DIRTY_MODELVIEW ;
+ dirtyBits |= DIRTY_INVERSE_MODELVIEW | DIRTY_INVERSE_TRANSPOSED_MODELVIEW ;
+ modifiedBits |= MODIFIED_MODELVIEW;
} else if(matrixMode==GL_PROJECTION) {
matrixP.put(m);
matrixP.reset();
- modified |= DIRTY_PROJECTION ;
+ modifiedBits |= MODIFIED_PROJECTION;
} else if(matrixMode==GL.GL_TEXTURE) {
matrixTex.put(m);
matrixTex.reset();
- modified |= DIRTY_TEXTURE ;
+ modifiedBits |= MODIFIED_TEXTURE;
}
m.position(spos);
}
+ @Override
public final void glPopMatrix() {
float[] stackEntry=null;
if(matrixMode==GL_MODELVIEW) {
@@ -428,6 +563,7 @@ public class PMVMatrix implements GLMatrixFunc {
glLoadMatrixf(stackEntry, 0);
}
+ @Override
public final void glPushMatrix() {
float[] stackEntry = new float[1*16];
if(matrixMode==GL_MODELVIEW) {
@@ -445,49 +581,56 @@ public class PMVMatrix implements GLMatrixFunc {
}
}
+ @Override
public final void glLoadIdentity() {
if(matrixMode==GL_MODELVIEW) {
matrixMv.put(matrixIdent);
matrixMv.reset();
- modified |= DIRTY_MODELVIEW ;
+ dirtyBits |= DIRTY_INVERSE_MODELVIEW | DIRTY_INVERSE_TRANSPOSED_MODELVIEW ;
+ modifiedBits |= MODIFIED_MODELVIEW;
} else if(matrixMode==GL_PROJECTION) {
matrixP.put(matrixIdent);
matrixP.reset();
- modified |= DIRTY_PROJECTION ;
+ modifiedBits |= MODIFIED_PROJECTION;
} else if(matrixMode==GL.GL_TEXTURE) {
matrixTex.put(matrixIdent);
matrixTex.reset();
- modified |= DIRTY_TEXTURE ;
+ modifiedBits |= MODIFIED_TEXTURE;
}
- matrixIdent.reset();
+ matrixIdent.reset();
}
+ @Override
public final void glMultMatrixf(final FloatBuffer m) {
if(matrixMode==GL_MODELVIEW) {
FloatUtil.multMatrixf(matrixMv, m, matrixMv);
- modified |= DIRTY_MODELVIEW ;
+ dirtyBits |= DIRTY_INVERSE_MODELVIEW | DIRTY_INVERSE_TRANSPOSED_MODELVIEW ;
+ modifiedBits |= MODIFIED_MODELVIEW;
} else if(matrixMode==GL_PROJECTION) {
FloatUtil.multMatrixf(matrixP, m, matrixP);
- modified |= DIRTY_PROJECTION ;
+ modifiedBits |= MODIFIED_PROJECTION;
} else if(matrixMode==GL.GL_TEXTURE) {
FloatUtil.multMatrixf(matrixTex, m, matrixTex);
- modified |= DIRTY_TEXTURE ;
+ modifiedBits |= MODIFIED_TEXTURE;
}
}
- public void glMultMatrixf(float[] m, int m_offset) {
+ @Override
+ public final void glMultMatrixf(float[] m, int m_offset) {
if(matrixMode==GL_MODELVIEW) {
FloatUtil.multMatrixf(matrixMv, m, m_offset, matrixMv);
- modified |= DIRTY_MODELVIEW ;
+ dirtyBits |= DIRTY_INVERSE_MODELVIEW | DIRTY_INVERSE_TRANSPOSED_MODELVIEW ;
+ modifiedBits |= MODIFIED_MODELVIEW;
} else if(matrixMode==GL_PROJECTION) {
FloatUtil.multMatrixf(matrixP, m, m_offset, matrixP);
- modified |= DIRTY_PROJECTION ;
+ modifiedBits |= MODIFIED_PROJECTION;
} else if(matrixMode==GL.GL_TEXTURE) {
FloatUtil.multMatrixf(matrixTex, m, m_offset, matrixTex);
- modified |= DIRTY_TEXTURE ;
+ modifiedBits |= MODIFIED_TEXTURE;
}
}
+ @Override
public final void glTranslatef(final float x, final float y, final float z) {
// Translation matrix:
// 1 0 0 x
@@ -500,6 +643,7 @@ public class PMVMatrix implements GLMatrixFunc {
glMultMatrixf(matrixTrans, 0);
}
+ @Override
public final void glRotatef(final float angdeg, float x, float y, float z) {
final float angrad = angdeg * (float) Math.PI / 180.0f;
final float c = (float)Math.cos(angrad);
@@ -536,6 +680,7 @@ public class PMVMatrix implements GLMatrixFunc {
glMultMatrixf(matrixRot, 0);
}
+ @Override
public final void glScalef(final float x, final float y, final float z) {
// Scale matrix:
// x 0 0 0
@@ -549,6 +694,7 @@ public class PMVMatrix implements GLMatrixFunc {
glMultMatrixf(matrixScale, 0);
}
+ @Override
public final void glOrthof(final float left, final float right, final float bottom, final float top, final float zNear, final float zFar) {
// Ortho matrix:
// 2/dx 0 0 tx
@@ -572,14 +718,7 @@ public class PMVMatrix implements GLMatrixFunc {
glMultMatrixf(matrixOrtho, 0);
}
- public final void gluPerspective(final float fovy, final float aspect, final float zNear, final float zFar) {
- float top=(float)Math.tan(fovy*((float)Math.PI)/360.0f)*zNear;
- float bottom=-1.0f*top;
- float left=aspect*bottom;
- float right=aspect*top;
- glFrustumf(left, right, bottom, top, zNear, zFar);
- }
-
+ @Override
public final void glFrustumf(final float left, final float right, final float bottom, final float top, final float zNear, final float zFar) {
if(zNear<=0.0f||zFar<0.0f) {
throw new GLException("GL_INVALID_VALUE: zNear and zFar must be positive, and zNear>0");
@@ -614,14 +753,33 @@ public class PMVMatrix implements GLMatrixFunc {
glMultMatrixf(matrixFrustum, 0);
}
- public void gluLookAt(float eyex, float eyey, float eyez,
+ //
+ // Extra functionality
+ //
+
+ /**
+ * {@link #glMultMatrixf(FloatBuffer) Multiply} the {@link #glGetMatrixMode() current matrix} with the perspective/frustum matrix.
+ */
+ public final void gluPerspective(final float fovy, final float aspect, final float zNear, final float zFar) {
+ float top=(float)Math.tan(fovy*((float)Math.PI)/360.0f)*zNear;
+ float bottom=-1.0f*top;
+ float left=aspect*bottom;
+ float right=aspect*top;
+ glFrustumf(left, right, bottom, top, zNear, zFar);
+ }
+
+ /**
+ * {@link #glMultMatrixf(FloatBuffer) Multiply} and {@link #glTranslatef(float, float, float) translate} the {@link #glGetMatrixMode() current matrix}
+ * with the eye, object and orientation.
+ */
+ public final void gluLookAt(float eyex, float eyey, float eyez,
float centerx, float centery, float centerz,
float upx, float upy, float upz) {
projectFloat.gluLookAt(this, eyex, eyey, eyez, centerx, centery, centerz, upx, upy, upz);
}
/**
- * Uses this instance {@link #glGetMvMatrixf()} and {@link #glGetPMatrixf()}
+ * Map object coordinates to window coordinates.
*
* @param objx
* @param objy
@@ -632,7 +790,7 @@ public class PMVMatrix implements GLMatrixFunc {
* @param win_pos_offset
* @return
*/
- public boolean gluProject(float objx, float objy, float objz,
+ public final boolean gluProject(float objx, float objy, float objz,
int[] viewport, int viewport_offset,
float[] win_pos, int win_pos_offset ) {
if(usesBackingArray) {
@@ -651,7 +809,7 @@ public class PMVMatrix implements GLMatrixFunc {
}
/**
- * Uses this instance {@link #glGetMvMatrixf()} and {@link #glGetPMatrixf()}
+ * Map window coordinates to object coordinates.
*
* @param winx
* @param winy
@@ -680,11 +838,189 @@ public class PMVMatrix implements GLMatrixFunc {
}
}
- public void gluPickMatrix(float x, float y,
+ public final void gluPickMatrix(float x, float y,
float deltaX, float deltaY,
int[] viewport, int viewport_offset) {
projectFloat.gluPickMatrix(this, x, y, deltaX, deltaY, viewport, viewport_offset);
}
+
+ public StringBuilder toString(StringBuilder sb, String f) {
+ if(null == sb) {
+ sb = new StringBuilder();
+ }
+ final boolean mviDirty = 0 != (DIRTY_INVERSE_MODELVIEW & dirtyBits);
+ final boolean mvitDirty = 0 != (DIRTY_INVERSE_TRANSPOSED_MODELVIEW & dirtyBits);
+ final boolean mviReq = 0 != (DIRTY_INVERSE_MODELVIEW & requestMask);
+ final boolean mvitReq = 0 != (DIRTY_INVERSE_TRANSPOSED_MODELVIEW & requestMask);
+ final boolean modP = 0 != ( MODIFIED_PROJECTION & modifiedBits );
+ final boolean modMv = 0 != ( MODIFIED_MODELVIEW & modifiedBits );
+ final boolean modT = 0 != ( MODIFIED_TEXTURE & modifiedBits );
+
+ sb.append("PMVMatrix[backingArray ").append(this.usesBackingArray());
+ sb.append(", modified[P ").append(modP).append(", Mv ").append(modMv).append(", T ").append(modT);
+ sb.append("], dirty/req[Mvi ").append(mviDirty).append("/").append(mviReq).append(", Mvit ").append(mvitDirty).append("/").append(mvitReq);
+ sb.append("], Projection").append(Platform.NEWLINE);
+ matrixToString(sb, f, matrixP);
+ sb.append(", Modelview").append(Platform.NEWLINE);
+ matrixToString(sb, f, matrixMv);
+ sb.append(", Texture").append(Platform.NEWLINE);
+ matrixToString(sb, f, matrixTex);
+ if( 0 != ( requestMask & DIRTY_INVERSE_MODELVIEW ) ) {
+ sb.append(", Inverse Modelview").append(Platform.NEWLINE);
+ matrixToString(sb, f, matrixMvi);
+ }
+ if( 0 != ( requestMask & DIRTY_INVERSE_TRANSPOSED_MODELVIEW ) ) {
+ sb.append(", Inverse Transposed Modelview").append(Platform.NEWLINE);
+ matrixToString(sb, f, matrixMvit);
+ }
+ sb.append("]");
+ return sb;
+ }
+
+ public String toString() {
+ return toString(null, "%10.5f").toString();
+ }
+
+ /**
+ * Returns the modified bits due to mutable operations..
+ * <p>
+ * A modified bit is set, if the corresponding matrix had been modified by a mutable operation
+ * since last {@link #update()} or {@link #getModifiedBits(boolean) getModifiedBits(true)} call.
+ * </p>
+ * @param clear if true, clears the modified bits, otherwise leaves them untouched.
+ *
+ * @see #MODIFIED_PROJECTION
+ * @see #MODIFIED_MODELVIEW
+ * @see #MODIFIED_TEXTURE
+ */
+ public final int getModifiedBits(boolean clear) {
+ final int r = modifiedBits;
+ if(clear) {
+ modifiedBits = 0;
+ }
+ return r;
+ }
+
+ /**
+ * Returns the dirty bits due to mutable operations.
+ * <p>
+ * A dirty bit is set , if the corresponding matrix had been modified by a mutable operation
+ * since last {@link #update()} call. The latter clears the dirty state only if the dirty matrix (Mvi or Mvit)
+ * has been requested by one of the {@link #glGetMviMatrixf() Mvi get} or {@link #glGetMvitMatrixf() Mvit get} methods.
+ * </p>
+ *
+ * @deprecated Function is exposed for debugging purposes only.
+ * @see #DIRTY_INVERSE_MODELVIEW
+ * @see #DIRTY_INVERSE_TRANSPOSED_MODELVIEW
+ * @see #glGetMviMatrixf()
+ * @see #glGetMvitMatrixf()
+ * @see #glGetPMvMviMatrixf()
+ * @see #glGetPMvMvitMatrixf()
+ */
+ public final int getDirtyBits() {
+ return dirtyBits;
+ }
+
+ /**
+ * Returns the request bit mask, which uses bit values equal to the dirty mask.
+ * <p>
+ * The request bit mask is set by one of the {@link #glGetMviMatrixf() Mvi get} or {@link #glGetMvitMatrixf() Mvit get} methods.
+ * </p>
+ *
+ * @deprecated Function is exposed for debugging purposes only.
+ * @see #disableMviMvitUpdate()
+ * @see #DIRTY_INVERSE_MODELVIEW
+ * @see #DIRTY_INVERSE_TRANSPOSED_MODELVIEW
+ * @see #glGetMviMatrixf()
+ * @see #glGetMvitMatrixf()
+ * @see #glGetPMvMviMatrixf()
+ * @see #glGetPMvMvitMatrixf()
+ */
+ public final int getRequestMask() {
+ return requestMask;
+ }
+
+
+ /**
+ * Disable {@link #update()} of the Mvi and Mvit matrix
+ * after it has been enabled by one of the {@link #glGetMviMatrixf() Mvi get} or {@link #glGetMvitMatrixf() Mvit get} methods.
+ * <p>
+ * This cleans the request bit mask used internally.
+ * </p>
+ * <p>
+ * Function may be useful to disable subsequent Mvi and Mvit updates if no more required.
+ * </p>
+ *
+ * @see #glGetMviMatrixf()
+ * @see #glGetMvitMatrixf()
+ * @see #glGetPMvMviMatrixf()
+ * @see #glGetPMvMvitMatrixf()
+ * @see #getRequestMask()
+ */
+ public final void disableMviMvitUpdate() {
+ requestMask &= ~DIRTY_ALL;
+ }
+
+ /**
+ * Update the derived {@link #glGetMviMatrixf() inverse modelview (Mvi)}
+ * and {@link #glGetMvitMatrixf() inverse transposed modelview (Mvit)} matrices
+ * <b>if</b> they are dirty <b>and</b> their usage/update has been requested
+ * by one of the {@link #glGetMviMatrixf() Mvi get} or {@link #glGetMvitMatrixf() Mvit get} methods.
+ * <p>
+ * The Mvi and Mvit matrices are considered dirty, if their corresponding
+ * {@link #glGetMvMatrixf() Mv matrix} has been modified since their last update.
+ * </p>
+ * <p>
+ * Method should be called manually in case mutable operations has been called
+ * and caller operates on already fetched references, i.e. not calling
+ * {@link #glGetMviMatrixf() Mvi get} or {@link #glGetMvitMatrixf() Mvit get} etc anymore.
+ * </p>
+ * <p>
+ * This method clears the modified bits like {@link #getModifiedBits(boolean) getModifiedBits(true)},
+ * which are set by any mutable operation. The modified bits have no impact
+ * on this method, but the return value.
+ * </p>
+ *
+ * @return true if any matrix has been modified since last update call or
+ * if the derived matrices Mvi and Mvit were updated, otherwise false.
+ * In other words, method returns true if any matrix used by the caller must be updated,
+ * e.g. uniforms in a shader program.
+ *
+ * @see #getModifiedBits(boolean)
+ * @see #MODIFIED_PROJECTION
+ * @see #MODIFIED_MODELVIEW
+ * @see #MODIFIED_TEXTURE
+ * @see #DIRTY_INVERSE_MODELVIEW
+ * @see #DIRTY_INVERSE_TRANSPOSED_MODELVIEW
+ * @see #glGetMviMatrixf()
+ * @see #glGetMvitMatrixf()
+ * @see #glGetPMvMviMatrixf()
+ * @see #glGetPMvMvitMatrixf()
+ * @see #disableMviMvitUpdate()
+ */
+ public final boolean update() {
+ return updateImpl(true);
+ }
+ private final boolean updateImpl(boolean clearModBits) {
+ final boolean mod = 0 != modifiedBits;
+ if(clearModBits) {
+ modifiedBits = 0;
+ }
+
+ if( 0 == ( dirtyBits & requestMask ) ) {
+ return mod; // nothing requested which may have been dirty
+ }
+
+ if(nioBackupArraySupported>=0) {
+ try {
+ nioBackupArraySupported = 1;
+ return setMviMvitNIOBackupArray() || mod;
+ } catch(UnsupportedOperationException uoe) {
+ nioBackupArraySupported = -1;
+ }
+ }
+ return setMviMvitNIODirectAccess() || mod;
+ }
//
// private
@@ -692,27 +1028,18 @@ public class PMVMatrix implements GLMatrixFunc {
private int nioBackupArraySupported = 0; // -1 not supported, 0 - TBD, 1 - supported
private final String msgCantComputeInverse = "Invalid source Mv matrix, can't compute inverse";
- private final void setMviMvit() {
- if( 0 != (usesMviMvit & 1) ) {
- if(nioBackupArraySupported>=0) {
- try {
- setMviMvitNIOBackupArray();
- nioBackupArraySupported = 1;
- return;
- } catch(UnsupportedOperationException uoe) {
- nioBackupArraySupported = -1;
- }
- }
- setMviMvitNIODirectAccess();
- }
- }
- private final void setMviMvitNIOBackupArray() {
+ private final boolean setMviMvitNIOBackupArray() {
final float[] _matrixMvi = matrixMvi.array();
final int _matrixMviOffset = matrixMvi.position();
- if(!projectFloat.gluInvertMatrixf(matrixMv.array(), matrixMv.position(), _matrixMvi, _matrixMviOffset)) {
- throw new GLException(msgCantComputeInverse);
+ boolean res = false;
+ if( 0 != ( dirtyBits & DIRTY_INVERSE_MODELVIEW ) ) { // only if dirt; always requested at this point, see update()
+ if(!projectFloat.gluInvertMatrixf(matrixMv.array(), matrixMv.position(), _matrixMvi, _matrixMviOffset)) {
+ throw new GLException(msgCantComputeInverse);
+ }
+ dirtyBits &= ~DIRTY_INVERSE_MODELVIEW;
+ res = true;
}
- if( 0 != (usesMviMvit & 2) ) {
+ if( 0 != ( requestMask & ( dirtyBits & DIRTY_INVERSE_TRANSPOSED_MODELVIEW ) ) ) { // only if requested & dirty
// transpose matrix
final float[] _matrixMvit = matrixMvit.array();
final int _matrixMvitOffset = matrixMvit.position();
@@ -721,34 +1048,43 @@ public class PMVMatrix implements GLMatrixFunc {
_matrixMvit[_matrixMvitOffset+j+i*4] = _matrixMvi[_matrixMviOffset+i+j*4];
}
}
- }
+ dirtyBits &= ~DIRTY_INVERSE_TRANSPOSED_MODELVIEW;
+ res = true;
+ }
+ return res;
}
- private final void setMviMvitNIODirectAccess() {
- if(!projectFloat.gluInvertMatrixf(matrixMv, matrixMvi)) {
- throw new GLException(msgCantComputeInverse);
+ private final boolean setMviMvitNIODirectAccess() {
+ boolean res = false;
+ if( 0 != ( dirtyBits & DIRTY_INVERSE_MODELVIEW ) ) { // only if dirt; always requested at this point, see update()
+ if(!projectFloat.gluInvertMatrixf(matrixMv, matrixMvi)) {
+ throw new GLException(msgCantComputeInverse);
+ }
+ dirtyBits &= ~DIRTY_INVERSE_MODELVIEW;
+ res = true;
}
- if( 0 != (usesMviMvit & 2) ) {
+ if( 0 != ( requestMask & ( dirtyBits & DIRTY_INVERSE_TRANSPOSED_MODELVIEW ) ) ) { // only if requested & dirty
// transpose matrix
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
matrixMvit.put(j+i*4, matrixMvi.get(i+j*4));
}
}
- }
+ dirtyBits &= ~DIRTY_INVERSE_TRANSPOSED_MODELVIEW;
+ res = true;
+ }
+ return res;
}
+ protected final float[] matrixBufferArray;
protected final boolean usesBackingArray;
protected Buffer matrixBuffer;
protected FloatBuffer matrixIdent, matrixPMvMvit, matrixPMvMvi, matrixPMv, matrixP, matrixTex, matrixMv, matrixMvi, matrixMvit;
protected float[] matrixMult, matrixTrans, matrixRot, matrixScale, matrixOrtho, matrixFrustum, vec3f;
protected List<float[]> matrixTStack, matrixPStack, matrixMvStack;
protected int matrixMode = GL_MODELVIEW;
- protected int modified = 0;
- protected int usesMviMvit = 0; // 0 - none, 1 - Mvi, 2 - Mvit, 3 - MviMvit (ofc no Mvit w/o Mvi!)
+ protected int modifiedBits = MODIFIED_ALL;
+ protected int dirtyBits = DIRTY_ALL; // contains the dirty bits, i.e. hinting for update operation
+ protected int requestMask = 0; // may contain the requested dirty bits: DIRTY_INVERSE_MODELVIEW | DIRTY_INVERSE_TRANSPOSED_MODELVIEW
protected ProjectFloat projectFloat;
-
- public static final int DIRTY_MODELVIEW = 1 << 0;
- public static final int DIRTY_PROJECTION = 1 << 1;
- public static final int DIRTY_TEXTURE = 1 << 2;
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderCode.java b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderCode.java
index f6b686d..e6dde32 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderCode.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderCode.java
@@ -46,6 +46,7 @@ import java.util.Set;
import javax.media.opengl.GL;
import javax.media.opengl.GL2ES2;
import javax.media.opengl.GLES2;
+import javax.media.opengl.GLContext;
import javax.media.opengl.GLException;
import jogamp.opengl.Debug;
@@ -806,6 +807,35 @@ public class ShaderCode {
}
}
+ // Shall we use: #ifdef GL_FRAGMENT_PRECISION_HIGH .. #endif for using highp in fragment shader if avail ?
+ /** {@value #es2_default_precision_vp} */
+ public static final String es2_default_precision_vp = "\nprecision highp float;\nprecision highp int;\n";
+ /** {@value #es2_default_precision_fp} */
+ public static final String es2_default_precision_fp = "\nprecision mediump float;\nprecision mediump int;\n/*precision lowp sampler2D;*/\n";
+
+ /**
+ * Default customization of this shader source code.
+ * <p>
+ * Note: The shader source to be edit must be created using a mutable StringBuilder.
+ * </p>
+ * @param gl a GL context, which must have been made current once
+ * @param preludeVersion if true {@link GLContext#getGLSLVersionString()} is preluded, otherwise not.
+ * @param es2DefaultPrecision optional default precision source code line(s) preluded if not null and if {@link GL#isGLES()}.
+ * You may use {@link #es2_default_precision_fp} for fragment shader and {@link #es2_default_precision_vp} for vertex shader.
+ * @return the index after the inserted data, maybe 0 if nothing has be inserted.
+ */
+ public final int defaultShaderCustomization(GL2ES2 gl, boolean preludeVersion, String es2DefaultPrecision) {
+ int pos = 0;
+ if(preludeVersion) {
+ final String glslVersion_prelude = gl.getContext().getGLSLVersionString();
+ pos = insertShaderSource(0, pos, glslVersion_prelude);
+ }
+ if( gl.isGLES() && null != es2DefaultPrecision ) {
+ pos = insertShaderSource(0, pos, es2DefaultPrecision);
+ }
+ return pos;
+ }
+
//----------------------------------------------------------------------
// Internals only below this point
//
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderProgram.java b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderProgram.java
index 14ea7d2..9cade1e 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderProgram.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderProgram.java
@@ -50,6 +50,7 @@ public class ShaderProgram {
return programInUse;
}
+ /** Returns the shader program name, which is non zero if valid. */
public int program() { return shaderProgram; }
/**
@@ -96,9 +97,9 @@ public class ShaderProgram {
}
allShaderCode.clear();
attachedShaderCode.clear();
- if(0<=shaderProgram) {
+ if( 0 != shaderProgram ) {
gl.glDeleteProgram(shaderProgram);
- shaderProgram=-1;
+ shaderProgram=0;
}
}
@@ -140,14 +141,17 @@ public class ShaderProgram {
//
/**
- * Creates the empty GL program object using {@link GL2ES2#glCreateProgram()}
+ * Creates the empty GL program object using {@link GL2ES2#glCreateProgram()},
+ * if not already created.
*
* @param gl
+ * @return true if shader program is valid, i.e. not zero
*/
- public synchronized final void init(GL2ES2 gl) {
- if(0>shaderProgram) {
+ public synchronized final boolean init(GL2ES2 gl) {
+ if( 0 == shaderProgram ) {
shaderProgram = gl.glCreateProgram();
}
+ return 0 != shaderProgram;
}
/**
@@ -158,12 +162,12 @@ public class ShaderProgram {
* @return true if the shader was successfully added, false if compilation failed.
*/
public synchronized boolean add(GL2ES2 gl, ShaderCode shaderCode, PrintStream verboseOut) {
- init(gl);
+ if( !init(gl) ) { return false; }
if( allShaderCode.add(shaderCode) ) {
- if(!shaderCode.compile(gl, verboseOut)) {
+ if( !shaderCode.compile(gl, verboseOut) ) {
return false;
}
- if(attachedShaderCode.add(shaderCode)) {
+ if( attachedShaderCode.add(shaderCode) ) {
ShaderUtil.attachShader(gl, shaderProgram, shaderCode.shader());
}
}
@@ -190,9 +194,7 @@ public class ShaderProgram {
* @see ShaderState#glResetAllVertexAttributes
*/
public synchronized boolean replaceShader(GL2ES2 gl, ShaderCode oldShader, ShaderCode newShader, PrintStream verboseOut) {
- init(gl);
-
- if(!newShader.compile(gl, verboseOut)) {
+ if(!init(gl) || !newShader.compile(gl, verboseOut)) {
return false;
}
@@ -235,11 +237,15 @@ public class ShaderProgram {
* @see #init(GL2ES2)
*/
public synchronized boolean link(GL2ES2 gl, PrintStream verboseOut) {
- init(gl);
+ if( !init(gl) ) {
+ programLinked = false; // mark unlinked due to user attempt to [re]link
+ return false;
+ }
for(Iterator<ShaderCode> iter=allShaderCode.iterator(); iter.hasNext(); ) {
final ShaderCode shaderCode = iter.next();
if(!shaderCode.compile(gl, verboseOut)) {
+ programLinked = false; // mark unlinked due to user attempt to [re]link
return false;
}
if(attachedShaderCode.add(shaderCode)) {
@@ -295,13 +301,16 @@ public class ShaderProgram {
public synchronized void useProgram(GL2ES2 gl, boolean on) {
if(!programLinked) { throw new GLException("Program is not linked"); }
if(programInUse==on) { return; }
- gl.glUseProgram(on?shaderProgram:0);
+ if( 0 == shaderProgram ) {
+ on = false;
+ }
+ gl.glUseProgram( on ? shaderProgram : 0 );
programInUse = on;
}
protected boolean programLinked = false;
protected boolean programInUse = false;
- protected int shaderProgram=-1;
+ protected int shaderProgram = 0; // non zero is valid!
protected HashSet<ShaderCode> allShaderCode = new HashSet<ShaderCode>();
protected HashSet<ShaderCode> attachedShaderCode = new HashSet<ShaderCode>();
protected int id = -1;
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderState.java b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderState.java
index 62082aa..ff8982d 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderState.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderState.java
@@ -42,9 +42,20 @@ import javax.media.opengl.GLUniformData;
import jogamp.opengl.Debug;
import com.jogamp.common.os.Platform;
-import com.jogamp.common.util.IntObjectHashMap;
import com.jogamp.opengl.util.GLArrayDataEditable;
+/**
+ * ShaderState allows to sharing data between shader programs,
+ * while updating the attribute and uniform locations when switching.
+ * <p>
+ * This allows seamless switching of programs using <i>almost</i> same data
+ * but performing different artifacts.
+ * </p>
+ * <p>
+ * A {@link #useProgram(GL2ES2, boolean) used} ShaderState is attached to the current GL context
+ * and can be retrieved via {@link #getShaderState(GL)}.
+ * </p>
+ */
public class ShaderState {
public static final boolean DEBUG = Debug.isPropertyDefined("jogl.debug.GLSLState", true);
private static final String currentStateKey = "jogamp.opengl.glsl.ShaderState" ;
@@ -54,7 +65,7 @@ public class ShaderState {
public boolean verbose() { return verbose; }
- public void setVerbose(boolean v) { verbose=v; }
+ public void setVerbose(boolean v) { verbose = DEBUG || v; }
/**
* Fetches the current shader state from this thread (TLS) current GLContext
@@ -123,25 +134,6 @@ public class ShaderState {
}
/**
- * Returns the attached user object for the given name to this ShaderState.
- */
- public final Object getAttachedObject(int name) {
- return attachedObjectsByInt.get(name);
- }
-
- /**
- * Attach user object for the given name to this ShaderState.
- * Returns the previously set object or null.
- */
- public final Object attachObject(int name, Object obj) {
- return attachedObjectsByInt.put(name, obj);
- }
-
- public final Object detachObject(int name) {
- return attachedObjectsByInt.remove(name);
- }
-
- /**
* Turns the shader program on or off.<br>
* Puts this ShaderState to to the thread local storage (TLS),
* if <code>on</code> is <code>true</code>.
@@ -200,25 +192,29 @@ public class ShaderState {
* <p>Use program, {@link #useProgram(GL2ES2, boolean)},
* if <code>enable</code> is <code>true</code>.</p>
*
+ * @return true if shader program was attached, otherwise false (already attached)
+ *
* @throws GLException if program was not linked and linking fails
*/
- public synchronized void attachShaderProgram(GL2ES2 gl, ShaderProgram prog, boolean enable) throws GLException {
- if(DEBUG) {
+ public synchronized boolean attachShaderProgram(GL2ES2 gl, ShaderProgram prog, boolean enable) throws GLException {
+ if(verbose) {
int curId = (null!=shaderProgram)?shaderProgram.id():-1;
int newId = (null!=prog)?prog.id():-1;
- System.err.println("Info: attachShaderProgram: "+curId+" -> "+newId+" (enable: "+enable+")\n\t"+shaderProgram+"\n\t"+prog);
- if(verbose) {
- Throwable tX = new Throwable("Info: attachShaderProgram: Trace");
- tX.printStackTrace();
- }
+ System.err.println("ShaderState: attachShaderProgram: "+curId+" -> "+newId+" (enable: "+enable+")\n\t"+shaderProgram+"\n\t"+prog);
+ if(DEBUG) {
+ Thread.dumpStack();
+ }
}
if(null!=shaderProgram) {
if(shaderProgram.equals(prog)) {
- // nothing to do ..
- if(DEBUG) {
- System.err.println("Info: attachShaderProgram: NOP: equal id: "+shaderProgram.id());
+ if(enable) {
+ useProgram(gl, true);
+ }
+ // nothing else to do ..
+ if(verbose) {
+ System.err.println("ShaderState: attachShaderProgram: No switch, equal id: "+shaderProgram.id()+", enabling "+enable);
}
- return;
+ return false;
}
if(shaderProgram.inUse()) {
if(null != prog && enable) {
@@ -248,6 +244,7 @@ public class ShaderState {
if(DEBUG) {
System.err.println("Info: attachShaderProgram: END");
}
+ return true;
}
public ShaderProgram shaderProgram() { return shaderProgram; }
@@ -262,7 +259,6 @@ public class ShaderState {
public synchronized void destroy(GL2ES2 gl) {
release(gl, true, true, true);
attachedObjectsByString.clear();
- attachedObjectsByInt.clear();
}
/**
@@ -437,11 +433,13 @@ public class ShaderState {
Integer idx = new Integer(location);
activeAttribLocationMap.put(name, idx);
if(DEBUG) {
- System.err.println("Info: glGetAttribLocation: "+name+", loc: "+location);
+ System.err.println("ShaderState: glGetAttribLocation: "+name+", loc: "+location);
}
} else if(verbose) {
- Throwable tX = new Throwable("Info: glGetAttribLocation failed, no location for: "+name+", loc: "+location);
- tX.printStackTrace();
+ System.err.println("ShaderState: glGetAttribLocation failed, no location for: "+name+", loc: "+location);
+ if(DEBUG) {
+ Thread.dumpStack();
+ }
}
}
return location;
@@ -498,14 +496,16 @@ public class ShaderState {
location = getAttribLocation(gl, name);
if(0>location) {
if(verbose) {
- Throwable tX = new Throwable("Info: glEnableVertexAttribArray failed, no index for: "+name);
- tX.printStackTrace();
+ System.err.println("ShaderState: glEnableVertexAttribArray failed, no index for: "+name);
+ if(DEBUG) {
+ Thread.dumpStack();
+ }
}
return false;
}
}
if(DEBUG) {
- System.err.println("Info: glEnableVertexAttribArray: "+name+", loc: "+location);
+ System.err.println("ShaderState: glEnableVertexAttribArray: "+name+", loc: "+location);
}
gl.glEnableVertexAttribArray(location);
return true;
@@ -571,14 +571,16 @@ public class ShaderState {
location = getAttribLocation(gl, name);
if(0>location) {
if(verbose) {
- Throwable tX = new Throwable("Info: glDisableVertexAttribArray failed, no index for: "+name);
- tX.printStackTrace();
+ System.err.println("ShaderState: glDisableVertexAttribArray failed, no index for: "+name);
+ if(DEBUG) {
+ Thread.dumpStack();
+ }
}
return false;
}
}
if(DEBUG) {
- System.err.println("Info: glDisableVertexAttribArray: "+name);
+ System.err.println("ShaderState: glDisableVertexAttribArray: "+name);
}
gl.glDisableVertexAttribArray(location);
return true;
@@ -660,7 +662,7 @@ public class ShaderState {
if(0 <= location) {
// only pass the data, if the attribute exists in the current shader
if(DEBUG) {
- System.err.println("Info: glVertexAttribPointer: "+data);
+ System.err.println("ShaderState: glVertexAttribPointer: "+data);
}
gl.glVertexAttribPointer(data);
return true;
@@ -740,9 +742,11 @@ public class ShaderState {
if( attribute.isVBO() ) {
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, attribute.getVBOName());
- }
-
- gl.glVertexAttribPointer(attribute);
+ gl.glVertexAttribPointer(attribute);
+ gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
+ } else {
+ gl.glVertexAttribPointer(attribute);
+ }
}
}
@@ -764,8 +768,8 @@ public class ShaderState {
if(!shaderProgram.linked()) throw new GLException("Program is not linked");
activeAttribLocationMap.clear();
- for(Iterator<GLArrayData> iter = managedAttributes.iterator(); iter.hasNext(); ) {
- iter.next().setLocation(-1);
+ for(int i=0; i<managedAttributes.size(); i++) {
+ ((GLArrayData)managedAttributes.get(i)).setLocation(-1);
}
for(Iterator<GLArrayData> iter = activeAttribDataMap.values().iterator(); iter.hasNext(); ) {
relocateAttribute(gl, iter.next());
@@ -778,7 +782,7 @@ public class ShaderState {
final int loc = attribute.getLocation();
if(0<=loc) {
- this.bindAttribLocation(gl, loc, name);
+ bindAttribLocation(gl, loc, name);
if(isVertexAttribArrayEnabled(name)) {
// enable attrib, VBO and pass location/data
@@ -787,9 +791,11 @@ public class ShaderState {
if( attribute.isVBO() ) {
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, attribute.getVBOName());
- }
-
- gl.glVertexAttribPointer(attribute);
+ gl.glVertexAttribPointer(attribute);
+ gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
+ } else {
+ gl.glVertexAttribPointer(attribute);
+ }
}
}
@@ -872,8 +878,10 @@ public class ShaderState {
Integer idx = new Integer(location);
activeUniformLocationMap.put(name, idx);
} else if(verbose) {
- Throwable tX = new Throwable("Info: glUniform failed, no location for: "+name+", index: "+location);
- tX.printStackTrace();
+ System.err.println("ShaderState: glUniform failed, no location for: "+name+", index: "+location);
+ if(DEBUG) {
+ Thread.dumpStack();
+ }
}
}
return location;
@@ -936,7 +944,7 @@ public class ShaderState {
if(0<=location) {
// only pass the data, if the uniform exists in the current shader
if(DEBUG) {
- System.err.println("Info: glUniform: "+data);
+ System.err.println("ShaderState: glUniform: "+data);
}
gl.glUniform(data);
}
@@ -985,7 +993,7 @@ public class ShaderState {
}
}
- public StringBuilder toString(StringBuilder sb) {
+ public StringBuilder toString(StringBuilder sb, boolean alsoUnlocated) {
if(null==sb) {
sb = new StringBuilder();
}
@@ -1008,19 +1016,31 @@ public class ShaderState {
}
sb.append(Platform.getNewline()).append(" ],").append(" activeAttributes [");
for(Iterator<GLArrayData> iter = activeAttribDataMap.values().iterator(); iter.hasNext(); ) {
- sb.append(Platform.getNewline()).append(" ").append(iter.next());
+ final GLArrayData ad = iter.next();
+ if( alsoUnlocated || 0 <= ad.getLocation() ) {
+ sb.append(Platform.getNewline()).append(" ").append(ad);
+ }
}
sb.append(Platform.getNewline()).append(" ],").append(" managedAttributes [");
for(Iterator<GLArrayData> iter = managedAttributes.iterator(); iter.hasNext(); ) {
- sb.append(Platform.getNewline()).append(" ").append(iter.next());
+ final GLArrayData ad = iter.next();
+ if( alsoUnlocated || 0 <= ad.getLocation() ) {
+ sb.append(Platform.getNewline()).append(" ").append(ad);
+ }
}
sb.append(Platform.getNewline()).append(" ],").append(" activeUniforms [");
for(Iterator<GLUniformData> iter=activeUniformDataMap.values().iterator(); iter.hasNext(); ) {
- sb.append(Platform.getNewline()).append(" ").append(iter.next());
+ final GLUniformData ud = iter.next();
+ if( alsoUnlocated || 0 <= ud.getLocation() ) {
+ sb.append(Platform.getNewline()).append(" ").append(ud);
+ }
}
sb.append(Platform.getNewline()).append(" ],").append(" managedUniforms [");
for(Iterator<GLUniformData> iter = managedUniforms.iterator(); iter.hasNext(); ) {
- sb.append(Platform.getNewline()).append(" ").append(iter.next());
+ final GLUniformData ud = iter.next();
+ if( alsoUnlocated || 0 <= ud.getLocation() ) {
+ sb.append(Platform.getNewline()).append(" ").append(ud);
+ }
}
sb.append(Platform.getNewline()).append(" ]").append(Platform.getNewline()).append("]");
return sb;
@@ -1028,10 +1048,10 @@ public class ShaderState {
@Override
public String toString() {
- return toString(null).toString();
+ return toString(null, DEBUG).toString();
}
- private boolean verbose = DEBUG ? true : false;
+ private boolean verbose = DEBUG;
private ShaderProgram shaderProgram=null;
private HashMap<String, Boolean> activedAttribEnabledMap = new HashMap<String, Boolean>();
@@ -1044,7 +1064,6 @@ public class ShaderState {
private ArrayList<GLUniformData> managedUniforms = new ArrayList<GLUniformData>();
private HashMap<String, Object> attachedObjectsByString = new HashMap<String, Object>();
- private IntObjectHashMap attachedObjectsByInt = new IntObjectHashMap();
private boolean resetAllShaderData = false;
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderUtil.java b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderUtil.java
index 40c0524..5afc5e3 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderUtil.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderUtil.java
@@ -159,16 +159,19 @@ public class ShaderUtil {
if(null == info.shaderBinaryFormats) {
info.shaderBinaryFormats = new HashSet<Integer>();
if (gl.isGLES2Compatible()) {
- final int[] param = new int[1];
- gl.glGetIntegerv(GL2ES2.GL_NUM_SHADER_BINARY_FORMATS, param, 0);
- int numFormats = param[0];
- if(numFormats>0) {
- int[] formats = new int[numFormats];
- gl.glGetIntegerv(GL2ES2.GL_SHADER_BINARY_FORMATS, formats, 0);
- for(int i=0; i<numFormats; i++) {
- info.shaderBinaryFormats.add(new Integer(formats[i]));
+ try {
+ final int[] param = new int[1];
+ gl.glGetIntegerv(GL2ES2.GL_NUM_SHADER_BINARY_FORMATS, param, 0);
+ final int err = gl.glGetError();
+ final int numFormats = GL.GL_NO_ERROR == err ? param[0] : 0;
+ if(numFormats>0) {
+ int[] formats = new int[numFormats];
+ gl.glGetIntegerv(GL2ES2.GL_SHADER_BINARY_FORMATS, formats, 0);
+ for(int i=0; i<numFormats; i++) {
+ info.shaderBinaryFormats.add(new Integer(formats[i]));
+ }
}
- }
+ } catch (GLException gle) { System.err.println("Catched Exception: "+gle.getMessage()); gle.printStackTrace(); }
}
}
return info.shaderBinaryFormats;
@@ -180,17 +183,25 @@ public class ShaderUtil {
final ProfileInformation info = getProfileInformation(gl);
if(null==info.shaderCompilerAvailable) {
if(gl.isGLES2()) {
- final byte[] param = new byte[1];
- gl.glGetBooleanv(GL2ES2.GL_SHADER_COMPILER, param, 0);
- boolean v = param[0]!=(byte)0x00;
- if(!v) {
- final Set<Integer> bfs = getShaderBinaryFormats(gl);
- if(bfs.size()==0) {
- // no supported binary formats, hence a compiler must be available!
- v = true;
+ boolean queryOK = false;
+ try {
+ final byte[] param = new byte[1];
+ gl.glGetBooleanv(GL2ES2.GL_SHADER_COMPILER, param, 0);
+ final int err = gl.glGetError();
+ boolean v = GL.GL_NO_ERROR == err && param[0]!=(byte)0x00;
+ if(!v) {
+ final Set<Integer> bfs = getShaderBinaryFormats(gl);
+ if(bfs.size()==0) {
+ // no supported binary formats, hence a compiler must be available!
+ v = true;
+ }
}
- }
- info.shaderCompilerAvailable = new Boolean(v);
+ info.shaderCompilerAvailable = new Boolean(v);
+ queryOK = true;
+ } catch (GLException gle) { System.err.println("Catched Exception: "+gle.getMessage()); gle.printStackTrace(); }
+ if(!queryOK) {
+ info.shaderCompilerAvailable = new Boolean(true);
+ }
} else if( gl.isGL2ES2() ) {
info.shaderCompilerAvailable = new Boolean(true);
} else {
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/FixedFuncUtil.java b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/FixedFuncUtil.java
index d92a7aa..a653bd4 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/FixedFuncUtil.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/FixedFuncUtil.java
@@ -4,26 +4,45 @@
package com.jogamp.opengl.util.glsl.fixedfunc;
-import javax.media.opengl.*;
-import javax.media.opengl.fixedfunc.*;
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2ES1;
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLException;
+import javax.media.opengl.fixedfunc.GLPointerFuncUtil;
+
+import jogamp.opengl.util.glsl.fixedfunc.FixedFuncHook;
+import jogamp.opengl.util.glsl.fixedfunc.FixedFuncImpl;
+import jogamp.opengl.util.glsl.fixedfunc.FixedFuncPipeline;
+
+import com.jogamp.opengl.util.PMVMatrix;
-import jogamp.opengl.util.glsl.fixedfunc.*;
/**
* Tool to pipeline GL2ES2 into a fixed function emulation implementing GL2ES1.
*/
public class FixedFuncUtil {
/**
+ * @param gl
+ * @param mode one of the {@link ShaderSelectionMode}s
+ * @param pmvMatrix optional pass through PMVMatrix for the {@link FixedFuncHook} and {@link FixedFuncPipeline}
* @return If gl is a GL2ES1 and force is false, return the type cast object,
* otherwise create a fixed function emulation pipeline using the given GL2ES2 impl
* and hook it to the GLContext via {@link GLContext#setGL(GL)}.
* @throws GLException if the GL object is neither GL2ES1 nor GL2ES2
+ *
+ * @see ShaderSelectionMode#AUTO
+ * @see ShaderSelectionMode#COLOR
+ * @see ShaderSelectionMode#COLOR_LIGHT_PER_VERTEX
+ * @see ShaderSelectionMode#COLOR_TEXTURE
+ * @see ShaderSelectionMode#COLOR_TEXTURE_LIGHT_PER_VERTEX
*/
- public static final GL2ES1 wrapFixedFuncEmul(GL gl, boolean force) {
+ public static final GL2ES1 wrapFixedFuncEmul(GL gl, ShaderSelectionMode mode, PMVMatrix pmvMatrix, boolean force, boolean verbose) {
if(gl.isGL2ES2() && ( !gl.isGL2ES1() || force ) ) {
- GL2ES2 es2 = gl.getGL2ES2();
- FixedFuncHook hook = new FixedFuncHook(es2);
- FixedFuncImpl impl = new FixedFuncImpl(es2, hook);
+ final GL2ES2 es2 = gl.getGL2ES2();
+ final FixedFuncHook hook = new FixedFuncHook(es2, mode, pmvMatrix);
+ hook.setVerbose(verbose);
+ final FixedFuncImpl impl = new FixedFuncImpl(es2, hook);
gl.getContext().setGL(impl);
return impl;
} else if(gl.isGL2ES1()) {
@@ -33,13 +52,22 @@ public class FixedFuncUtil {
}
/**
+ * @param gl
+ * @param mode one of the {@link ShaderSelectionMode}s
+ * @param pmvMatrix optional pass through PMVMatrix for the {@link FixedFuncHook} and {@link FixedFuncPipeline}
* @return If gl is a GL2ES1, return the type cast object,
* otherwise create a fixed function emulation pipeline using the GL2ES2 impl.
* and hook it to the GLContext via {@link GLContext#setGL(GL)}.
* @throws GLException if the GL object is neither GL2ES1 nor GL2ES2
+ *
+ * @see ShaderSelectionMode#AUTO
+ * @see ShaderSelectionMode#COLOR
+ * @see ShaderSelectionMode#COLOR_LIGHT_PER_VERTEX
+ * @see ShaderSelectionMode#COLOR_TEXTURE
+ * @see ShaderSelectionMode#COLOR_TEXTURE_LIGHT_PER_VERTEX
*/
- public static final GL2ES1 wrapFixedFuncEmul(GL gl) {
- return wrapFixedFuncEmul(gl, false);
+ public static final GL2ES1 wrapFixedFuncEmul(GL gl, ShaderSelectionMode mode, PMVMatrix pmvMatrix) {
+ return wrapFixedFuncEmul(gl, mode, null, false, false);
}
/**
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/ShaderSelectionMode.java b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/ShaderSelectionMode.java
new file mode 100644
index 0000000..e6bdf70
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/ShaderSelectionMode.java
@@ -0,0 +1,27 @@
+package com.jogamp.opengl.util.glsl.fixedfunc;
+
+/**
+ * Shader selection mode
+ *
+ * @see ShaderSelectionMode#AUTO
+ * @see ShaderSelectionMode#COLOR
+ * @see ShaderSelectionMode#COLOR_LIGHT_PER_VERTEX
+ * @see ShaderSelectionMode#COLOR_TEXTURE
+ * @see ShaderSelectionMode#COLOR_TEXTURE_LIGHT_PER_VERTEX
+ */
+public enum ShaderSelectionMode {
+ /** Auto shader selection, based upon FFP states. */
+ AUTO,
+ /** Fixed shader selection: Simple color. */
+ COLOR,
+ /** Fixed shader selection: Multi-Textured color. 2 texture units. */
+ COLOR_TEXTURE2,
+ /** Fixed shader selection: Multi-Textured color. 4 texture units. */
+ COLOR_TEXTURE4,
+ /** Fixed shader selection: Multi-Textured color. 8 texture units. */
+ COLOR_TEXTURE8,
+ /** Fixed shader selection: Color with vertex-lighting. */
+ COLOR_LIGHT_PER_VERTEX,
+ /** Fixed shader selection: Multi-Textured color with vertex-lighting. 8 texture units.*/
+ COLOR_TEXTURE8_LIGHT_PER_VERTEX
+}
\ No newline at end of file
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java b/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java
index e7bf87a..6e66e3d 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java
@@ -833,9 +833,14 @@ public class Texture {
}
/**
- * Returns the underlying OpenGL texture object for this texture.
+ * Returns the underlying OpenGL texture object for this texture
+ * and generates it if not done yet.
+ * <p>
* Most applications will not need to access this, since it is
* handled automatically by the bind(GL) and destroy(GL) APIs.
+ * </p>
+ * @param gl required to be valid and current in case the texture object has not been generated yet,
+ * otherwise it may be <code>null</code>.
*/
public int getTextureObject(GL gl) {
validateTexID(gl, false);
@@ -1089,7 +1094,7 @@ public class Texture {
// Prefer GL_ARB_texture_rectangle on ATI hardware on Mac OS X
// due to software fallbacks
- if (NativeWindowFactory.TYPE_MACOSX.equals(NativeWindowFactory.getNativeWindowType(false))) {
+ if (NativeWindowFactory.TYPE_MACOSX == NativeWindowFactory.getNativeWindowType(false)) {
String vendor = gl.glGetString(GL.GL_VENDOR);
if (vendor != null && vendor.startsWith("ATI")) {
return true;
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/LEDataInputStream.java b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/LEDataInputStream.java
index 37dbc54..b7262aa 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/LEDataInputStream.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/LEDataInputStream.java
@@ -180,7 +180,7 @@ public class LEDataInputStream extends FilterInputStream implements DataInput
{
int i1 = readInt();
int i2 = readInt();
- return ((long)(i1) & 0xFFFFFFFFL) + (i2 << 32);
+ return ((long)i1 & 0xFFFFFFFFL) + ((long)i2 << 32);
}
public final float readFloat() throws IOException
diff --git a/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java b/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java
index 5fa8ce3..b052769 100644
--- a/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java
+++ b/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java
@@ -87,20 +87,20 @@ import jogamp.opengl.Debug;
public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser {
private static final boolean DEBUG = Debug.isPropertyDefined("jogl.debug.CapabilitiesChooser", true);
- final static int NO_SCORE = -9999999;
- final static int DOUBLE_BUFFER_MISMATCH_PENALTY = 1000;
- final static int OPAQUE_MISMATCH_PENALTY = 750;
- final static int STENCIL_MISMATCH_PENALTY = 500;
- final static int MULTISAMPLE_MISMATCH_PENALTY = 500;
- final static int MULTISAMPLE_EXTENSION_MISMATCH_PENALTY = 250; // just a little drop, no scale
+ private final static int NO_SCORE = -9999999;
+ private final static int DOUBLE_BUFFER_MISMATCH_PENALTY = 1000;
+ private final static int OPAQUE_MISMATCH_PENALTY = 750;
+ private final static int STENCIL_MISMATCH_PENALTY = 500;
+ private final static int MULTISAMPLE_MISMATCH_PENALTY = 500;
+ private final static int MULTISAMPLE_EXTENSION_MISMATCH_PENALTY = 250; // just a little drop, no scale
// Pseudo attempt to keep equal rank penalties scale-equivalent
// (e.g., stencil mismatch is 3 * accum because there are 3 accum
// components)
- final static int COLOR_MISMATCH_PENALTY_SCALE = 36;
- final static int DEPTH_MISMATCH_PENALTY_SCALE = 6;
- final static int ACCUM_MISMATCH_PENALTY_SCALE = 1;
- final static int STENCIL_MISMATCH_PENALTY_SCALE = 3;
- final static int MULTISAMPLE_MISMATCH_PENALTY_SCALE = 3;
+ private final static int COLOR_MISMATCH_PENALTY_SCALE = 36;
+ private final static int DEPTH_MISMATCH_PENALTY_SCALE = 6;
+ private final static int ACCUM_MISMATCH_PENALTY_SCALE = 1;
+ private final static int STENCIL_MISMATCH_PENALTY_SCALE = 3;
+ private final static int MULTISAMPLE_MISMATCH_PENALTY_SCALE = 3;
@Override
public int chooseCapabilities(final CapabilitiesImmutable desired,
@@ -150,11 +150,20 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser {
if (cur == null) {
continue;
}
- if (gldes.isOnscreen() != cur.isOnscreen()) {
- continue;
+ if (gldes.isOnscreen() && !cur.isOnscreen()) {
+ continue; // requested onscreen, but n/a
}
- if (!gldes.isOnscreen() && gldes.isPBuffer() && !cur.isPBuffer()) {
- continue; // only skip if requested Offscreen && PBuffer, but no PBuffer available
+ if (!gldes.isOnscreen()) {
+ /** FBO is generic ..
+ if (gldes.isFBO() && !cur.isFBO()) {
+ continue; // requested FBO, but n/a
+ } */
+ if (gldes.isPBuffer() && !cur.isPBuffer()) {
+ continue; // requested pBuffer, but n/a
+ }
+ if (gldes.isBitmap() && !cur.isBitmap()) {
+ continue; // requested pBuffer, but n/a
+ }
}
if (gldes.getStereo() != cur.getStereo()) {
continue;
diff --git a/src/jogl/classes/javax/media/opengl/GLArrayData.java b/src/jogl/classes/javax/media/opengl/GLArrayData.java
index 7c56b53..5d17f68 100644
--- a/src/jogl/classes/javax/media/opengl/GLArrayData.java
+++ b/src/jogl/classes/javax/media/opengl/GLArrayData.java
@@ -145,7 +145,11 @@ public interface GLArrayData {
/**
* True, if GL shall normalize fixed point data while converting
- * them into float
+ * them into float.
+ * <p>
+ * Default behavior (of the fixed function pipeline) is <code>true</code>
+ * for fixed point data type and <code>false</code> for floating point data types.
+ * </p>
*/
public boolean getNormalized();
diff --git a/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java b/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java
index 0b2c664..38f1746 100644
--- a/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java
+++ b/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java
@@ -115,6 +115,12 @@ public interface GLAutoDrawable extends GLDrawable {
public static final boolean SCREEN_CHANGE_ACTION_ENABLED = Debug.getBooleanProperty("jogl.screenchange.action", true);
/**
+ * If the implementation uses delegation, return the delegated {@link GLDrawable} instance,
+ * otherwise return <code>this</code> instance.
+ */
+ public GLDrawable getDelegatedDrawable();
+
+ /**
* Returns the context associated with this drawable. The returned
* context will be synchronized.
* Don't rely on it's identity, the context may change.
@@ -124,23 +130,31 @@ public interface GLAutoDrawable extends GLDrawable {
/**
* Associate a new context to this drawable and also propagates the context/drawable switch by
* calling {@link GLContext#setGLDrawable(GLDrawable, boolean) newCtx.setGLDrawable(drawable, true);}.
- * <code>drawable</code> might be an inner GLDrawable instance if using such a delegation pattern,
- * or this GLAutoDrawable itself.
- * <p>
- * If the old context's drawable was an {@link GLAutoDrawable}, it's reference to the given drawable
- * is being cleared by calling
- * {@link GLAutoDrawable#setContext(GLContext) ((GLAutoDrawable)oldCtx.getGLDrawable()).setContext(null)}.
- * </p>
+ * <code>drawable</code> might be an inner GLDrawable instance if using a delegation pattern,
+ * or this GLAutoDrawable instance.
* <p>
* If the old or new context was current on this thread, it is being released before switching the drawable.
* The new context will be made current afterwards, if it was current before.
- * However the user shall take extra care that not other thread
- * attempts to make this context current. Otherwise a race condition may happen.
+ * However the user shall take extra care that no other thread
+ * attempts to make this context current.
+ * </p>
+ * <p>
+ * Be aware that the old context is still bound to the drawable,
+ * and that one context can only be bound to one drawable at one time!
* </p>
* <p>
- * <b>Disclaimer</b>: Even though the API may allows this functionality in theory, your mileage may vary
- * switching the drawable of an already established GLContext, i.e. which is already made current once.
- * FIXME: Validate functionality!
+ * In case you do not intend to use the old context anymore, i.e.
+ * not assigning it to another drawable, it shall be
+ * destroyed before setting the new context, i.e.:
+ * <pre>
+ GLContext oldCtx = glad.getContext();
+ if(null != oldCtx) {
+ oldCtx.destroy();
+ }
+ glad.setContext(newCtx);
+ * </pre>
+ * This is required, since a context must have a valid drawable at all times
+ * and this API shall not restrict the user in any way.
* </p>
*
* @param newCtx the new context
diff --git a/src/jogl/classes/javax/media/opengl/GLBase.java b/src/jogl/classes/javax/media/opengl/GLBase.java
index f5831a7..9bcee81 100644
--- a/src/jogl/classes/javax/media/opengl/GLBase.java
+++ b/src/jogl/classes/javax/media/opengl/GLBase.java
@@ -273,6 +273,42 @@ public interface GLBase {
*/
public boolean isExtensionAvailable(String glExtensionName);
+ /**
+ * Returns <code>true</code> if basic FBO support is available, otherwise <code>false</code>.
+ * <p>
+ * Basic FBO is supported if the context is either GL-ES >= 2.0, GL >= core 3.0 or implements the extensions
+ * <code>GL_ARB_ES2_compatibility</code>, <code>GL_ARB_framebuffer_object</code>, <code>GL_EXT_framebuffer_object</code> or <code>GL_OES_framebuffer_object</code>.
+ * </p>
+ * <p>
+ * Basic FBO support may only include one color attachment and no multisampling,
+ * as well as limited internal formats for renderbuffer.
+ * </p>
+ * @see GLContext#hasBasicFBOSupport()
+ */
+ public boolean hasBasicFBOSupport();
+
+ /**
+ * Returns <code>true</code> if full FBO support is available, otherwise <code>false</code>.
+ * <p>
+ * Full FBO is supported if the context is either GL >= core 3.0 or implements the extensions
+ * <code>ARB_framebuffer_object</code>, or all of
+ * <code>EXT_framebuffer_object</code>, <code>EXT_framebuffer_multisample</code>,
+ * <code>EXT_framebuffer_blit</code>, <code>GL_EXT_packed_depth_stencil</code>.
+ * </p>
+ * <p>
+ * Full FBO support includes multiple color attachments and multisampling.
+ * </p>
+ * @see GLContext#hasFullFBOSupport()
+ */
+ public boolean hasFullFBOSupport();
+
+ /**
+ * Returns the maximum number of FBO RENDERBUFFER samples
+ * if {@link #hasFullFBOSupport() full FBO is supported}, otherwise false.
+ * @see GLContext#getMaxRenderbufferSamples()
+ */
+ public int getMaxRenderbufferSamples();
+
/**
* Returns true if the GL context supports non power of two (NPOT) textures,
* otherwise false.
@@ -284,6 +320,8 @@ public interface GLBase {
*/
public boolean isNPOTTextureAvailable();
+ public boolean isTextureFormatBGRA8888Available();
+
/** Provides a platform-independent way to specify the minimum swap
interval for buffer swaps. An argument of 0 disables
sync-to-vertical-refresh completely, while an argument of 1
diff --git a/src/jogl/classes/javax/media/opengl/GLCapabilities.java b/src/jogl/classes/javax/media/opengl/GLCapabilities.java
index 8845ec6..9b004a0 100644
--- a/src/jogl/classes/javax/media/opengl/GLCapabilities.java
+++ b/src/jogl/classes/javax/media/opengl/GLCapabilities.java
@@ -102,23 +102,52 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil
}
}
+ /**
+ * Copies all {@link GLCapabilities} and {@link Capabilities} values
+ * from <code>source</code> into this instance.
+ * @return this instance
+ */
+ public GLCapabilities copyFrom(GLCapabilitiesImmutable source) {
+ super.copyFrom(source);
+ glProfile = source.getGLProfile();
+ isPBuffer = source.isPBuffer();
+ isFBO = source.isFBO();
+ doubleBuffered = source.getDoubleBuffered();
+ stereo = source.getStereo();
+ hardwareAccelerated = source.getHardwareAccelerated();
+ depthBits = source.getDepthBits();
+ stencilBits = source.getStencilBits();
+ accumRedBits = source.getAccumRedBits();
+ accumGreenBits = source.getAccumGreenBits();
+ accumBlueBits = source.getAccumBlueBits();
+ accumAlphaBits = source.getAccumAlphaBits();
+ sampleBuffers = source.getSampleBuffers();
+ pbufferFloatingPointBuffers = source.getPbufferFloatingPointBuffers();
+ pbufferRenderToTexture = source.getPbufferRenderToTexture();
+ pbufferRenderToTextureRectangle = source.getPbufferRenderToTextureRectangle();
+ numSamples = source.getNumSamples();
+ sampleExtension = source.getSampleExtension();
+ return this;
+ }
+
@Override
public int hashCode() {
// 31 * x == (x << 5) - x
- int hash = 31 + this.glProfile.hashCode() ;
+ int hash = super.hashCode();
+ hash = ((hash << 5) - hash) + this.glProfile.hashCode() ;
+ hash = ((hash << 5) - hash) + ( this.hardwareAccelerated ? 1 : 0 );
+ hash = ((hash << 5) - hash) + ( this.stereo ? 1 : 0 );
hash = ((hash << 5) - hash) + ( this.isFBO ? 1 : 0 );
hash = ((hash << 5) - hash) + ( this.isPBuffer ? 1 : 0 );
- hash = ((hash << 5) - hash) + ( this.stereo ? 1 : 0 );
- hash = ((hash << 5) - hash) + ( this.hardwareAccelerated ? 1 : 0 );
+ hash = ((hash << 5) - hash) + ( this.sampleBuffers ? 1 : 0 );
+ hash = ((hash << 5) - hash) + this.getNumSamples();
+ hash = ((hash << 5) - hash) + this.sampleExtension.hashCode();
hash = ((hash << 5) - hash) + this.depthBits;
hash = ((hash << 5) - hash) + this.stencilBits;
hash = ((hash << 5) - hash) + this.accumRedBits;
hash = ((hash << 5) - hash) + this.accumGreenBits;
hash = ((hash << 5) - hash) + this.accumBlueBits;
hash = ((hash << 5) - hash) + this.accumAlphaBits;
- hash = ((hash << 5) - hash) + ( this.sampleBuffers ? 1 : 0 );
- hash = ((hash << 5) - hash) + this.numSamples;
- hash = ((hash << 5) - hash) + this.sampleExtension.hashCode();
hash = ((hash << 5) - hash) + ( this.pbufferFloatingPointBuffers ? 1 : 0 );
hash = ((hash << 5) - hash) + ( this.pbufferRenderToTexture ? 1 : 0 );
hash = ((hash << 5) - hash) + ( this.pbufferRenderToTextureRectangle ? 1 : 0 );
@@ -136,6 +165,7 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil
other.getGLProfile()==glProfile &&
other.isPBuffer()==isPBuffer &&
other.isFBO()==isFBO &&
+ other.getDoubleBuffered() == doubleBuffered &&
other.getStereo()==stereo &&
other.getHardwareAccelerated()==hardwareAccelerated &&
other.getDepthBits()==depthBits &&
@@ -148,9 +178,8 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil
other.getPbufferFloatingPointBuffers()==pbufferFloatingPointBuffers &&
other.getPbufferRenderToTexture()==pbufferRenderToTexture &&
other.getPbufferRenderToTextureRectangle()==pbufferRenderToTextureRectangle;
- if(sampleBuffers) {
- res = res &&
- other.getNumSamples()==numSamples &&
+ if(res && sampleBuffers) {
+ res = other.getNumSamples()==getNumSamples() &&
other.getSampleExtension().equals(sampleExtension) ;
}
return res;
@@ -222,19 +251,24 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil
public void setGLProfile(GLProfile profile) {
glProfile=profile;
}
-
+
@Override
public final boolean isPBuffer() {
return isPBuffer;
}
/**
- * Enables or disables pbuffer usage.
+ * Requesting offscreen pbuffer mode.
* <p>
* If enabled this method also invokes {@link #setOnscreen(int) setOnscreen(false)}.
* </p>
+ * <p>
* Defaults to false.
- */
+ * </p>
+ * <p>
+ * Requesting offscreen pbuffer mode disables the offscreen auto selection.
+ * </p>
+ */
public void setPBuffer(boolean enable) {
if(enable) {
setOnscreen(false);
@@ -248,11 +282,16 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil
}
/**
- * Enables or disables FBO usage.
+ * Requesting offscreen FBO mode.
* <p>
* If enabled this method also invokes {@link #setOnscreen(int) setOnscreen(false)}.
* </p>
+ * <p>
* Defaults to false.
+ * </p>
+ * <p>
+ * Requesting offscreen FBO mode disables the offscreen auto selection.
+ * </p>
*/
public void setFBO(boolean enable) {
if(enable) {
@@ -261,21 +300,6 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil
isFBO = enable;
}
- /**
- * Sets whether the drawable surface supports onscreen.<br>
- * If enabled this method also invokes {@link #setPBuffer(int) setPBuffer(false)}
- * and {@link #setFBO(int) setFBO(false)}<br>
- * Defaults to true.
- */
- @Override
- public void setOnscreen(boolean onscreen) {
- if(onscreen) {
- setPBuffer(false);
- setFBO(false);
- }
- super.setOnscreen(onscreen);
- }
-
@Override
public final boolean getDoubleBuffered() {
return doubleBuffered;
@@ -465,9 +489,9 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil
sink = new StringBuilder();
}
- int samples = sampleBuffers ? numSamples : 0 ;
+ final int samples = sampleBuffers ? numSamples : 0 ;
- super.toString(sink);
+ super.toString(sink, false);
sink.append(", accum-rgba ").append(accumRedBits).append("/").append(accumGreenBits).append("/").append(accumBlueBits).append("/").append(accumAlphaBits);
sink.append(", dp/st/ms: ").append(depthBits).append("/").append(stencilBits).append("/").append(samples);
@@ -490,20 +514,37 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil
sink.append(", sw, ");
}
sink.append(glProfile);
- if(!isOnscreen()) {
- if(isFBO) {
- sink.append(", fbo");
- }
- if(isPBuffer) {
- sink.append(", pbuffer [r2t ").append(pbufferRenderToTexture?1:0)
- .append(", r2tr ").append(pbufferRenderToTextureRectangle?1:0)
- .append(", float ").append(pbufferFloatingPointBuffers?1:0)
- .append("]");
- }
- if(!isFBO && !isPBuffer) {
- sink.append(", pixmap");
+ if(isOnscreen()) {
+ sink.append(", on-scr[");
+ } else {
+ sink.append(", offscr[");
+ }
+ boolean ns=false;
+ if(isFBO()) {
+ sink.append("fbo");
+ ns = true;
+ }
+ if(isPBuffer()) {
+ if(ns) { sink.append(", "); }
+ sink.append("pbuffer [r2t ").append(pbufferRenderToTexture?1:0)
+ .append(", r2tr ").append(pbufferRenderToTextureRectangle?1:0)
+ .append(", float ").append(pbufferFloatingPointBuffers?1:0)
+ .append("]");
+ ns = true;
+ }
+ if(isBitmap()) {
+ if(ns) { sink.append(", "); }
+ sink.append("bitmap");
+ ns = true;
+ }
+ if(!ns) { // !FBO !PBuffer !Bitmap
+ if(isOnscreen()) {
+ sink.append("."); // no additional off-screen modes besides on-screen
+ } else {
+ sink.append("auto-cfg"); // auto-config off-screen mode
}
}
+ sink.append("]");
return sink;
}
diff --git a/src/jogl/classes/javax/media/opengl/GLCapabilitiesImmutable.java b/src/jogl/classes/javax/media/opengl/GLCapabilitiesImmutable.java
index 7e0459b..ee261ca 100644
--- a/src/jogl/classes/javax/media/opengl/GLCapabilitiesImmutable.java
+++ b/src/jogl/classes/javax/media/opengl/GLCapabilitiesImmutable.java
@@ -50,7 +50,7 @@ public interface GLCapabilitiesImmutable extends CapabilitiesImmutable {
GLProfile getGLProfile();
/**
- * Returns the number of bits requested for the accumulation
+ * Returns the number of bits for the accumulation
* buffer's alpha component. On some systems only the accumulation
* buffer depth, which is the sum of the red, green, and blue bits,
* is considered.
@@ -58,7 +58,7 @@ public interface GLCapabilitiesImmutable extends CapabilitiesImmutable {
int getAccumAlphaBits();
/**
- * Returns the number of bits requested for the accumulation
+ * Returns the number of bits for the accumulation
* buffer's blue component. On some systems only the accumulation
* buffer depth, which is the sum of the red, green, and blue bits,
* is considered.
@@ -66,7 +66,7 @@ public interface GLCapabilitiesImmutable extends CapabilitiesImmutable {
int getAccumBlueBits();
/**
- * Returns the number of bits requested for the accumulation
+ * Returns the number of bits for the accumulation
* buffer's green component. On some systems only the accumulation
* buffer depth, which is the sum of the red, green, and blue bits,
* is considered.
@@ -74,7 +74,7 @@ public interface GLCapabilitiesImmutable extends CapabilitiesImmutable {
int getAccumGreenBits();
/**
- * Returns the number of bits requested for the accumulation
+ * Returns the number of bits for the accumulation
* buffer's red component. On some systems only the accumulation
* buffer depth, which is the sum of the red, green, and blue bits,
* is considered.
@@ -82,74 +82,115 @@ public interface GLCapabilitiesImmutable extends CapabilitiesImmutable {
int getAccumRedBits();
/**
- * Returns the number of bits requested for the depth buffer.
+ * Returns the number of depth buffer bits.
*/
int getDepthBits();
/**
- * Indicates whether double-buffering is enabled.
+ * Returns whether double-buffering is requested, available or chosen.
+ * <p>
+ * Default is true.
+ * </p>
*/
boolean getDoubleBuffered();
/**
- * Indicates whether hardware acceleration is enabled.
+ * Returns whether hardware acceleration is requested, available or chosen.
+ * <p>
+ * Default is true.
+ * </p>
*/
boolean getHardwareAccelerated();
/**
- * Returns the used extension for full-scene antialiasing
- * (FSAA), default is {@link #DEFAULT_SAMPLE_EXTENSION}.
+ * Returns the extension for full-scene antialiasing
+ * (FSAA).
+ * <p>
+ * Default is {@link #DEFAULT_SAMPLE_EXTENSION}.
+ * </p>
*/
String getSampleExtension();
/**
* Returns whether sample buffers for full-scene antialiasing
- * (FSAA) should be allocated for this drawable. Defaults to
- * false.
+ * (FSAA) should be allocated for this drawable.
+ * <p>
+ * Default is false.
+ * </p>
*/
boolean getSampleBuffers();
/**
* Returns the number of sample buffers to be allocated if sample
- * buffers are enabled, otherwise returns 0. Defaults to 2.
+ * buffers are enabled, otherwise returns 0.
+ * <p>
+ * Default is 0 due to disable sample buffers per default.
+ * </p>
*/
int getNumSamples();
/**
* For pbuffers only, returns whether floating-point buffers should
- * be used if available. Defaults to false.
+ * be used if available.
+ * <p>
+ * Default is false.
+ * </p>
*/
boolean getPbufferFloatingPointBuffers();
/**
* For pbuffers only, returns whether the render-to-texture
- * extension should be used if available. Defaults to false.
+ * extension should be used if available.
+ * <p>
+ * Default is false.
+ * </p>
*/
boolean getPbufferRenderToTexture();
/**
* For pbuffers only, returns whether the render-to-texture
- * extension should be used. Defaults to false.
+ * extension should be used.
+ * <p>
+ * Default is false.
+ * </p>
*/
boolean getPbufferRenderToTextureRectangle();
/**
- * Returns the number of bits requested for the stencil buffer.
+ * Returns the number of stencil buffer bits.
+ * <p>
+ * Default is 0.
+ * </p>
*/
int getStencilBits();
/**
- * Indicates whether stereo is enabled.
+ * Returns whether stereo is requested, available or chosen.
+ * <p>
+ * Default is false.
+ * </p>
*/
boolean getStereo();
/**
- * Indicates whether pbuffer offscreen is used/requested.
+ * Returns whether pbuffer offscreen mode is requested, available or chosen.
+ * <p>
+ * Default is false.
+ * </p>
+ * <p>
+ * For chosen capabilities, only the selected offscreen surface is set to <code>true</code>.
+ * </p>
*/
boolean isPBuffer();
/**
- * Indicates whether FBO offscreen is used/requested.
+ * Returns whether FBO offscreen mode is requested, available or chosen.
+ * <p>
+ * Default is false.
+ * </p>
+ * <p>
+ * For chosen capabilities, only the selected offscreen surface is set to <code>true</code>.
+ * </p>
*/
boolean isFBO();
diff --git a/src/jogl/classes/javax/media/opengl/GLContext.java b/src/jogl/classes/javax/media/opengl/GLContext.java
index 63a02ad..de10a28 100644
--- a/src/jogl/classes/javax/media/opengl/GLContext.java
+++ b/src/jogl/classes/javax/media/opengl/GLContext.java
@@ -52,10 +52,11 @@ import jogamp.opengl.Debug;
import jogamp.opengl.GLContextImpl;
import com.jogamp.common.os.Platform;
-import com.jogamp.common.util.IntObjectHashMap;
+import com.jogamp.common.util.VersionNumber;
import com.jogamp.common.util.locks.LockFactory;
import com.jogamp.common.util.locks.RecursiveLock;
import com.jogamp.opengl.GLExtensions;
+import com.jogamp.opengl.GLRendererQuirks;
/** Abstraction for an OpenGL rendering context. In order to perform
OpenGL rendering, a context must be "made current" on the current
@@ -97,6 +98,9 @@ public abstract class GLContext {
*/
public static final boolean PROFILE_ALIASING = !Debug.isPropertyDefined("jogl.debug.GLContext.NoProfileAliasing", true);
+ protected static final boolean FORCE_NO_FBO_SUPPORT = Debug.isPropertyDefined("jogl.fbo.force.none", true);
+ protected static final boolean FORCE_MIN_FBO_SUPPORT = Debug.isPropertyDefined("jogl.fbo.force.min", true);
+
public static final boolean DEBUG = Debug.debug("GLContext");
public static final boolean TRACE_SWITCH = Debug.isPropertyDefined("jogl.debug.GLContext.TraceSwitch", true);
@@ -128,9 +132,9 @@ public abstract class GLContext {
/** <code>GL_ARB_ES2_compatibility</code> implementation related: Context is compatible w/ ES2. Not a cache key. See {@link #isGLES2Compatible()}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */
protected static final int CTX_IMPL_ES2_COMPAT = 1 << 8;
- /** Context supports basic FBO, details see {@link #hasFBO()}.
+ /** Context supports basic FBO, details see {@link #hasBasicFBOSupport()}.
* Not a cache key.
- * @see #hasFBO()
+ * @see #hasBasicFBOSupport()
* @see #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)
*/
protected static final int CTX_IMPL_FBO = 1 << 9;
@@ -140,8 +144,7 @@ public abstract class GLContext {
private static final ThreadLocal<GLContext> currentContext = new ThreadLocal<GLContext>();
- private final HashMap<String, Object> attachedObjectsByString = new HashMap<String, Object>();
- private final IntObjectHashMap attachedObjectsByInt = new IntObjectHashMap();
+ private final HashMap<String, Object> attachedObjects = new HashMap<String, Object>();
// RecursiveLock maintains a queue of waiting Threads, ensuring the longest waiting thread will be notified at unlock.
protected final RecursiveLock lock = LockFactory.createRecursiveLock();
@@ -157,8 +160,13 @@ public abstract class GLContext {
protected int ctxMinorVersion;
protected int ctxOptions;
protected String ctxVersionString;
+ protected VersionNumber ctxGLSLVersion;
private int currentSwapInterval;
+ protected GLRendererQuirks glRendererQuirks;
+ /** Did the drawable association changed ? see {@link GLRendererQuirks#NoSetSwapIntervalPostRetarget} */
+ protected boolean drawableRetargeted;
+
protected void resetStates() {
if (DEBUG) {
System.err.println(getThreadName() + ": GLContext.resetStates()");
@@ -168,12 +176,36 @@ public abstract class GLContext {
ctxMinorVersion=-1;
ctxOptions=0;
ctxVersionString=null;
- attachedObjectsByString.clear();
- attachedObjectsByInt.clear();
+ ctxGLSLVersion=null;
+ attachedObjects.clear();
contextHandle=0;
currentSwapInterval = -1;
+ glRendererQuirks = null;
+ drawableRetargeted = false;
}
+ /**
+ * Returns the instance of {@link GLRendererQuirks}, allowing one to determine workarounds.
+ * @return instance of {@link GLRendererQuirks} if context was made current once, otherwise <code>null</code>.
+ */
+ public final GLRendererQuirks getRendererQuirks() { return glRendererQuirks; }
+
+ /**
+ * Returns true if the <code>quirk</code> exist in {@link #getRendererQuirks()}, otherwise false.
+ * <p>
+ * Convenience method for:
+ * <pre>
+ * final GLRendererQuirks glrq = ctx.getRendererQuirks();
+ * boolean hasQuirk = null != glrq ? glrq.exist(quirk) : false ;
+ * </pre>
+ * </p>
+ * @param quirk the quirk to be tested, e.g. {@link GLRendererQuirks#NoDoubleBufferedPBuffer}.
+ * @throws IllegalArgumentException if the quirk is out of range
+ */
+ public final boolean hasRendererQuirk(int quirk) throws IllegalArgumentException {
+ return null != glRendererQuirks ? glRendererQuirks.exist(quirk) : false ;
+ }
+
/**
* Sets the read/write drawable for framebuffer operations.
* <p>
@@ -181,11 +213,6 @@ public abstract class GLContext {
* and made current afterwards. However the user shall take extra care that not other thread
* attempts to make this context current. Otherwise a race condition may happen.
* </p>
- * <p>
- * <b>Disclaimer</b>: Even though the API may allows this functionality in theory, your mileage may vary
- * switching the drawable of an already established GLContext, i.e. which is already made current once.
- * FIXME: Validate functionality!
- * </p>
* @param readWrite the read/write drawable for framebuffer operations.
* @param setWriteOnly if <code>true</code> and if the current read-drawable differs
* from the write-drawable ({@link #setGLReadDrawable(GLDrawable)}),
@@ -250,19 +277,23 @@ public abstract class GLContext {
* Makes this GLContext current on the calling thread.
* <p>
* There are two return values that indicate success and one that
- * indicates failure. A return value of CONTEXT_CURRENT_NEW
- * indicates that that context has been made current, and that
- * this is the first time this context has been made current, or
- * that the state of the underlying context or drawable may have
- * changed since the last time this context was made current. In
- * this case, the application may wish to initialize the state. A
- * return value of CONTEXT_CURRENT indicates that the context has
+ * indicates failure.
+ * </p>
+ * <p>
+ * A return value of {@link #CONTEXT_CURRENT_NEW}
+ * indicates that that context has been made current for the 1st time,
+ * or that the state of the underlying context or drawable has
+ * changed since the last time this context was current.
+ * In this case, the application may wish to initialize the render state.
+ * </p>
+ * <p>
+ * A return value of {@link #CONTEXT_CURRENT} indicates that the context has
* been made currrent, with its previous state restored.
* </p>
* <p>
* If the context could not be made current (for example, because
* the underlying drawable has not ben realized on the display) ,
- * a value of CONTEXT_NOT_CURRENT is returned.
+ * a value of {@link #CONTEXT_NOT_CURRENT} is returned.
* </p>
* <p>
* This method is blocking, i.e. waits until another thread has
@@ -273,11 +304,11 @@ public abstract class GLContext {
* and unlocked at {@link #release()}
* </p>
*
- * @return CONTEXT_CURRENT if the context was successfully made current
- * @return CONTEXT_CURRENT_NEW if the context was successfully made
- * current, but need to be initialized.
- *
- * @return CONTEXT_NOT_CURRENT if the context could not be made current.
+ * @return <ul>
+ * <li>{@link #CONTEXT_CURRENT_NEW} if the context was successfully made current the 1st time,</li>
+ * <li>{@link #CONTEXT_CURRENT} if the context was successfully made current,</li>
+ * <li>{@link #CONTEXT_NOT_CURRENT} if the context could not be made current.</li>
+ * </ul>
*
* @throws GLException if synchronization is disabled and the
* context is current on another thread, or because the context
@@ -425,27 +456,8 @@ public abstract class GLContext {
/**
* Returns the attached user object for the given name to this GLContext.
*/
- public final Object getAttachedObject(int name) {
- return attachedObjectsByInt.get(name);
- }
-
- /**
- * Returns the attached user object for the given name to this GLContext.
- */
public final Object getAttachedObject(String name) {
- return attachedObjectsByString.get(name);
- }
-
- /**
- * Sets the attached user object for the given name to this GLContext.
- * Returns the previously set object or null.
- */
- public final Object attachObject(int name, Object obj) {
- return attachedObjectsByInt.put(name, obj);
- }
-
- public final Object detachObject(int name) {
- return attachedObjectsByInt.remove(name);
+ return attachedObjects.get(name);
}
/**
@@ -453,11 +465,11 @@ public abstract class GLContext {
* Returns the previously set object or null.
*/
public final Object attachObject(String name, Object obj) {
- return attachedObjectsByString.put(name, obj);
+ return attachedObjects.put(name, obj);
}
public final Object detachObject(String name) {
- return attachedObjectsByString.remove(name);
+ return attachedObjects.remove(name);
}
/**
@@ -488,6 +500,12 @@ public abstract class GLContext {
sb.append(toHexString(contextHandle));
sb.append(", ");
sb.append(getGL());
+ sb.append(",\n\t quirks: ");
+ if(null != glRendererQuirks) {
+ glRendererQuirks.toString(sb);
+ } else {
+ sb.append("n/a");
+ }
if(getGLDrawable()!=getGLReadDrawable()) {
sb.append(",\n\tRead Drawable : ");
sb.append(getGLReadDrawable());
@@ -497,8 +515,6 @@ public abstract class GLContext {
sb.append(",\n\tDrawable: ");
sb.append(getGLDrawable());
}
- sb.append(", lock ");
- sb.append(lock.toString());
return sb;
}
@@ -616,6 +632,78 @@ public abstract class GLContext {
public final boolean isCreatedWithARBMethod() { return ( 0 != ( CTX_IS_ARB_CREATED & ctxOptions ) ); }
/**
+ * Returns the matching GLSL version number, queried by this context GL
+ * via {@link GL2ES2#GL_SHADING_LANGUAGE_VERSION} if ≥ ES2.0 or GL2.0,
+ * otherwise a static match is being utilized.
+ * <p>
+ * The context must have been current once, otherwise <code>null</code> is returned.
+ * </p>
+ * <p>
+ * Examples w/ <code>major.minor</code>:
+ * <pre>
+ * 1.00 (ES2.0), 1.10 (GL2.0), 1.20 (GL2.1), 1.50 GL(3.2),
+ * 3.30 (GL3.3), 4.40 (GL4.0)
+ * </pre >
+ * </p>
+ * <p>
+ * <i>Matching</i> could also refer to the maximum GLSL version usable by this context
+ * since <i>normal</i> GL implementations are capable of using a lower GLSL version as well.
+ * The latter is not true on OSX w/ a GL3 context.
+ * </p>
+ *
+ * @param GLSL version number if context has been made current at least once, otherwise <code>null</code>.
+ *
+ * @see #getGLVersionMajor()
+ * @see #getGLVersionMinor()
+ */
+ public final VersionNumber getGLSLVersionNumber() {
+ return ctxGLSLVersion;
+ }
+
+ /**
+ * Returns the GLSL version string as to be used in a shader program, including a terminating newline '\n',
+ * i.e.:
+ * <pre>
+ * #version 110
+ * </pre>
+ * <p>
+ * If context has not been made current, <code>null</code> is returned.
+ * </p>
+ * @see #getGLSLVersionNumber()
+ */
+ public final String getGLSLVersionString() {
+ if(null == ctxGLSLVersion) {
+ return null;
+ }
+ final int minor = ctxGLSLVersion.getMinor();
+ return "#version " + ctxGLSLVersion.getMajor() + ( minor < 10 ? "0"+minor : minor ) + "\n" ;
+ }
+
+ protected static final void getStaticGLSLVersionNumber(int glMajorVersion, int glMinorVersion, int ctxOptions, int[] res) {
+ if( 0 != ( CTX_PROFILE_ES & ctxOptions ) ) {
+ res[0] = 1; res[1] = 0; // ES 2.0 -> GLSL 1.00
+ } else if( 1 == glMajorVersion ) {
+ res[0] = 1; res[0] = 10; // GL 1.x -> GLSL 1.10
+ } else if( 2 == glMajorVersion ) {
+ res[0] = 1;
+ switch ( glMinorVersion ) {
+ case 0: res[1] = 10; break; // GL 2.0 -> GLSL 1.10
+ default: res[1] = 20; break; // GL 2.1 -> GLSL 1.20
+ }
+ } else if( 3 == glMajorVersion && 2 >= glMajorVersion ) {
+ res[0] = 1;
+ switch ( glMinorVersion ) {
+ case 0: res[1] = 30; break; // GL 3.0 -> GLSL 1.30
+ case 1: res[1] = 40; break; // GL 3.1 -> GLSL 1.40
+ default: res[1] = 50; break; // GL 3.2 -> GLSL 1.50
+ }
+ } else { // >= 3.3
+ res[0] = glMajorVersion; // GL M.N -> GLSL M.N
+ res[1] = glMinorVersion * 10;
+ }
+ }
+
+ /**
* @return true if this context is an ES2 context or implements
* the extension <code>GL_ARB_ES2_compatibility</code>, otherwise false
*/
@@ -625,12 +713,23 @@ public abstract class GLContext {
/**
* @return true if impl. is a hardware rasterizer, otherwise false.
+ * @see #isHardwareRasterizer(AbstractGraphicsDevice, GLProfile)
* @see GLProfile#isHardwareRasterizer()
*/
public final boolean isHardwareRasterizer() {
return 0 == ( ctxOptions & CTX_IMPL_ACCEL_SOFT ) ;
}
+ /**
+ * @return true if context supports GLSL, i.e. is either {@link #isGLES2()}, {@link #isGL3()} or {@link #isGL2()} <i>and</i> major-version > 1.
+ * @see GLProfile#hasGLSL()
+ */
+ public final boolean hasGLSL() {
+ return isGLES2() ||
+ isGL3() ||
+ isGL2() && ctxMajorVersion>1 ;
+ }
+
/**
* Returns <code>true</code> if basic FBO support is available, otherwise <code>false</code>.
* <p>
@@ -642,21 +741,56 @@ public abstract class GLContext {
* as well as limited internal formats for renderbuffer.
* </p>
* @see #CTX_IMPL_FBO
- * @see com.jogamp.opengl.FBObject#supportsBasicFBO(GL)
- * @see com.jogamp.opengl.FBObject#supportsFullFBO(GL)
*/
- public final boolean hasFBO() {
+ public final boolean hasBasicFBOSupport() {
return 0 != ( ctxOptions & CTX_IMPL_FBO ) ;
}
+ /**
+ * Returns <code>true</code> if full FBO support is available, otherwise <code>false</code>.
+ * <p>
+ * Full FBO is supported if the context is either GL >= core 3.0 or implements the extensions
+ * <code>ARB_framebuffer_object</code>, or all of
+ * <code>EXT_framebuffer_object</code>, <code>EXT_framebuffer_multisample</code>,
+ * <code>EXT_framebuffer_blit</code>, <code>GL_EXT_packed_depth_stencil</code>.
+ * </p>
+ * <p>
+ * Full FBO support includes multiple color attachments and multisampling.
+ * </p>
+ */
+ public final boolean hasFullFBOSupport() {
+ return !FORCE_MIN_FBO_SUPPORT && hasBasicFBOSupport() &&
+ ( isGL3() || // GL >= 3.0
+ isExtensionAvailable(GLExtensions.ARB_framebuffer_object) || // ARB_framebuffer_object
+ ( isExtensionAvailable(GLExtensions.EXT_framebuffer_object) && // All EXT_framebuffer_object*
+ isExtensionAvailable(GLExtensions.EXT_framebuffer_multisample) &&
+ isExtensionAvailable(GLExtensions.EXT_framebuffer_blit) &&
+ isExtensionAvailable(GLExtensions.EXT_packed_depth_stencil)
+ )
+ ) ;
+ }
+
/**
- * @return true if context supports GLSL
- * @see GLProfile#hasGLSL()
+ * Returns the maximum number of FBO RENDERBUFFER samples
+ * if {@link #hasFullFBOSupport() full FBO is supported}, otherwise false.
*/
- public final boolean hasGLSL() {
- return isGL2ES2() ;
+ public final int getMaxRenderbufferSamples() {
+ if( hasFullFBOSupport() ) {
+ final GL gl = getGL();
+ final int[] val = new int[] { 0 } ;
+ try {
+ gl.glGetIntegerv(GL2GL3.GL_MAX_SAMPLES, val, 0);
+ final int glerr = gl.glGetError();
+ if(GL.GL_NO_ERROR == glerr) {
+ return val[0];
+ } else if(DEBUG) {
+ System.err.println("GLContext.getMaxRenderbufferSamples: GL_MAX_SAMPLES query GL Error 0x"+Integer.toHexString(glerr));
+ }
+ } catch (GLException gle) { gle.printStackTrace(); }
+ }
+ return 0;
}
-
+
/** Note: The GL impl. may return a const value, ie {@link GLES2#isNPOTTextureAvailable()} always returns <code>true</code>. */
public boolean isNPOTTextureAvailable() {
return isGL3() || isGLES2Compatible() || isExtensionAvailable(GLExtensions.ARB_texture_non_power_of_two);
@@ -680,6 +814,12 @@ public abstract class GLContext {
&& 0 != (ctxOptions & (CTX_PROFILE_COMPAT|CTX_PROFILE_CORE));
}
+ /** Indicates whether this profile is capable of GL4 (core only). <p>Includes [ GL4 ].</p> */
+ public final boolean isGL4core() {
+ return ctxMajorVersion>=4 && 0 != (ctxOptions & CTX_IS_ARB_CREATED)
+ && 0 != (ctxOptions & CTX_PROFILE_CORE);
+ }
+
/** @see GLProfile#isGL3bc() */
public final boolean isGL3bc() {
return ( ctxMajorVersion>3 || ctxMajorVersion==3 && ctxMinorVersion>=1 )
@@ -694,6 +834,13 @@ public abstract class GLContext {
&& 0 != (ctxOptions & (CTX_PROFILE_COMPAT|CTX_PROFILE_CORE));
}
+ /** Indicates whether this profile is capable of GL3 (core only). <p>Includes [ GL4, GL3 ].</p> */
+ public final boolean isGL3core() {
+ return ( ctxMajorVersion>3 || ctxMajorVersion==3 && ctxMinorVersion>=1 )
+ && 0 != (ctxOptions & CTX_IS_ARB_CREATED)
+ && 0 != (ctxOptions & CTX_PROFILE_CORE);
+ }
+
/** @see GLProfile#isGL2() */
public final boolean isGL2() {
return ctxMajorVersion>=1 && 0!=(ctxOptions & CTX_PROFILE_COMPAT);
@@ -730,8 +877,8 @@ public abstract class GLContext {
}
/**
- * Set the swap interval if the current context.
- * @param interval Should be ≥ 0. 0 Disables the vertical synchronisation,
+ * Set the swap interval of the current context and attached drawable.
+ * @param interval Should be ≥ 0. 0 disables the vertical synchronization,
* where ≥ 1 is the number of vertical refreshes before a swap buffer occurs.
* A value < 0 is ignored.
* @return true if the operation was successful, otherwise false
@@ -741,9 +888,11 @@ public abstract class GLContext {
public final boolean setSwapInterval(int interval) throws GLException {
validateCurrent();
if(0<=interval) {
- if( setSwapIntervalImpl(interval) ) {
- currentSwapInterval = interval;
- return true;
+ if( !drawableRetargeted || !hasRendererQuirk(GLRendererQuirks.NoSetSwapIntervalPostRetarget) ) {
+ if( setSwapIntervalImpl(interval) ) {
+ currentSwapInterval = interval;
+ return true;
+ }
}
}
return false;
@@ -757,15 +906,12 @@ public abstract class GLContext {
* the default value <code>-1</code> is returned.
* </p>
* <p>
- * The default value for a valid context is <code>1</code> for
- * an EGL based profile (ES1 or ES2) and <code>-1</code> (undefined)
- * for desktop.
+ * For a valid context the default value is <code>1</code>
+ * in case of an EGL based profile (ES1 or ES2) and <code>-1</code>
+ * (undefined) for desktop.
* </p>
*/
public final int getSwapInterval() {
- if(-1 == currentSwapInterval && this.isGLES()) {
- currentSwapInterval = 1;
- }
return currentSwapInterval;
}
protected final void setDefaultSwapInterval() {
@@ -1036,6 +1182,9 @@ public abstract class GLContext {
validateProfileBits(profile, "profile");
validateProfileBits(resCtp, "resCtp");
+ if(FORCE_NO_FBO_SUPPORT) {
+ resCtp &= ~CTX_IMPL_FBO ;
+ }
if(DEBUG) {
System.err.println("GLContext.mapAvailableGLVersion: "+device+": "+getGLVersion(reqMajor, 0, profile, null)+" -> "+getGLVersion(resMajor, resMinor, resCtp, null));
// Thread.dumpStack();
@@ -1141,7 +1290,7 @@ public abstract class GLContext {
}
/**
- * Returns the GLProfile's major version number and it's context property (CTP) for availability mapping request.
+ * Returns the GLProfile's major version number at reqMajorCTP[0] and it's context property (CTP) at reqMajorCTP[1] for availability mapping request.
*/
protected static final void getRequestMajorAndCompat(final GLProfile glp, int[/*2*/] reqMajorCTP) {
final GLProfile glpImpl = glp.getImpl();
@@ -1149,7 +1298,9 @@ public abstract class GLContext {
reqMajorCTP[0]=4;
} else if (glpImpl.isGL3()) {
reqMajorCTP[0]=3;
- } else /* if (glpImpl.isGL2()) */ {
+ } else if (glpImpl.isGLES1()) {
+ reqMajorCTP[0]=1;
+ } else /* if (glpImpl.isGL2() || glpImpl.isGLES2()) */ {
reqMajorCTP[0]=2;
}
if( glpImpl.isGLES() ) {
@@ -1217,18 +1368,36 @@ public abstract class GLContext {
* FBO feature is implemented in OpenGL, hence it is {@link GLProfile} dependent.
* </p>
* <p>
- * FBO support is queried as described in {@link #hasFBO()}.
+ * FBO support is queried as described in {@link #hasBasicFBOSupport()}.
* </p>
*
* @param device the device to request whether FBO is available for
* @param glp {@link GLProfile} to check for FBO capabilities
- * @see GLContext#hasFBO()
+ * @see GLContext#hasBasicFBOSupport()
*/
public static final boolean isFBOAvailable(AbstractGraphicsDevice device, GLProfile glp) {
return 0 != ( CTX_IMPL_FBO & getAvailableContextProperties(device, glp) );
}
/**
+ * @return <code>1</code> if using a hardware rasterizer, <code>0</code> if using a software rasterizer and <code>-1</code> if not determined yet.
+ * @see GLContext#isHardwareRasterizer()
+ * @see GLProfile#isHardwareRasterizer()
+ */
+ public static final int isHardwareRasterizer(AbstractGraphicsDevice device, GLProfile glp) {
+ final int r;
+ final int ctp = getAvailableContextProperties(device, glp);
+ if(0 == ctp) {
+ r = -1;
+ } else if( 0 == ( CTX_IMPL_ACCEL_SOFT & ctp ) ) {
+ r = 1;
+ } else {
+ r = 0;
+ }
+ return r;
+ }
+
+ /**
* @param device the device to request whether the profile is available for
* @param reqMajor Key Value either 1, 2, 3 or 4
* @param reqProfile Key Value either {@link #CTX_PROFILE_COMPAT}, {@link #CTX_PROFILE_CORE} or {@link #CTX_PROFILE_ES}
@@ -1326,6 +1495,6 @@ public abstract class GLContext {
protected static String getThreadName() {
return Thread.currentThread().getName();
}
-
+
}
diff --git a/src/jogl/classes/javax/media/opengl/GLDrawable.java b/src/jogl/classes/javax/media/opengl/GLDrawable.java
index 10eea2e..c0910eb 100644
--- a/src/jogl/classes/javax/media/opengl/GLDrawable.java
+++ b/src/jogl/classes/javax/media/opengl/GLDrawable.java
@@ -149,7 +149,7 @@ public interface GLDrawable {
This object shall be directly associated to the attached {@link NativeSurface}'s
{@link AbstractGraphicsConfiguration}, and if changes are necessary,
they should reflect those as well.
- @return A copy of the queried object.
+ @return The immutable queried instance.
*/
public GLCapabilitiesImmutable getChosenGLCapabilities();
diff --git a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
index 9a0d2cb..70480e7 100644
--- a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
+++ b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
@@ -48,14 +48,17 @@ import java.util.List;
import com.jogamp.common.JogampRuntimeException;
import com.jogamp.common.util.ReflectionUtil;
+import com.jogamp.opengl.GLAutoDrawableDelegate;
+import com.jogamp.opengl.GLRendererQuirks;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.CapabilitiesImmutable;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.ProxySurface;
-import javax.media.nativewindow.ProxySurface.UpstreamSurfaceHook;
-import javax.media.opengl.GLProfile.ShutdownType;
+import javax.media.nativewindow.UpstreamSurfaceHook;
import jogamp.opengl.Debug;
@@ -94,9 +97,28 @@ import jogamp.opengl.Debug;
*/
public abstract class GLDrawableFactory {
+ protected static final boolean DEBUG = Debug.debug("GLDrawable");
+
+ /**
+ * We have to disable support for ANGLE, the D3D ES2 emulation on Windows provided w/ Firefox and Chrome.
+ * When run in the mentioned browsers, the eglInitialize(..) implementation crashes.
+ * <p>
+ * This can be overridden by explicitly enabling ANGLE on Windows by setting the property
+ * <code>jogl.enable.ANGLE</code>.
+ * </p>
+ */
+ protected static final boolean enableANGLE = Debug.isPropertyDefined("jogl.enable.ANGLE", true);
+
+ /**
+ * In case no OpenGL ES implementation is required
+ * and if the running platform may have a buggy implementation,
+ * setting the property <code>jogl.disable.opengles</code> disables querying a possible existing OpenGL ES implementation.
+ */
+ protected static final boolean disableOpenGLES = Debug.isPropertyDefined("jogl.disable.opengles", true);
+
static final String macosxFactoryClassNameCGL = "jogamp.opengl.macosx.cgl.MacOSXCGLDrawableFactory";
static final String macosxFactoryClassNameAWTCGL = "jogamp.opengl.macosx.cgl.awt.MacOSXAWTCGLDrawableFactory";
-
+
private static volatile boolean isInit = false;
private static GLDrawableFactory eglFactory;
private static GLDrawableFactory nativeOSFactory;
@@ -106,6 +128,7 @@ public abstract class GLDrawableFactory {
// Shutdown hook mechanism for the factory
private static boolean factoryShutdownHookRegistered = false;
private static Thread factoryShutdownHook = null;
+ private static volatile boolean isJVMShuttingDown = false;
/**
* Instantiate singleton factories if available, EGLES1, EGLES2 and the OS native ones.
@@ -123,16 +146,16 @@ public abstract class GLDrawableFactory {
private static final void initSingletonImpl() {
registerFactoryShutdownHook();
- final String nativeOSType = NativeWindowFactory.getNativeWindowType(true);
+ final String nwt = NativeWindowFactory.getNativeWindowType(true);
GLDrawableFactory tmp = null;
String factoryClassName = Debug.getProperty("jogl.gldrawablefactory.class.name", true);
ClassLoader cl = GLDrawableFactory.class.getClassLoader();
if (null == factoryClassName) {
- if ( nativeOSType.equals(NativeWindowFactory.TYPE_X11) ) {
+ if ( nwt == NativeWindowFactory.TYPE_X11 ) {
factoryClassName = "jogamp.opengl.x11.glx.X11GLXDrawableFactory";
- } else if ( nativeOSType.equals(NativeWindowFactory.TYPE_WINDOWS) ) {
+ } else if ( nwt == NativeWindowFactory.TYPE_WINDOWS ) {
factoryClassName = "jogamp.opengl.windows.wgl.WindowsWGLDrawableFactory";
- } else if ( nativeOSType.equals(NativeWindowFactory.TYPE_MACOSX) ) {
+ } else if ( nwt == NativeWindowFactory.TYPE_MACOSX ) {
if(ReflectionUtil.isClassAvailable(macosxFactoryClassNameAWTCGL, cl)) {
factoryClassName = macosxFactoryClassNameAWTCGL;
} else {
@@ -140,53 +163,64 @@ public abstract class GLDrawableFactory {
}
} else {
// may use egl*Factory ..
- if (GLProfile.DEBUG) {
- System.err.println("GLDrawableFactory.static - No native OS Factory for: "+nativeOSType+"; May use EGLDrawableFactory, if available." );
+ if (DEBUG || GLProfile.DEBUG) {
+ System.err.println("GLDrawableFactory.static - No native Windowing Factory for: "+nwt+"; May use EGLDrawableFactory, if available." );
}
}
}
if (null != factoryClassName) {
- if (GLProfile.DEBUG) {
- System.err.println("GLDrawableFactory.static - Native OS Factory for: "+nativeOSType+": "+factoryClassName);
+ if (DEBUG || GLProfile.DEBUG) {
+ System.err.println("GLDrawableFactory.static - Native OS Factory for: "+nwt+": "+factoryClassName);
}
try {
tmp = (GLDrawableFactory) ReflectionUtil.createInstance(factoryClassName, cl);
} catch (JogampRuntimeException jre) {
- if (GLProfile.DEBUG) {
- System.err.println("Info: GLDrawableFactory.static - Native Platform: "+nativeOSType+" - not available: "+factoryClassName);
+ if (DEBUG || GLProfile.DEBUG) {
+ System.err.println("Info: GLDrawableFactory.static - Native Platform: "+nwt+" - not available: "+factoryClassName);
jre.printStackTrace();
}
}
}
- nativeOSFactory = tmp;
-
+ if(null != tmp && tmp.isComplete()) {
+ nativeOSFactory = tmp;
+ }
tmp = null;
- try {
- tmp = (GLDrawableFactory) ReflectionUtil.createInstance("jogamp.opengl.egl.EGLDrawableFactory", cl);
- } catch (JogampRuntimeException jre) {
- if (GLProfile.DEBUG) {
- System.err.println("Info: GLDrawableFactory.static - EGLDrawableFactory - not available");
- jre.printStackTrace();
+
+ if(!disableOpenGLES) {
+ try {
+ tmp = (GLDrawableFactory) ReflectionUtil.createInstance("jogamp.opengl.egl.EGLDrawableFactory", cl);
+ } catch (JogampRuntimeException jre) {
+ if (DEBUG || GLProfile.DEBUG) {
+ System.err.println("Info: GLDrawableFactory.static - EGLDrawableFactory - not available");
+ jre.printStackTrace();
+ }
+ }
+ if(null != tmp && tmp.isComplete()) {
+ eglFactory = tmp;
}
+ } else if( DEBUG || GLProfile.DEBUG ) {
+ System.err.println("Info: GLDrawableFactory.static - EGLDrawableFactory - disabled!");
}
- eglFactory = tmp;
}
- protected static void shutdown(ShutdownType shutdownType) {
+ protected static void shutdown() {
if (isInit) { // volatile: ok
synchronized (GLDrawableFactory.class) {
if (isInit) {
isInit=false;
- unregisterFactoryShutdownHook();
- shutdownImpl(shutdownType);
+ shutdownImpl();
}
}
}
}
- private static void shutdownImpl(ShutdownType shutdownType) {
+
+ private static void shutdownImpl() {
+ // Following code will _always_ remain in shutdown hook
+ // due to special semantics of native utils, i.e. X11Utils.
+ // The latter requires shutdown at JVM-Shutdown only.
synchronized(glDrawableFactories) {
for(int i=0; i<glDrawableFactories.size(); i++) {
- glDrawableFactories.get(i).destroy(shutdownType);
+ glDrawableFactories.get(i).destroy();
}
glDrawableFactories.clear();
@@ -194,6 +228,8 @@ public abstract class GLDrawableFactory {
nativeOSFactory = null;
eglFactory = null;
}
+ GLContext.shutdown();
+ NativeWindowFactory.shutdown(isJVMShuttingDown);
}
private static synchronized void registerFactoryShutdownHook() {
@@ -202,7 +238,8 @@ public abstract class GLDrawableFactory {
}
factoryShutdownHook = new Thread(new Runnable() {
public void run() {
- GLDrawableFactory.shutdownImpl(GLProfile.ShutdownType.COMPLETE);
+ isJVMShuttingDown = true;
+ GLDrawableFactory.shutdownImpl();
}
});
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@@ -214,30 +251,19 @@ public abstract class GLDrawableFactory {
factoryShutdownHookRegistered = true;
}
- private static synchronized void unregisterFactoryShutdownHook() {
- if (!factoryShutdownHookRegistered) {
- return;
- }
- AccessController.doPrivileged(new PrivilegedAction<Object>() {
- public Object run() {
- Runtime.getRuntime().removeShutdownHook(factoryShutdownHook);
- return null;
- }
- });
- factoryShutdownHookRegistered = false;
- }
-
-
protected GLDrawableFactory() {
synchronized(glDrawableFactories) {
glDrawableFactories.add(this);
}
}
+
+ /** Returns true if this factory is complete, i.e. ready to be used. Otherwise return false. */
+ protected abstract boolean isComplete();
protected void enterThreadCriticalZone() {};
protected void leaveThreadCriticalZone() {};
- protected abstract void destroy(ShutdownType shutdownType);
+ protected abstract void destroy();
/**
* Retrieve the default <code>device</code> {@link AbstractGraphicsDevice#getConnection() connection},
@@ -306,6 +332,42 @@ public abstract class GLDrawableFactory {
protected abstract boolean createSharedResource(AbstractGraphicsDevice device);
/**
+ * Returns true if the <code>quirk</code> exist in the shared resource's context {@link GLRendererQuirks}.
+ * <p>
+ * Convenience method for:
+ * <pre>
+ final GLRendererQuirks glrq = factory.getRendererQuirks(device);
+ return null != glrq ? glrq.exist(quirk) : false;
+ * </pre>
+ * </p>
+ *
+ * @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be <code>null</code> for the platform's default device.
+ * @param quirk the quirk to be tested, e.g. {@link GLRendererQuirks#NoDoubleBufferedPBuffer}.
+ * @throws IllegalArgumentException if the quirk is out of range
+ * @see #getRendererQuirks()
+ * @see GLRendererQuirks
+ */
+ public final boolean hasRendererQuirk(AbstractGraphicsDevice device, int quirk) {
+ final GLRendererQuirks glrq = getRendererQuirks(device);
+ return null != glrq ? glrq.exist(quirk) : false;
+ }
+
+ /**
+ * Returns the shared resource's context {@link GLRendererQuirks}.
+ * <p>
+ * Implementation calls {@link GLContext#getRendererQuirks()} on the shared resource context.
+ * </p>
+ * <p>
+ * In case no shared device exist yet or the implementation doesn't support tracking quirks,
+ * the result is always <code>null</code>.
+ * </p>
+ * @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be <code>null</code> for the platform's default device.
+ * @see GLContext#getRendererQuirks()
+ * @see GLRendererQuirks
+ */
+ public abstract GLRendererQuirks getRendererQuirks(AbstractGraphicsDevice device);
+
+ /**
* Returns the sole GLDrawableFactory instance for the desktop (X11, WGL, ..) if exist or null
*/
public static GLDrawableFactory getDesktopFactory() {
@@ -374,44 +436,63 @@ public abstract class GLDrawableFactory {
// Methods to create high-level objects
/**
- * Returns a GLDrawable according to it's chosen Capabilities,<br>
+ * Returns a GLDrawable according to it's chosen {@link GLCapabilitiesImmutable},<br>
* which determines pixel format, on- and offscreen incl. PBuffer type.
* <p>
- * The native platform's chosen Capabilties are referenced within the target
- * NativeSurface's AbstractGraphicsConfiguration.<p>
- *
- * In case target's {@link javax.media.nativewindow.Capabilities#isOnscreen()} is true,<br>
- * an onscreen GLDrawable will be realized.
+ * The chosen {@link GLCapabilitiesImmutable} are referenced within the target
+ * {@link NativeSurface}'s {@link AbstractGraphicsConfiguration}.<p>
+ * </p>
* <p>
- * In case target's {@link javax.media.nativewindow.Capabilities#isOnscreen()} is false,<br>
- * either a Pbuffer drawable is created if target's {@link javax.media.opengl.GLCapabilities#isPBuffer()} is true,<br>
- * or a simple pixmap/bitmap drawable is created. The latter is unlikely to be hardware accelerated.<br>
+ * An onscreen GLDrawable is created if {@link CapabilitiesImmutable#isOnscreen() caps.isOnscreen()} is true.
+ * </p>
* <p>
- *
+ * A FBO drawable is created if both {@link GLCapabilitiesImmutable#isFBO() caps.isFBO()}
+ * and {@link GLContext#isFBOAvailable(AbstractGraphicsDevice, GLProfile) canCreateFBO(device, caps.getGLProfile())} is true.
+ * </p>
+ * <p>
+ * A Pbuffer drawable is created if both {@link GLCapabilitiesImmutable#isPBuffer() caps.isPBuffer()}
+ * and {@link #canCreateGLPbuffer(AbstractGraphicsDevice) canCreateGLPbuffer(device)} is true.
+ * </p>
+ * <p>
+ * If not onscreen and neither FBO nor Pbuffer is available,
+ * a simple pixmap/bitmap drawable/surface is created, which is unlikely to be hardware accelerated.
+ * </p>
+ *
* @throws IllegalArgumentException if the passed target is null
* @throws GLException if any window system-specific errors caused
* the creation of the GLDrawable to fail.
*
+ * @see #canCreateGLPbuffer(AbstractGraphicsDevice)
+ * @see GLContext#isFBOAvailable(AbstractGraphicsDevice, GLProfile)
+ * @see javax.media.opengl.GLCapabilities#isOnscreen()
+ * @see javax.media.opengl.GLCapabilities#isFBO()
+ * @see javax.media.opengl.GLCapabilities#isPBuffer()
* @see javax.media.nativewindow.GraphicsConfigurationFactory#chooseGraphicsConfiguration(Capabilities, CapabilitiesChooser, AbstractGraphicsScreen)
*/
public abstract GLDrawable createGLDrawable(NativeSurface target)
throws IllegalArgumentException, GLException;
-
+
/**
- * Creates a Offscreen GLDrawable incl it's offscreen {@link javax.media.nativewindow.NativeSurface} with the given capabilites and dimensions.
+ * Creates an {@link GLOffscreenAutoDrawable} incl it's offscreen {@link javax.media.nativewindow.NativeSurface} with the given capabilites and dimensions.
+ * <p>
+ * The {@link GLOffscreenAutoDrawable}'s {@link GLDrawable} is realized and it's {@link GLContext} assigned but not yet made current.
+ * </p>
* <p>
- * It's {@link AbstractGraphicsConfiguration} is properly set according to the given {@link GLCapabilitiesImmutable}, see below.
+ * In case the passed {@link GLCapabilitiesImmutable} contains default values, i.e.
+ * {@link GLCapabilitiesImmutable#isOnscreen() caps.isOnscreen()} <code> == true</code>,
+ * it is auto-configured. The latter will set offscreen and also FBO <i>or</i> Pbuffer, whichever is available in that order.
* </p>
* <p>
- * A FBO drawable is created if both {@link javax.media.opengl.GLCapabilities#isFBO() caps.isFBO()}
+ * A FBO based auto drawable, {@link GLOffscreenAutoDrawable.FBO}, is created if both {@link GLCapabilitiesImmutable#isFBO() caps.isFBO()}
* and {@link GLContext#isFBOAvailable(AbstractGraphicsDevice, GLProfile) canCreateFBO(device, caps.getGLProfile())} is true.
* </p>
* <p>
- * A Pbuffer drawable is created if both {@link javax.media.opengl.GLCapabilities#isPBuffer() caps.isPBuffer()}
- * and {@link #canCreateGLPbuffer(javax.media.nativewindow.AbstractGraphicsDevice) canCreateGLPbuffer(device)} is true.
+ * A Pbuffer based auto drawable is created if both {@link GLCapabilitiesImmutable#isPBuffer() caps.isPBuffer()}
+ * and {@link #canCreateGLPbuffer(AbstractGraphicsDevice) canCreateGLPbuffer(device)} is true.
* </p>
* <p>
- * If neither FBO nor Pbuffer is available, a simple pixmap/bitmap drawable/surface is created, which is unlikely to be hardware accelerated.
+ * If neither FBO nor Pbuffer is available,
+ * a simple pixmap/bitmap auto drawable is created, which is unlikely to be hardware accelerated.
* </p>
*
* @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared device to be used, may be <code>null</code> for the platform's default device.
@@ -419,17 +500,55 @@ public abstract class GLDrawableFactory {
* @param chooser the custom chooser, may be null for default
* @param width the requested offscreen width
* @param height the requested offscreen height
+ * @return the created and initialized offscreen {@link GLOffscreenAutoDrawable} instance
*
- * @return the created offscreen GLDrawable
+ * @throws GLException if any window system-specific errors caused
+ * the creation of the Offscreen to fail.
+ *
+ * @see #createOffscreenDrawable(AbstractGraphicsDevice, GLCapabilitiesImmutable, GLCapabilitiesChooser, int, int)
+ */
+ public abstract GLOffscreenAutoDrawable createOffscreenAutoDrawable(AbstractGraphicsDevice device,
+ GLCapabilitiesImmutable caps,
+ GLCapabilitiesChooser chooser,
+ int width, int height,
+ GLContext shareWith) throws GLException;
+ /**
+ * Creates a offscreen {@link GLDrawable} incl it's offscreen {@link javax.media.nativewindow.NativeSurface} with the given capabilites and dimensions.
+ * <p>
+ * In case the passed {@link GLCapabilitiesImmutable} contains default values, i.e.
+ * {@link GLCapabilitiesImmutable#isOnscreen() caps.isOnscreen()} <code> == true</code>,
+ * it is auto-configured. The latter will set offscreen and also FBO <i>or</i> Pbuffer, whichever is available in that order.
+ * </p>
+ * <p>
+ * A resizeable FBO drawable, {@link GLFBODrawable.Resizeable}, is created if both {@link GLCapabilitiesImmutable#isFBO() caps.isFBO()}
+ * and {@link GLContext#isFBOAvailable(AbstractGraphicsDevice, GLProfile) canCreateFBO(device, caps.getGLProfile())} is true.
+ * </p>
+ * <p>
+ * A Pbuffer drawable is created if both {@link GLCapabilitiesImmutable#isPBuffer() caps.isPBuffer()}
+ * and {@link #canCreateGLPbuffer(AbstractGraphicsDevice) canCreateGLPbuffer(device)} is true.
+ * </p>
+ * <p>
+ * If neither FBO nor Pbuffer is available,
+ * a simple pixmap/bitmap drawable is created, which is unlikely to be hardware accelerated.
+ * </p>
+ *
+ * @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared device to be used, may be <code>null</code> for the platform's default device.
+ * @param caps the requested GLCapabilties
+ * @param chooser the custom chooser, may be null for default
+ * @param width the requested offscreen width
+ * @param height the requested offscreen height
+ *
+ * @return the created offscreen {@link GLDrawable}
*
* @throws GLException if any window system-specific errors caused
* the creation of the Offscreen to fail.
+ *
+ * @see #createOffscreenAutoDrawable(AbstractGraphicsDevice, GLCapabilitiesImmutable, GLCapabilitiesChooser, int, int, GLContext)
*/
public abstract GLDrawable createOffscreenDrawable(AbstractGraphicsDevice device,
- GLCapabilitiesImmutable capabilities,
+ GLCapabilitiesImmutable caps,
GLCapabilitiesChooser chooser,
- int width, int height)
- throws GLException;
+ int width, int height) throws GLException;
/**
* Creates a proxy {@link NativeSurface} w/ defined surface handle, i.e. a {@link WrappedSurface} or {@link GDISurface} instance.
@@ -460,6 +579,21 @@ public abstract class GLDrawableFactory {
GLCapabilitiesImmutable caps, GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstream);
/**
+ * Returns true if it is possible to create an <i>framebuffer object</i> (FBO).
+ * <p>
+ * FBO feature is implemented in OpenGL, hence it is {@link GLProfile} dependent.
+ * </p>
+ * <p>
+ * FBO support is queried as described in {@link GLContext#hasBasicFBOSupport()}.
+ * </p>
+ *
+ * @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be <code>null</code> for the platform's default device.
+ * @param glp {@link GLProfile} to check for FBO capabilities
+ * @see GLContext#hasBasicFBOSupport()
+ */
+ public abstract boolean canCreateFBO(AbstractGraphicsDevice device, GLProfile glp);
+
+ /**
* Returns true if it is possible to create a GLPbuffer. Some older
* graphics cards do not have this capability.
*
@@ -468,7 +602,10 @@ public abstract class GLDrawableFactory {
public abstract boolean canCreateGLPbuffer(AbstractGraphicsDevice device);
/**
- * Creates a GLPbuffer with the given capabilites and dimensions. <P>
+ * Creates a GLPbuffer {@link GLAutoDrawable} with the given capabilites and dimensions.
+ * <p>
+ * The GLPbuffer drawable is realized and initialized eagerly.
+ * </p>
*
* See the note in the overview documentation on
* <a href="../../../overview-summary.html#SHARING">context sharing</a>.
@@ -480,10 +617,12 @@ public abstract class GLDrawableFactory {
* @param initialHeight initial height of pbuffer
* @param shareWith a shared GLContext this GLPbuffer shall use
*
- * @return the new {@link GLPbuffer} specific {@link GLAutoDrawable}
+ * @return the created and initialized {@link GLPbuffer} instance
*
* @throws GLException if any window system-specific errors caused
* the creation of the GLPbuffer to fail.
+ *
+ * @deprecated {@link GLPbuffer} is deprecated, use {@link #createOffscreenAutoDrawable(AbstractGraphicsDevice, GLCapabilitiesImmutable, GLCapabilitiesChooser, int, int, GLContext)}
*/
public abstract GLPbuffer createGLPbuffer(AbstractGraphicsDevice device,
GLCapabilitiesImmutable capabilities,
diff --git a/src/jogl/classes/javax/media/opengl/GLFBODrawable.java b/src/jogl/classes/javax/media/opengl/GLFBODrawable.java
new file mode 100644
index 0000000..079d9af
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/GLFBODrawable.java
@@ -0,0 +1,175 @@
+/**
+ * Copyright 2012 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community OR
+ * CONTRIBUTORS 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.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package javax.media.opengl;
+
+import javax.media.nativewindow.NativeWindowException;
+
+import com.jogamp.opengl.FBObject;
+import com.jogamp.opengl.FBObject.TextureAttachment;
+
+/**
+ * Platform-independent {@link GLDrawable} specialization,
+ * exposing {@link FBObject} functionality.
+ *
+ * <p>
+ * A {@link GLFBODrawable} is uninitialized until a {@link GLContext} is bound
+ * and made current the first time, hence only then it's capabilities <i>fully</i> reflect expectations,
+ * i.e. color, depth, stencil and MSAA bits will be <i>valid</i> only after the first {@link GLContext#makeCurrent() makeCurrent()} call.
+ * On-/offscreen bits are <i>valid</i> after {@link #setRealized(boolean) setRealized(true)}.
+ * </p>
+ *
+ * <p>
+ * MSAA is used if {@link GLCapabilitiesImmutable#getNumSamples() requested}.
+ * </p>
+ * <p>
+ * Double buffering is used if {@link GLCapabilitiesImmutable#getDoubleBuffered() requested}.
+ * </p>
+ * <p>
+ * In MSAA mode, it always uses the implicit 2nd {@link FBObject framebuffer} {@link FBObject#getSamplingSinkFBO() sink}.
+ * Hence double buffering is always the case w/ MSAA.
+ * </p>
+ * <p>
+ * In non MSAA a second explicit {@link FBObject framebuffer} is being used.
+ * This method allows compliance w/ the spec, i.e. read and draw framebuffer selection
+ * and double buffer usage for e.g. {@link GL#glReadPixels(int, int, int, int, int, int, java.nio.Buffer) glReadPixels(..)}.
+ * This method also allows usage of both textures seperately.
+ * </p>
+ * <p>
+ * It would be possible to implement double buffering simply using
+ * {@link FBObject.TextureAttachment texture attachment}s with one {@link FBObject framebuffer}.
+ * This would require mode selection and hence complicate the API. Besides, it would
+ * not support differentiation of read and write framebuffer and hence not be spec compliant.
+ * </p>
+ * <p>
+ * Actual swapping of the {@link FBObject.TextureAttachment texture}s or {@link FBObject framebuffer}
+ * is performed either in the {@link #contextMadeCurrent(boolean) context current hook}
+ * or when {@link #swapBuffersImpl(boolean) swapping buffers}, whatever comes first.<br/>
+ * </p>
+ */
+public interface GLFBODrawable extends GLDrawable {
+ // public enum DoubleBufferMode { NONE, TEXTURE, FBO }; // TODO: Add or remove TEXTURE (only) DoubleBufferMode support
+
+ /**
+ * @return <code>true</code> if initialized, i.e. a {@link GLContext} is bound and made current once, otherwise <code>false</code>.
+ */
+ public boolean isInitialized();
+
+ /**
+ * Notify this instance about upstream size change
+ * to reconfigure the {@link FBObject}.
+ * @param gl GL context object bound to this drawable, will be made current during operation.
+ * A prev. current context will be make current after operation.
+ * @throws GLException if resize operation failed
+ */
+ void resetSize(GL gl) throws GLException;
+
+ /**
+ * @return the used texture unit
+ */
+ int getTextureUnit();
+
+ /**
+ *
+ * @param unit the texture unit to be used
+ */
+ void setTextureUnit(int unit);
+
+ /**
+ * Set a new sample size
+ * @param gl GL context object bound to this drawable, will be made current during operation.
+ * A prev. current context will be make current after operation.
+ * @param newSamples new sample size
+ * @throws GLException if resetting the FBO failed
+ */
+ void setNumSamples(GL gl, int newSamples) throws GLException;
+
+ /**
+ * @return the number of sample buffers if using MSAA, otherwise 0
+ */
+ int getNumSamples();
+
+ /**
+ * @return the used {@link DoubleBufferMode}
+ */
+ // DoubleBufferMode getDoubleBufferMode(); // TODO: Add or remove TEXTURE (only) DoubleBufferMode support
+
+ /**
+ * Sets the {@link DoubleBufferMode}. Must be called before {@link #isInitialized() initialization},
+ * otherwise an exception is thrown.
+ * <p>
+ * This call has no effect is MSAA is selected, since MSAA always forces the mode to {@link DoubleBufferMode#FBO FBO}.
+ * Also setting the mode to {@link DoubleBufferMode#NONE NONE} where double buffering is {@link GLCapabilitiesImmutable#getDoubleBuffered() requested}
+ * or setting a double buffering mode w/o {@link GLCapabilitiesImmutable#getDoubleBuffered() request} will be ignored.
+ * </p>
+ * <p>
+ * Since {@link DoubleBufferMode#TEXTURE TEXTURE} mode is currently not implemented, this method has no effect.
+ * </p>
+ * @throws GLException if already initialized, see {@link #isInitialized()}.
+ */
+ // void setDoubleBufferMode(DoubleBufferMode mode) throws GLException; // TODO: Add or remove TEXTURE (only) DoubleBufferMode support
+
+ /**
+ * If MSAA is being used and {@link GL#GL_FRONT} is requested,
+ * the internal {@link FBObject} {@link FBObject#getSamplingSinkFBO() sample sink} is being returned.
+ *
+ * @param bufferName {@link GL#GL_FRONT} and {@link GL#GL_BACK} are valid buffer names
+ * @return the named {@link FBObject}
+ * @throws IllegalArgumentException if an illegal buffer name is being used
+ */
+ FBObject getFBObject(int bufferName) throws IllegalArgumentException;
+
+ /**
+ * Returns the named texture buffer.
+ * <p>
+ * If MSAA is being used, only the {@link GL#GL_FRONT} buffer is accessible
+ * and an exception is being thrown if {@link GL#GL_BACK} is being requested.
+ * </p>
+ * @param bufferName {@link GL#GL_FRONT} and {@link GL#GL_BACK} are valid buffer names
+ * @return the named {@link TextureAttachment}
+ * @throws IllegalArgumentException if using MSAA and {@link GL#GL_BACK} is requested or an illegal buffer name is being used
+ */
+ FBObject.TextureAttachment getTextureBuffer(int bufferName) throws IllegalArgumentException;
+
+ /** Resizeable {@link GLFBODrawable} specialization */
+ public interface Resizeable extends GLFBODrawable {
+ /**
+ * Resize this drawable.
+ * <p>
+ * This drawable is being locked during operation.
+ * </p>
+ * @param context the {@link GLContext} bound to this drawable, will be made current during operation
+ * A prev. current context will be make current after operation.
+ * @param newWidth
+ * @param newHeight
+ * @throws NativeWindowException in case the surface could no be locked
+ * @throws GLException in case an error during the resize operation occurred
+ */
+ void setSize(GLContext context, int newWidth, int newHeight) throws NativeWindowException, GLException;
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/util/AWTKeyAdapter.java b/src/jogl/classes/javax/media/opengl/GLOffscreenAutoDrawable.java
similarity index 57%
copy from src/test/com/jogamp/opengl/test/junit/util/AWTKeyAdapter.java
copy to src/jogl/classes/javax/media/opengl/GLOffscreenAutoDrawable.java
index 6c01561..6fe76a3 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/AWTKeyAdapter.java
+++ b/src/jogl/classes/javax/media/opengl/GLOffscreenAutoDrawable.java
@@ -1,5 +1,5 @@
/**
- * Copyright 2010 JogAmp Community. All rights reserved.
+ * Copyright 2012 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
@@ -25,50 +25,39 @@
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of JogAmp Community.
*/
-
-package com.jogamp.opengl.test.junit.util;
-import java.awt.event.KeyEvent;
+package javax.media.opengl;
-public class AWTKeyAdapter extends java.awt.event.KeyAdapter implements InputEventCountAdapter {
+import javax.media.nativewindow.NativeWindowException;
- String prefix;
- int keyTyped;
- boolean pressed;
+import com.jogamp.opengl.FBObject;
- public AWTKeyAdapter(String prefix) {
- this.prefix = prefix;
- reset();
- }
-
- public boolean isPressed() {
- return pressed;
- }
+/**
+ * Platform-independent {@link GLAutoDrawable} specialization,
+ * exposing offscreen functionality.
+ * <p>
+ * This class distinguishes itself from {@link GLAutoDrawable}
+ * with it's {@link #setSize(int, int)} functionality.
+ * </p>
+ */
+public interface GLOffscreenAutoDrawable extends GLAutoDrawable {
- public int getCount() {
- return keyTyped;
- }
-
- public void reset() {
- keyTyped = 0;
- pressed = false;
- }
-
- public void keyPressed(KeyEvent e) {
- pressed = true;
- System.err.println("KEY AWT PRESSED ["+pressed+"]: "+prefix+", "+e);
- }
-
- public void keyReleased(KeyEvent e) {
- pressed = false;
- System.err.println("KEY AWT RELEASED ["+pressed+"]: "+prefix+", "+e);
- }
-
- public void keyTyped(java.awt.event.KeyEvent e) {
- ++keyTyped;
- System.err.println("KEY AWT TYPED ["+keyTyped+"]: "+prefix+", "+e);
- }
+ /**
+ * Resize this auto drawable.
+ * @param newWidth
+ * @param newHeight
+ * @throws NativeWindowException in case the surface could no be locked
+ * @throws GLException in case of an error during the resize operation
+ */
+ void setSize(int newWidth, int newHeight) throws NativeWindowException, GLException;
+
+ /**
+ * Set the upstream UI toolkit object.
+ * @see #getUpstreamWidget()
+ */
+ void setUpstreamWidget(Object newUpstreamWidget);
- public String toString() { return prefix+"[pressed "+pressed+", typed "+keyTyped+"]"; }
+ /** {@link FBObject} based {@link GLOffscreenAutoDrawable} specialization */
+ public interface FBO extends GLOffscreenAutoDrawable, GLFBODrawable {
+ }
}
-
diff --git a/src/jogl/classes/javax/media/opengl/GLPbuffer.java b/src/jogl/classes/javax/media/opengl/GLPbuffer.java
index 273a992..de7731a 100644
--- a/src/jogl/classes/javax/media/opengl/GLPbuffer.java
+++ b/src/jogl/classes/javax/media/opengl/GLPbuffer.java
@@ -45,7 +45,11 @@ package javax.media.opengl;
contains experimental methods for accessing the pbuffer's contents
as a texture map and enabling rendering to floating-point frame
buffers. These methods are not guaranteed to be supported on all
- platforms and may be deprecated in a future release. */
+ platforms and may be deprecated in a future release.
+
+ @deprecated Use {@link GLOffscreenAutoDrawable} w/ {@link GLCapabilities#setFBO(boolean)}
+ via {@link GLDrawableFactory#createOffscreenAutoDrawable(javax.media.nativewindow.AbstractGraphicsDevice, GLCapabilitiesImmutable, GLCapabilitiesChooser, int, int, GLContext) GLDrawableFactory.createOffscreenAutoDrawable(..)}.
+ */
public interface GLPbuffer extends GLAutoDrawable {
/** Indicates the GL_APPLE_float_pixels extension is being used for this pbuffer. */
diff --git a/src/jogl/classes/javax/media/opengl/GLProfile.java b/src/jogl/classes/javax/media/opengl/GLProfile.java
index 1e10dc9..f916ab8 100644
--- a/src/jogl/classes/javax/media/opengl/GLProfile.java
+++ b/src/jogl/classes/javax/media/opengl/GLProfile.java
@@ -77,23 +77,6 @@ public class GLProfile {
public static final boolean DEBUG = Debug.debug("GLProfile");
- /**
- * We have to disable support for ANGLE, the D3D ES2 emulation on Windows provided w/ Firefox and Chrome.
- * When run in the mentioned browsers, the eglInitialize(..) implementation crashes.
- * <p>
- * This can be overridden by explicitly enabling ANGLE on Windows by setting the property
- * <code>jogl.enable.ANGLE</code>.
- * </p>
- */
- private static final boolean enableANGLE = Debug.isPropertyDefined("jogl.enable.ANGLE", true);
-
- /**
- * In case no OpenGL ES implementation is required
- * and if the running platform may have a buggy implementation,
- * setting the property <code>jogl.disable.opengles</code> disables querying a possible existing OpenGL ES implementation.
- */
- private static final boolean disableOpenGLES = Debug.isPropertyDefined("jogl.disable.opengles", true);
-
static {
// Also initializes TempJarCache if shall be used.
Platform.initSingleton();
@@ -101,29 +84,29 @@ public class GLProfile {
/**
* Static initialization of JOGL.
+ *
* <p>
- * The parameter <code>firstUIActionOnProcess</code> has an impact on concurrent locking,<br>
- * see {@link javax.media.nativewindow.NativeWindowFactory#initSingleton(boolean) NativeWindowFactory.initSingleton(firstUIActionOnProcess)}.
+ * This method shall not need to be called for other reasons than having a defined initialization sequence.
* </p>
- * <p>
- * Applications using this method may place it's call before any other UI invocation
- * in the <code>main class</code>'s static block or within the <code>main function</code>.
- * In such case, applications may pass <code>firstUIActionOnProcess=true</code> to use native toolkit locking.</P>
- * <P>
- * RCP Application (Applet's, Webstart, Netbeans, ..) using JOGL are not be able to initialize JOGL
- * before the first UI action.
- * In such case you shall pass <code>firstUIActionOnProcess=false</code>.</P>
+ *
* <P>
* In case this method is not invoked, GLProfile is initialized implicit by
- * the first call to {@link #getDefault()}, {@link #get(java.lang.String)} passing <code>firstUIActionOnProcess=false</code>.
+ * the first call to {@link #getDefault()}, {@link #get(java.lang.String)}.
* <P>
- *
- * @param firstUIActionOnProcess Should be <code>true</code> if called before the first UI action of the running program,
- * otherwise <code>false</code>.
*
- * @deprecated Use {@link #initSingleton()}. This method is subject to be removed in future versions of JOGL.
+ * <p>
+ * To initialize JOGL at startup ASAP, this method may be invoked in the <i>main class</i>'s
+ * static initializer block, in the <i>static main() method</i> or in the <i>Applet init() method</i>.
+ * </p>
+ *
+ * <p>
+ * Since JOGL's initialization is complex and involves multi threading, it is <b>not</b> recommended
+ * to be have it invoked on the AWT EDT thread. In case all JOGL usage is performed
+ * on the AWT EDT, invoke this method outside the AWT EDT - see above.
+ * </p>
+ *
*/
- public static void initSingleton(final boolean firstUIActionOnProcess) {
+ public static void initSingleton() {
final boolean justInitialized;
initLock.lock();
try {
@@ -131,7 +114,7 @@ public class GLProfile {
initialized = true;
justInitialized = true;
if(DEBUG) {
- System.err.println("GLProfile.initSingleton(firstUIActionOnProcess: "+firstUIActionOnProcess+") - thread "+Thread.currentThread().getName());
+ System.err.println("GLProfile.initSingleton() - thread "+Thread.currentThread().getName());
Thread.dumpStack();
}
@@ -171,7 +154,7 @@ public class GLProfile {
}
JNILibLoaderBase.addNativeJarLibs(classesFromJavaJars, "-all", new String[] { "-noawt", "-mobile", "-core" } );
}
- initProfilesForDefaultDevices(firstUIActionOnProcess);
+ initProfilesForDefaultDevices();
return null;
}
});
@@ -189,17 +172,6 @@ public class GLProfile {
}
/**
- * Static initialization of JOGL.
- *
- * <p>
- * This method shall not need to be called for other reasons than having a defined initialization sequence.
- * </p>
- */
- public static void initSingleton() {
- GLProfile.initSingleton(false);
- }
-
- /**
* Trigger eager initialization of GLProfiles for the given device,
* in case it isn't done yet.
*
@@ -209,44 +181,25 @@ public class GLProfile {
getProfileMap(device, true);
}
- /**
- * Shutdown type for {@link GLProfile#shutdown(ShutdownType)}.
- * <p>
- * {@link #SHARED_ONLY} For thread based resources only, suitable for eg. {@link java.applet.Applet Applet} restart.<br>
- * {@link #COMPLETE} Everything.<br>
- * </p>
- */
- public enum ShutdownType {
- /* Shared thread based resources only, eg. for Applets */
- SHARED_ONLY,
- /* Everything */
- COMPLETE;
- }
-
/**
* Manual shutdown method, may be called after your last JOGL use
* within the running JVM.<br>
* It releases all temporary created resources, ie issues {@link javax.media.opengl.GLDrawableFactory#shutdown()}.<br>
* The shutdown implementation is called via the JVM shutdown hook, if not manually invoked.<br>
* <p>
- * This method shall not need to be called for other reasons than issuing a proper shutdown of resources.
+ * This method shall not need to be called for other reasons than issuing a proper shutdown of resources at a defined time.
* </p>
- * @param type the shutdown type, see {@link ShutdownType}.
*/
- public static void shutdown(ShutdownType type) {
+ public static void shutdown() {
initLock.lock();
try {
if(initialized) { // volatile: ok
initialized = false;
if(DEBUG) {
- System.err.println("GLProfile.shutdown(type: "+type+") - thread "+Thread.currentThread().getName());
+ System.err.println("GLProfile.shutdown() - thread "+Thread.currentThread().getName());
Thread.dumpStack();
}
- GLDrawableFactory.shutdown(type);
- if(ShutdownType.COMPLETE == type) {
- GLContext.shutdown();
- }
- NativeWindowFactory.shutdown();
+ GLDrawableFactory.shutdown();
}
} finally {
initLock.unlock();
@@ -1411,11 +1364,10 @@ public class GLProfile {
/**
* Tries the profiles implementation and native libraries.
*/
- private static void initProfilesForDefaultDevices(boolean firstUIActionOnProcess) {
- NativeWindowFactory.initSingleton(firstUIActionOnProcess);
+ private static void initProfilesForDefaultDevices() {
+ NativeWindowFactory.initSingleton();
if(DEBUG) {
- System.err.println("GLProfile.init firstUIActionOnProcess: "+ firstUIActionOnProcess
- + ", thread: " + Thread.currentThread().getName());
+ System.err.println("GLProfile.init - thread: " + Thread.currentThread().getName());
System.err.println(VersionUtil.getPlatformInfo());
System.err.println(GlueGenVersion.getInstance());
System.err.println(NativeWindowVersion.getInstance());
@@ -1476,34 +1428,17 @@ public class GLProfile {
}
} else {
defaultDesktopDevice = desktopFactory.getDefaultDevice();
- defaultDevice = defaultDesktopDevice;
- if(DEBUG) {
- System.err.println("Info: GLProfile.init - Default device is desktop derived: "+defaultDevice);
- }
}
- if ( !disableOpenGLES && ReflectionUtil.isClassAvailable("jogamp.opengl.egl.EGLDrawableFactory", classloader) ) {
+ if ( ReflectionUtil.isClassAvailable("jogamp.opengl.egl.EGLDrawableFactory", classloader) ) {
t=null;
try {
eglFactory = (GLDrawableFactoryImpl) GLDrawableFactory.getFactoryImpl(GLES2);
if(null != eglFactory) {
- final boolean isANGLE = ((jogamp.opengl.egl.EGLDrawableFactory)eglFactory).isANGLE();
- if(isANGLE && !enableANGLE) {
- if(DEBUG) {
- System.err.println("Info: GLProfile.init - EGL/ES2 ANGLE disabled");
- }
- eglFactory.destroy(ShutdownType.COMPLETE);
- eglFactory = null;
- hasEGLFactory = false;
- } else {
- if(DEBUG && isANGLE) {
- System.err.println("Info: GLProfile.init - EGL/ES2 ANGLE enabled");
- }
- hasEGLFactory = true;
- // update hasGLES1Impl, hasGLES2Impl based on EGL
- hasGLES2Impl = null!=eglFactory.getGLDynamicLookupHelper(2) && hasGLES2Impl;
- hasGLES1Impl = null!=eglFactory.getGLDynamicLookupHelper(1) && hasGLES1Impl;
- }
+ hasEGLFactory = true;
+ // update hasGLES1Impl, hasGLES2Impl based on EGL
+ hasGLES2Impl = null!=eglFactory.getGLDynamicLookupHelper(2) && hasGLES2Impl;
+ hasGLES1Impl = null!=eglFactory.getGLDynamicLookupHelper(1) && hasGLES1Impl;
}
} catch (LinkageError le) {
t=le;
@@ -1521,7 +1456,7 @@ public class GLProfile {
}
}
- final AbstractGraphicsDevice defaultEGLDevice;
+ final AbstractGraphicsDevice defaultEGLDevice;
if(null == eglFactory) {
hasGLES2Impl = false;
hasGLES1Impl = false;
@@ -1530,25 +1465,33 @@ public class GLProfile {
System.err.println("Info: GLProfile.init - EGL GLDrawable factory not available");
}
} else {
- defaultEGLDevice = eglFactory.getDefaultDevice();
- if(null == defaultDevice) {
- defaultDevice = defaultEGLDevice;
- if(DEBUG) {
- System.err.println("Info: GLProfile.init - Default device is EGL derived: "+defaultDevice);
- }
- }
+ defaultEGLDevice = eglFactory.getDefaultDevice();
}
- /** Should not be required .. but keep it here if simple probe on defaultDevice ain't enough.
- final boolean addedDesktopProfile = initProfilesForDevice(defaultDesktopDevice);
- final boolean addedEGLProfile = initProfilesForDevice(defaultEGLDevice);
- final boolean addedAnyProfile = addedDesktopProfile || addedEGLProfile ;
- */
- final boolean addedAnyProfile = initProfilesForDevice(defaultDevice);
-
+ if( null != defaultDesktopDevice ) {
+ defaultDevice = defaultDesktopDevice;
+ if(DEBUG) {
+ System.err.println("Info: GLProfile.init - Default device is desktop derived: "+defaultDevice);
+ }
+ } else if ( null != defaultEGLDevice ) {
+ defaultDevice = defaultEGLDevice;
+ if(DEBUG) {
+ System.err.println("Info: GLProfile.init - Default device is EGL derived: "+defaultDevice);
+ }
+ } else {
+ if(DEBUG) {
+ System.err.println("Info: GLProfile.init - Default device not available");
+ }
+ defaultDevice = null;
+ }
+
+ // we require to initialize the EGL device 1st, if available
+ final boolean addedEGLProfile = null != defaultEGLDevice ? initProfilesForDevice(defaultEGLDevice) : false;
+ final boolean addedDesktopProfile = null != defaultDesktopDevice ? initProfilesForDevice(defaultDesktopDevice) : false;
+ final boolean addedAnyProfile = addedEGLProfile || addedDesktopProfile ;
+
if(DEBUG) {
- // System.err.println("GLProfile.init addedAnyProfile "+addedAnyProfile+" (desktop: "+addedDesktopProfile+", egl "+addedEGLProfile+")");
- System.err.println("GLProfile.init addedAnyProfile "+addedAnyProfile);
+ System.err.println("GLProfile.init addedAnyProfile "+addedAnyProfile+" (desktop: "+addedDesktopProfile+", egl "+addedEGLProfile+")");
System.err.println("GLProfile.init isAWTAvailable "+isAWTAvailable);
System.err.println("GLProfile.init hasDesktopGLFactory "+hasDesktopGLFactory);
System.err.println("GLProfile.init hasGL234Impl "+hasGL234Impl);
diff --git a/src/test/com/jogamp/opengl/test/junit/util/EventCountAdapter.java b/src/jogl/classes/javax/media/opengl/GLRunnable2.java
similarity index 82%
copy from src/test/com/jogamp/opengl/test/junit/util/EventCountAdapter.java
copy to src/jogl/classes/javax/media/opengl/GLRunnable2.java
index 76a1884..1598a62 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/EventCountAdapter.java
+++ b/src/jogl/classes/javax/media/opengl/GLRunnable2.java
@@ -1,5 +1,5 @@
/**
- * Copyright 2010 JogAmp Community. All rights reserved.
+ * Copyright 2012 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
@@ -26,9 +26,19 @@
* or implied, of JogAmp Community.
*/
-package com.jogamp.opengl.test.junit.util;
+package javax.media.opengl;
-public interface EventCountAdapter {
- void reset();
+/**
+ * <p>
+ * Declares a one-shot OpenGL command.
+ * </p>
+ */
+public interface GLRunnable2<T,U> {
+ /**
+ * @param gl a current GL object
+ * @param args custom arguments
+ * @return the desired object
+ */
+ T run(GL gl, U args);
}
diff --git a/src/jogl/classes/javax/media/opengl/GLUniformData.java b/src/jogl/classes/javax/media/opengl/GLUniformData.java
index 475ff45..9638ba8 100644
--- a/src/jogl/classes/javax/media/opengl/GLUniformData.java
+++ b/src/jogl/classes/javax/media/opengl/GLUniformData.java
@@ -3,6 +3,9 @@ package javax.media.opengl;
import java.nio.*;
+import com.jogamp.common.nio.Buffers;
+import com.jogamp.opengl.FloatUtil;
+
public class GLUniformData {
/**
@@ -69,14 +72,33 @@ public class GLUniformData {
public IntBuffer intBufferValue() { return (IntBuffer)data; };
public FloatBuffer floatBufferValue() { return (FloatBuffer)data; };
+ public StringBuilder toString(StringBuilder sb) {
+ if(null == sb) {
+ sb = new StringBuilder();
+ }
+ sb.append("GLUniformData[name ").append(name).
+ append(", location ").append(location).
+ append(", size ").append(rows).append("x").append(columns).
+ append(", count ").append(count).
+ append(", data ");
+ if(isMatrix() && data instanceof FloatBuffer) {
+ sb.append("\n");
+ final FloatBuffer fb = (FloatBuffer)getBuffer();
+ for(int i=0; i<count; i++) {
+ FloatUtil.matrixToString(sb, i+": ", "%10.5f", fb, i*rows*columns, rows, columns, false);
+ sb.append(",\n");
+ }
+ } else if(isBuffer()) {
+ Buffers.toString(sb, null, getBuffer());
+ } else {
+ sb.append(data);
+ }
+ sb.append("]");
+ return sb;
+ }
+
public String toString() {
- return "GLUniformData[name "+name+
- ", location "+location+
- ", size "+rows+"*"+columns+
- ", count "+count+
- ", matrix "+isMatrix+
- ", data "+data+
- "]";
+ return toString(null).toString();
}
private void init(String name, int rows, int columns, Object data) {
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
index 03fd78a..1e9fcc9 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
@@ -98,6 +98,7 @@ import jogamp.common.awt.AWTEDTExecutor;
import jogamp.opengl.Debug;
import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLDrawableHelper;
+import jogamp.opengl.GLDrawableImpl;
// FIXME: Subclasses need to call resetGLFunctionAvailability() on their
// context whenever the displayChanged() function is called on our
@@ -109,6 +110,16 @@ import jogamp.opengl.GLDrawableHelper;
interfaces when adding a heavyweight doesn't work either because
of Z-ordering or LayoutManager problems.
*
+ * <h5><A NAME="java2dgl">Offscreen Layer Remarks</A></h5>
+ *
+ * {@link OffscreenLayerOption#setShallUseOffscreenLayer(boolean) setShallUseOffscreenLayer(true)}
+ * maybe called to use an offscreen drawable (FBO or PBuffer) allowing
+ * the underlying JAWT mechanism to composite the image, if supported.
+ * <p>
+ * {@link OffscreenLayerOption#setShallUseOffscreenLayer(boolean) setShallUseOffscreenLayer(true)}
+ * is being called if {@link GLCapabilitiesImmutable#isOnscreen()} is <code>false</code>.
+ * </p>
+ *
* <h5><A NAME="java2dgl">Java2D OpenGL Remarks</A></h5>
*
* To avoid any conflicts with a potential Java2D OpenGL context,<br>
@@ -145,7 +156,8 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
private final RecursiveLock lock = LockFactory.createRecursiveLock();
private final GLDrawableHelper helper = new GLDrawableHelper();
private AWTGraphicsConfiguration awtConfig;
- private volatile GLDrawable drawable; // volatile: avoid locking for read-only access
+ private volatile GLDrawableImpl drawable; // volatile: avoid locking for read-only access
+ private volatile JAWTWindow jawtWindow; // the JAWTWindow presentation of this AWT Canvas, bound to the 'drawable' lifecycle
private GLContextImpl context;
private volatile boolean sendReshape = false; // volatile: maybe written by EDT w/o locking
@@ -236,6 +248,9 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
// don't allow the user to change data
capsReqUser = (GLCapabilitiesImmutable) capsReqUser.cloneMutable();
}
+ if(!capsReqUser.isOnscreen()) {
+ setShallUseOffscreenLayer(true); // trigger offscreen layer - if supported
+ }
if(null==device) {
GraphicsConfiguration gc = super.getGraphicsConfiguration();
@@ -268,9 +283,9 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
@Override
public final boolean isOffscreenLayerSurfaceEnabled() {
- final GLDrawable _drawable = drawable;
- if(null != _drawable) {
- return ((JAWTWindow)_drawable.getNativeSurface()).isOffscreenLayerSurfaceEnabled();
+ final JAWTWindow _jawtWindow = jawtWindow;
+ if(null != _jawtWindow) {
+ return _jawtWindow.isOffscreenLayerSurfaceEnabled();
}
return false;
}
@@ -425,6 +440,12 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
@Override
public void display() {
+ if( !validateGLDrawable() ) {
+ if(DEBUG) {
+ System.err.println(getThreadName()+": Info: GLCanvas display - skipped GL render, drawable not valid yet");
+ }
+ return; // not yet available ..
+ }
Threading.invoke(true, displayOnEDTAction, getTreeLock());
awtWindowClosingProtocol.addClosingListenerOneShot();
}
@@ -450,11 +471,9 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
/** Overridden to cause OpenGL rendering to be performed during
repaint cycles. Subclasses which override this method must call
super.paint() in their paint() method in order to function
- properly. <P>
-
- <B>Overrides:</B>
- <DL><DD><CODE>paint</CODE> in class <CODE>java.awt.Component</CODE></DD></DL> */
- @Override
+ properly.
+ */
+ @Override
public void paint(Graphics g) {
if (Beans.isDesignTime()) {
// Make GLCanvas behave better in NetBeans GUI builder
@@ -476,7 +495,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
(int) ((getHeight() + bounds.getHeight()) / 2));
return;
}
- if( ! this.helper.isAnimatorAnimating() ) {
+ if( ! this.helper.isExternalAnimatorAnimating() ) {
display();
}
}
@@ -539,11 +558,11 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
private void createDrawableAndContext() {
// no lock required, since this resource ain't available yet
- final JAWTWindow jawtWindow = (JAWTWindow) NativeWindowFactory.getNativeWindow(this, awtConfig);
+ jawtWindow = (JAWTWindow) NativeWindowFactory.getNativeWindow(this, awtConfig);
jawtWindow.setShallUseOffscreenLayer(shallUseOffscreenLayer);
jawtWindow.lockSurface();
try {
- drawable = GLDrawableFactory.getFactory(capsReqUser.getGLProfile()).createGLDrawable(jawtWindow);
+ drawable = (GLDrawableImpl) GLDrawableFactory.getFactory(capsReqUser.getGLProfile()).createGLDrawable(jawtWindow);
context = (GLContextImpl) drawable.createContext(shareWith);
context.setContextCreationFlags(additionalCtxCreationFlags);
} finally {
@@ -557,24 +576,36 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
if( _drawable.isRealized() ) {
return true;
}
- if (!Beans.isDesignTime() &&
- 0 < _drawable.getWidth() * _drawable.getHeight() ) {
- // make sure drawable realization happens on AWT EDT, due to AWTTree lock
- AWTEDTExecutor.singleton.invoke(true, setRealizedOnEDTAction);
- sendReshape=true; // ensure a reshape is being send ..
- if(DEBUG) {
- System.err.println(getThreadName()+": Realized Drawable: "+_drawable.toString());
- Thread.dumpStack();
- }
- return true;
+ if( Beans.isDesignTime() || !isDisplayable() || 0 >= _drawable.getWidth() || 0 >= _drawable.getHeight() ) {
+ return false; // early out!
}
+ // make sure drawable realization happens on AWT EDT, due to AWTTree lock
+ AWTEDTExecutor.singleton.invoke(getTreeLock(), true, setRealizedOnEDTAction);
+ final boolean res = _drawable.isRealized();
+ if(DEBUG) {
+ System.err.println(getThreadName()+": Realized Drawable: "+res+", "+_drawable.toString());
+ Thread.dumpStack();
+ }
+ return res;
}
return false;
}
- private Runnable setRealizedOnEDTAction = new Runnable() {
- @Override
- public void run() {
- drawable.setRealized(true);
+ private Runnable setRealizedOnEDTAction = new Runnable() {
+ public void run() {
+ final RecursiveLock _lock = lock;
+ _lock.lock();
+ try {
+ final GLDrawable _drawable = drawable;
+ if( null == _drawable || 0 >= _drawable.getWidth() || 0 >= _drawable.getHeight() ) {
+ return;
+ }
+ _drawable.setRealized(true);
+ if( _drawable.isRealized() ) {
+ sendReshape=true; // ensure a reshape is being send ..
+ }
+ } finally {
+ _lock.unlock();
+ }
} };
/** <p>Overridden to track when this component is removed from a
@@ -619,22 +650,40 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
@SuppressWarnings("deprecation")
@Override
public void reshape(int x, int y, int width, int height) {
- super.reshape(x, y, width, height);
- final GLDrawable _drawable = drawable;
- if(null != _drawable && _drawable.isRealized() && !_drawable.getChosenGLCapabilities().isOnscreen()) {
- dispose(true);
- } else {
- sendReshape = true;
+ synchronized (getTreeLock()) { // super.reshape(..) claims tree lock, so we do extend it's lock over reshape
+ super.reshape(x, y, width, height);
+
+ if(DEBUG) {
+ final NativeSurface ns = getNativeSurface();
+ final long nsH = null != ns ? ns.getSurfaceHandle() : 0;
+ System.err.println("GLCanvas.sizeChanged: ("+Thread.currentThread().getName()+"): "+width+"x"+height+" - surfaceHandle 0x"+Long.toHexString(nsH));
+ // Thread.dumpStack();
+ }
+ if( validateGLDrawable() ) {
+ final GLDrawableImpl _drawable = drawable;
+ if( ! _drawable.getChosenGLCapabilities().isOnscreen() ) {
+ final RecursiveLock _lock = lock;
+ _lock.lock();
+ try {
+ final GLDrawableImpl _drawableNew = GLDrawableHelper.resizeOffscreenDrawable(_drawable, context, width, height);
+ if(_drawable != _drawableNew) {
+ // write back
+ drawable = _drawableNew;
+ }
+ } finally {
+ _lock.unlock();
+ }
+ }
+ sendReshape = true; // async if display() doesn't get called below, but avoiding deadlock
+ }
}
}
- /** <B>Overrides:</B>
- <DL><DD><CODE>update</CODE> in class <CODE>java.awt.Component</CODE></DD></DL> */
/**
* Overridden from Canvas to prevent the AWT's clearing of the
* canvas from interfering with the OpenGL rendering.
*/
- @Override
+ @Override
public void update(Graphics g) {
paint(g);
}
@@ -680,7 +729,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
_lock.lock();
try {
final GLContext oldCtx = context;
- final boolean newCtxCurrent = helper.switchContext(drawable, oldCtx, newCtx, additionalCtxCreationFlags);
+ final boolean newCtxCurrent = GLDrawableHelper.switchContext(drawable, oldCtx, newCtx, additionalCtxCreationFlags);
context=(GLContextImpl)newCtx;
if(newCtxCurrent) {
context.makeCurrent();
@@ -692,6 +741,11 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
}
@Override
+ public final GLDrawable getDelegatedDrawable() {
+ return drawable;
+ }
+
+ @Override
public GLContext getContext() {
return context;
}
@@ -811,11 +865,11 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
public void run() {
context=null;
if(null!=drawable) {
- final JAWTWindow jawtWindow = (JAWTWindow)drawable.getNativeSurface();
drawable.setRealized(false);
drawable=null;
if(null!=jawtWindow) {
jawtWindow.destroy();
+ jawtWindow=null;
}
}
@@ -865,7 +919,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
if(!disposeRegenerate) {
if(null != awtConfig) {
- disposeAbstractGraphicsDevice();
+ AWTEDTExecutor.singleton.invoke(getTreeLock(), true, disposeAbstractGraphicsDeviceActionOnEDT);
}
awtConfig=null;
}
@@ -880,7 +934,13 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
}
};
- private final Runnable disposeAbstractGraphicsDeviceAction = new Runnable() {
+ /**
+ * Disposes the AbstractGraphicsDevice within EDT,
+ * since resources created (X11: Display), must be destroyed in the same thread, where they have been created.
+ *
+ * @see #chooseGraphicsConfiguration(javax.media.opengl.GLCapabilitiesImmutable, javax.media.opengl.GLCapabilitiesImmutable, javax.media.opengl.GLCapabilitiesChooser, java.awt.GraphicsDevice)
+ */
+ private final Runnable disposeAbstractGraphicsDeviceActionOnEDT = new Runnable() {
@Override
public void run() {
if(null != awtConfig) {
@@ -899,31 +959,11 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
}
}
};
-
- /**
- * Disposes the AbstractGraphicsDevice within EDT,
- * since resources created (X11: Display), must be destroyed in the same thread, where they have been created.
- *
- * @see #chooseGraphicsConfiguration(javax.media.opengl.GLCapabilitiesImmutable, javax.media.opengl.GLCapabilitiesImmutable, javax.media.opengl.GLCapabilitiesChooser, java.awt.GraphicsDevice)
- */
- private void disposeAbstractGraphicsDevice() {
- if( EventQueue.isDispatchThread() || Thread.holdsLock(getTreeLock()) ) {
- disposeAbstractGraphicsDeviceAction.run();
- } else {
- try {
- EventQueue.invokeAndWait(disposeAbstractGraphicsDeviceAction);
- } catch (InvocationTargetException e) {
- throw new GLException(e.getTargetException());
- } catch (InterruptedException e) {
- throw new GLException(e);
- }
- }
- }
-
+
private final Runnable initAction = new Runnable() {
@Override
public void run() {
- helper.init(GLCanvas.this);
+ helper.init(GLCanvas.this, !sendReshape);
}
};
@@ -944,13 +984,6 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
}
};
- private final Runnable swapBuffersAction = new Runnable() {
- @Override
- public void run() {
- drawable.swapBuffers();
- }
- };
-
// Workaround for ATI driver bugs related to multithreading issues
// like simultaneous rendering via Animators to canvases that are
// being resized on the AWT event dispatch thread
@@ -960,11 +993,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
final RecursiveLock _lock = lock;
_lock.lock();
try {
- if( validateGLDrawable() ) {
- helper.invokeGL(drawable, context, displayAction, initAction);
- } else if(DEBUG) {
- System.err.println(getThreadName()+": Info: GLCanvas display - skipped GL render, drawable not valid yet");
- }
+ helper.invokeGL(drawable, context, displayAction, initAction);
} finally {
_lock.unlock();
}
@@ -976,8 +1005,10 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
public void run() {
final RecursiveLock _lock = lock;
_lock.lock();
- try {
- helper.invokeGL(drawable, context, swapBuffersAction, initAction);
+ try {
+ if(null != drawable) {
+ drawable.swapBuffers();
+ }
} finally {
_lock.unlock();
}
@@ -1045,7 +1076,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
* @param device
* @return the chosen AWTGraphicsConfiguration
*
- * @see #disposeAbstractGraphicsDevice()
+ * @see #disposeAbstractGraphicsDeviceActionOnEDT
*/
private AWTGraphicsConfiguration chooseGraphicsConfiguration(final GLCapabilitiesImmutable capsChosen,
final GLCapabilitiesImmutable capsRequested,
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
index acb8f21..d0b9fb9 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
@@ -121,7 +121,7 @@ import com.jogamp.opengl.util.GLBuffers;
* </P>
*/
- at SuppressWarnings("serial")
+ at SuppressWarnings({ "serial", "deprecation" })
public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosingProtocol {
private static final boolean DEBUG = Debug.debug("GLJPanel");
@@ -396,7 +396,6 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
their reshape() method in order to function properly. <P>
<DL><DD><CODE>reshape</CODE> in class <CODE>java.awt.Component</CODE></DD></DL> */
- @SuppressWarnings("deprecation")
@Override
public void reshape(int x, int y, int width, int height) {
super.reshape(x, y, width, height);
@@ -471,7 +470,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
return null;
}
final GLContext oldCtx = backend.getContext();
- final boolean newCtxCurrent = helper.switchContext(backend.getDrawable(), oldCtx, newCtx, additionalCtxCreationFlags);
+ final boolean newCtxCurrent = GLDrawableHelper.switchContext(backend.getDrawable(), oldCtx, newCtx, additionalCtxCreationFlags);
backend.setContext(newCtx);
if(newCtxCurrent) {
newCtx.makeCurrent();
@@ -481,6 +480,14 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
@Override
+ public final GLDrawable getDelegatedDrawable() {
+ if (backend == null) {
+ return null;
+ }
+ return backend.getDrawable();
+ }
+
+ @Override
public GLContext getContext() {
if (backend == null) {
return null;
@@ -672,7 +679,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
if (!backend.preGL(g)) {
return;
}
- helper.init(GLJPanel.this);
+ helper.init(GLJPanel.this, !sendReshape);
backend.postGL(g, false);
}
diff --git a/src/jogl/classes/javax/media/opengl/fixedfunc/GLMatrixFunc.java b/src/jogl/classes/javax/media/opengl/fixedfunc/GLMatrixFunc.java
index a34d490..9fee0a2 100644
--- a/src/jogl/classes/javax/media/opengl/fixedfunc/GLMatrixFunc.java
+++ b/src/jogl/classes/javax/media/opengl/fixedfunc/GLMatrixFunc.java
@@ -31,69 +31,122 @@ package javax.media.opengl.fixedfunc;
import java.nio.*;
+import javax.media.opengl.GL;
+
+/**
+ * Subset of OpenGL fixed function pipeline's matrix operations.
+ */
public interface GLMatrixFunc {
- public static final int GL_MATRIX_MODE = 0x0BA0;
- public static final int GL_MODELVIEW = 0x1700;
- public static final int GL_PROJECTION = 0x1701;
- // public static final int GL_TEXTURE = 0x1702; // Use GL.GL_TEXTURE due to ambiguous GL usage
- public static final int GL_MODELVIEW_MATRIX = 0x0BA6;
- public static final int GL_PROJECTION_MATRIX = 0x0BA7;
- public static final int GL_TEXTURE_MATRIX = 0x0BA8;
-
- /**
- * glGetFloatv
- * @param pname GL_MODELVIEW_MATRIX, GL_PROJECTION_MATRIX or GL_TEXTURE_MATRIX
- * @param params the FloatBuffer's position remains unchanged,
- * which is the same behavior than the native JOGL GL impl
- */
- public void glGetFloatv(int pname, java.nio.FloatBuffer params);
- public void glGetFloatv(int pname, float[] params, int params_offset);
- /**
- * glGetIntegerv
- * @param pname GL_MATRIX_MODE
- * @param params the FloatBuffer's position remains unchanged
- * which is the same behavior than the native JOGL GL impl
- */
- public void glGetIntegerv(int pname, IntBuffer params);
- public void glGetIntegerv(int pname, int[] params, int params_offset);
-
- /**
- * sets the current matrix
- * @param pname GL_MODELVIEW, GL_PROJECTION or GL.GL_TEXTURE
- */
- public void glMatrixMode(int mode) ;
-
- public void glPushMatrix();
- public void glPopMatrix();
-
- public void glLoadIdentity() ;
-
- /**
- * glLoadMatrixf
- * @param params the FloatBuffer's position remains unchanged,
- * which is the same behavior than the native JOGL GL impl
- */
- public void glLoadMatrixf(java.nio.FloatBuffer m) ;
- public void glLoadMatrixf(float[] m, int m_offset);
-
- /**
- * glMultMatrixf
- * @param m the FloatBuffer's position remains unchanged,
- * which is the same behavior than the native JOGL GL impl
- */
- public void glMultMatrixf(java.nio.FloatBuffer m) ;
- public void glMultMatrixf(float[] m, int m_offset);
-
- public void glTranslatef(float x, float y, float z) ;
-
- public void glRotatef(float angle, float x, float y, float z);
-
- public void glScalef(float x, float y, float z) ;
-
- public void glOrthof(float left, float right, float bottom, float top, float zNear, float zFar) ;
-
- public void glFrustumf(float left, float right, float bottom, float top, float zNear, float zFar);
+ public static final int GL_MATRIX_MODE = 0x0BA0;
+ /** Matrix mode modelview */
+ public static final int GL_MODELVIEW = 0x1700;
+ /** Matrix mode projection */
+ public static final int GL_PROJECTION = 0x1701;
+ // public static final int GL_TEXTURE = 0x1702; // Use GL.GL_TEXTURE due to ambiguous GL usage
+ /** Matrix access name for modelview */
+ public static final int GL_MODELVIEW_MATRIX = 0x0BA6;
+ /** Matrix access name for projection */
+ public static final int GL_PROJECTION_MATRIX = 0x0BA7;
+ /** Matrix access name for texture */
+ public static final int GL_TEXTURE_MATRIX = 0x0BA8;
+
+ /**
+ * Copy the named matrix into the given storage.
+ * @param pname {@link #GL_MODELVIEW_MATRIX}, {@link #GL_PROJECTION_MATRIX} or {@link #GL_TEXTURE_MATRIX}
+ * @param params the FloatBuffer's position remains unchanged,
+ * which is the same behavior than the native JOGL GL impl
+ */
+ public void glGetFloatv(int pname, java.nio.FloatBuffer params);
+
+ /**
+ * Copy the named matrix to the given storage at offset.
+ * @param pname {@link #GL_MODELVIEW_MATRIX}, {@link #GL_PROJECTION_MATRIX} or {@link #GL_TEXTURE_MATRIX}
+ * @param params storage
+ * @param params_offset storage offset
+ */
+ public void glGetFloatv(int pname, float[] params, int params_offset);
+
+ /**
+ * glGetIntegerv
+ * @param pname {@link #GL_MATRIX_MODE} to receive the current matrix mode
+ * @param params the FloatBuffer's position remains unchanged
+ * which is the same behavior than the native JOGL GL impl
+ */
+ public void glGetIntegerv(int pname, IntBuffer params);
+ public void glGetIntegerv(int pname, int[] params, int params_offset);
+
+ /**
+ * Sets the current matrix mode.
+ * @param mode {@link #GL_MODELVIEW}, {@link #GL_PROJECTION} or {@link GL#GL_TEXTURE GL_TEXTURE}.
+ */
+ public void glMatrixMode(int mode) ;
+
+ /**
+ * Push the current matrix to it's stack, while preserving it's values.
+ * <p>
+ * There exist one stack per matrix mode, i.e. {@link #GL_MODELVIEW}, {@link #GL_PROJECTION} and {@link GL#GL_TEXTURE GL_TEXTURE}.
+ * </p>
+ */
+ public void glPushMatrix();
+
+ /**
+ * Pop the current matrix from it's stack.
+ * @see #glPushMatrix()
+ */
+ public void glPopMatrix();
+
+ /**
+ * Load the current matrix with the identity matrix
+ */
+ public void glLoadIdentity() ;
+
+ /**
+ * Load the current matrix w/ the provided one.
+ * @param params the FloatBuffer's position remains unchanged,
+ * which is the same behavior than the native JOGL GL impl
+ */
+ public void glLoadMatrixf(java.nio.FloatBuffer m) ;
+ /**
+ * Load the current matrix w/ the provided one.
+ */
+ public void glLoadMatrixf(float[] m, int m_offset);
+
+ /**
+ * Multiply the current matrix
+ * @param m the FloatBuffer's position remains unchanged,
+ * which is the same behavior than the native JOGL GL impl
+ */
+ public void glMultMatrixf(java.nio.FloatBuffer m) ;
+ /**
+ * Multiply the current matrix
+ */
+ public void glMultMatrixf(float[] m, int m_offset);
+
+ /**
+ * Translate the current matrix.
+ */
+ public void glTranslatef(float x, float y, float z) ;
+
+ /**
+ * Rotate the current matrix.
+ */
+ public void glRotatef(float angle, float x, float y, float z);
+
+ /**
+ * Scale the current matrix.
+ */
+ public void glScalef(float x, float y, float z) ;
+
+ /**
+ * {@link #glMultMatrixf(FloatBuffer) Multiply} the current matrix with the orthogonal matrix.
+ */
+ public void glOrthof(float left, float right, float bottom, float top, float zNear, float zFar) ;
+
+ /**
+ * {@link #glMultMatrixf(FloatBuffer) Multiply} the current matrix with the frustum matrix.
+ */
+ public void glFrustumf(float left, float right, float bottom, float top, float zNear, float zFar);
}
diff --git a/src/jogl/classes/javax/media/opengl/fixedfunc/GLPointerFuncUtil.java b/src/jogl/classes/javax/media/opengl/fixedfunc/GLPointerFuncUtil.java
index e52154c..79ec38e 100644
--- a/src/jogl/classes/javax/media/opengl/fixedfunc/GLPointerFuncUtil.java
+++ b/src/jogl/classes/javax/media/opengl/fixedfunc/GLPointerFuncUtil.java
@@ -40,6 +40,15 @@ public class GLPointerFuncUtil {
* @return default fixed function array name
*/
public static String getPredefinedArrayIndexName(int glArrayIndex) {
+ return getPredefinedArrayIndexName(glArrayIndex, -1);
+ }
+
+ /**
+ * @param glArrayIndex the fixed function array index
+ * @param multiTexCoordIndex index for multiTexCoordIndex
+ * @return default fixed function array name
+ */
+ public static String getPredefinedArrayIndexName(int glArrayIndex, int multiTexCoordIndex) {
switch(glArrayIndex) {
case GLPointerFunc.GL_VERTEX_ARRAY:
return mgl_Vertex;
@@ -48,7 +57,11 @@ public class GLPointerFuncUtil {
case GLPointerFunc.GL_COLOR_ARRAY:
return mgl_Color;
case GLPointerFunc.GL_TEXTURE_COORD_ARRAY:
- return mgl_MultiTexCoord;
+ if(0<=multiTexCoordIndex) {
+ return mgl_MultiTexCoord+multiTexCoordIndex;
+ } else {
+ return mgl_MultiTexCoord+multiTexCoordIndex;
+ }
}
return null;
}
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/RegionRendererImpl01.java b/src/jogl/classes/jogamp/graph/curve/opengl/RegionRendererImpl01.java
index c34d1cb..2884aca 100755
--- a/src/jogl/classes/jogamp/graph/curve/opengl/RegionRendererImpl01.java
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/RegionRendererImpl01.java
@@ -65,7 +65,9 @@ public class RegionRendererImpl01 extends RegionRenderer {
sp.add(rsVp);
sp.add(rsFp);
- sp.init(gl);
+ if( !sp.init(gl) ) {
+ throw new GLException("RegionRenderer: Couldn't init program: "+sp);
+ }
st.attachShaderProgram(gl, sp, false);
st.bindAttribLocation(gl, AttributeNames.VERTEX_ATTR_IDX, AttributeNames.VERTEX_ATTR_NAME);
st.bindAttribLocation(gl, AttributeNames.TEXCOORD_ATTR_IDX, AttributeNames.TEXCOORD_ATTR_NAME);
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/TextRendererImpl01.java b/src/jogl/classes/jogamp/graph/curve/opengl/TextRendererImpl01.java
index 158f024..0cf424c 100644
--- a/src/jogl/classes/jogamp/graph/curve/opengl/TextRendererImpl01.java
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/TextRendererImpl01.java
@@ -58,7 +58,9 @@ public class TextRendererImpl01 extends TextRenderer {
sp.add(rsVp);
sp.add(rsFp);
- sp.init(gl);
+ if( !sp.init(gl) ) {
+ throw new GLException("RegionRenderer: Couldn't init program: "+sp);
+ }
st.attachShaderProgram(gl, sp, false);
st.bindAttribLocation(gl, AttributeNames.VERTEX_ATTR_IDX, AttributeNames.VERTEX_ATTR_NAME);
st.bindAttribLocation(gl, AttributeNames.TEXCOORD_ATTR_IDX, AttributeNames.TEXCOORD_ATTR_NAME);
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PES2.java b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PES2.java
index aabef29..85d3ad5 100644
--- a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PES2.java
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PES2.java
@@ -220,14 +220,14 @@ public class VBORegion2PES2 extends GLRegion {
gl.glActiveTexture(GL.GL_TEXTURE0 + mgl_ActiveTexture.intValue());
fbo.use(gl, texA);
verticeFboAttr.enableBuffer(gl, true);
- texCoordFboAttr.enableBuffer(gl, true);
- indicesFbo.enableBuffer(gl, true);
+ texCoordFboAttr.enableBuffer(gl, true);
+ indicesFbo.bindBuffer(gl, true); // keeps VBO binding
- gl.glDrawElements(GL2ES2.GL_TRIANGLES, indicesFbo.getElementCount() * indicesFbo.getComponentCount(), GL2ES2.GL_UNSIGNED_SHORT, 0);
+ gl.glDrawElements(GL2ES2.GL_TRIANGLES, indicesFbo.getElementCount() * indicesFbo.getComponentCount(), GL2ES2.GL_UNSIGNED_SHORT, 0);
- verticeFboAttr.enableBuffer(gl, false);
+ indicesFbo.bindBuffer(gl, false);
texCoordFboAttr.enableBuffer(gl, false);
- indicesFbo.enableBuffer(gl, false);
+ verticeFboAttr.enableBuffer(gl, false);
fbo.unuse(gl);
// setback: gl.glActiveTexture(currentActiveTextureEngine[0]);
@@ -287,13 +287,13 @@ public class VBORegion2PES2 extends GLRegion {
private void renderRegion(GL2ES2 gl) {
verticeTxtAttr.enableBuffer(gl, true);
texCoordTxtAttr.enableBuffer(gl, true);
- indicesTxt.enableBuffer(gl, true);
+ indicesTxt.bindBuffer(gl, true); // keeps VBO binding
- gl.glDrawElements(GL2ES2.GL_TRIANGLES, indicesTxt.getElementCount() * indicesTxt.getComponentCount(), GL2ES2.GL_UNSIGNED_SHORT, 0);
+ gl.glDrawElements(GL2ES2.GL_TRIANGLES, indicesTxt.getElementCount() * indicesTxt.getComponentCount(), GL2ES2.GL_UNSIGNED_SHORT, 0);
- verticeTxtAttr.enableBuffer(gl, false);
+ indicesTxt.bindBuffer(gl, false);
texCoordTxtAttr.enableBuffer(gl, false);
- indicesTxt.enableBuffer(gl, false);
+ verticeTxtAttr.enableBuffer(gl, false);
}
public void destroy(GL2ES2 gl, RenderState rs) {
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegionSPES2.java b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegionSPES2.java
index 14ff038..0cba444 100644
--- a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegionSPES2.java
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegionSPES2.java
@@ -127,14 +127,14 @@ public class VBORegionSPES2 extends GLRegion {
protected void drawImpl(GL2ES2 gl, RenderState rs, int vp_width, int vp_height, int[/*1*/] texWidth) {
verticeAttr.enableBuffer(gl, true);
- texCoordAttr.enableBuffer(gl, true);
- indices.enableBuffer(gl, true);
-
- gl.glDrawElements(GL2ES2.GL_TRIANGLES, indices.getElementCount() * indices.getComponentCount(), GL2ES2.GL_UNSIGNED_SHORT, 0);
-
- verticeAttr.enableBuffer(gl, false);
+ texCoordAttr.enableBuffer(gl, true);
+ indices.bindBuffer(gl, true); // keeps VBO binding
+
+ gl.glDrawElements(GL2ES2.GL_TRIANGLES, indices.getElementCount() * indices.getComponentCount(), GL2ES2.GL_UNSIGNED_SHORT, 0);
+
+ indices.bindBuffer(gl, false);
texCoordAttr.enableBuffer(gl, false);
- indices.enableBuffer(gl, false);
+ verticeAttr.enableBuffer(gl, false);
}
public final void destroy(GL2ES2 gl, RenderState rs) {
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-es2-merged.vp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-es2-merged.vp
index 530b24f..8fb985d 100644
--- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-es2-merged.vp
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-es2-merged.vp
@@ -1,8 +1,8 @@
//Copyright 2010 JogAmp Community. All rights reserved.
#ifdef GL_ES
- precision lowp float;
- precision lowp int;
+ precision highp float;
+ precision highp int;
#endif
uniform mat4 gcu_PMVMatrix[3]; // P, Mv, and Mvi
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-es2.vp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-es2.vp
index 15ce8cc..a5dc158 100644
--- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-es2.vp
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-es2.vp
@@ -2,8 +2,8 @@
#version 100
-precision mediump float;
-precision mediump int;
+precision highp float;
+precision highp int;
#include curverenderer01-xxx.vp
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01a-es2-merged.fp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01a-es2-merged.fp
index da32df5..a57d8fc 100644
--- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01a-es2-merged.fp
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01a-es2-merged.fp
@@ -1,8 +1,8 @@
//Copyright 2010 JogAmp Community. All rights reserved.
#ifdef GL_ES
- precision lowp float;
- precision lowp int;
+ precision mediump float;
+ precision mediump int;
#endif
uniform mat4 gcu_PMVMatrix[3]; // P, Mv, and Mvi
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01b-es2.fp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01b-es2.fp
index 2e70963..d474872 100644
--- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01b-es2.fp
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01b-es2.fp
@@ -8,7 +8,7 @@
precision mediump float;
precision mediump int;
-precision mediump sampler2D;
+precision mediump sampler2D; // default is lowp
#include curverenderer01b-xxx.fp
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer02a-es2.fp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer02a-es2.fp
index b524203..240a6c3 100644
--- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer02a-es2.fp
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer02a-es2.fp
@@ -8,7 +8,7 @@
precision mediump float;
precision mediump int;
-precision mediump sampler2D;
+precision mediump sampler2D; // default is lowp
#include curverenderer02a-xxx.fp
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer02b-es2.fp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer02b-es2.fp
index e0486dd..884e756 100644
--- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer02b-es2.fp
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer02b-es2.fp
@@ -8,7 +8,7 @@
precision mediump float;
precision mediump int;
-precision mediump sampler2D;
+precision mediump sampler2D; // default is lowp
#include curverenderer02b-xxx.fp
diff --git a/src/jogl/classes/jogamp/graph/font/JavaFontLoader.java b/src/jogl/classes/jogamp/graph/font/JavaFontLoader.java
index a00e957..3736c5f 100644
--- a/src/jogl/classes/jogamp/graph/font/JavaFontLoader.java
+++ b/src/jogl/classes/jogamp/graph/font/JavaFontLoader.java
@@ -41,7 +41,10 @@ import com.jogamp.graph.font.FontFactory;
public class JavaFontLoader implements FontSet {
- final static FontSet fontLoader = new JavaFontLoader();
+ // FIXME: Add cache size to limit memory usage
+ private static final IntObjectHashMap fontMap = new IntObjectHashMap();
+
+ private static final FontSet fontLoader = new JavaFontLoader();
public static FontSet get() {
return fontLoader;
@@ -74,9 +77,6 @@ public class JavaFontLoader implements FontSet {
}
}
- // FIXME: Add cache size to limit memory usage
- static final IntObjectHashMap fontMap = new IntObjectHashMap();
-
static boolean is(int bits, int bit) {
return 0 != ( bits & bit ) ;
}
diff --git a/src/jogl/classes/jogamp/graph/font/UbuntuFontLoader.java b/src/jogl/classes/jogamp/graph/font/UbuntuFontLoader.java
index 0772cc4..c4c5802 100644
--- a/src/jogl/classes/jogamp/graph/font/UbuntuFontLoader.java
+++ b/src/jogl/classes/jogamp/graph/font/UbuntuFontLoader.java
@@ -40,9 +40,14 @@ import java.net.URLConnection;
public class UbuntuFontLoader implements FontSet {
- final static FontSet fontLoader = new UbuntuFontLoader();
+ // FIXME: Add cache size to limit memory usage
+ private static final IntObjectHashMap fontMap = new IntObjectHashMap();
+
+ private static final String relPath = "fonts/ubuntu/" ;
+
+ private static final FontSet fontLoader = new UbuntuFontLoader();
- public static FontSet get() {
+ public static final FontSet get() {
return fontLoader;
}
@@ -59,14 +64,9 @@ public class UbuntuFontLoader implements FontSet {
};
- final static String relPath = "fonts/ubuntu/" ;
-
private UbuntuFontLoader() {
}
- // FIXME: Add cache size to limit memory usage
- static final IntObjectHashMap fontMap = new IntObjectHashMap();
-
static boolean is(int bits, int bit) {
return 0 != ( bits & bit ) ;
}
diff --git a/src/jogl/classes/jogamp/graph/geom/plane/Path2D.java b/src/jogl/classes/jogamp/graph/geom/plane/Path2D.java
index 8082fe4..c895e83 100644
--- a/src/jogl/classes/jogamp/graph/geom/plane/Path2D.java
+++ b/src/jogl/classes/jogamp/graph/geom/plane/Path2D.java
@@ -397,7 +397,7 @@ public final class Path2D implements Cloneable {
}
public boolean contains(AABBox r) {
- return contains(r);
+ return contains(r.getMinX(), r.getMinY(), r.getWidth(), r.getHeight());
}
public boolean intersects(AABBox r) {
diff --git a/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java b/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java
index cc4e1b4..85156e8 100644
--- a/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java
+++ b/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java
@@ -30,16 +30,15 @@ package jogamp.opengl;
import java.io.PrintStream;
-import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindowException;
import javax.media.nativewindow.WindowClosingProtocol;
import javax.media.nativewindow.WindowClosingProtocol.WindowClosingMode;
import javax.media.opengl.FPSCounter;
import javax.media.opengl.GL;
import javax.media.opengl.GLAnimatorControl;
import javax.media.opengl.GLAutoDrawable;
-import javax.media.opengl.GLAutoDrawableDelegate;
import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawable;
@@ -49,6 +48,7 @@ import javax.media.opengl.GLProfile;
import javax.media.opengl.GLRunnable;
import com.jogamp.common.util.locks.RecursiveLock;
+import com.jogamp.opengl.GLAutoDrawableDelegate;
import com.jogamp.opengl.util.Animator;
@@ -61,71 +61,83 @@ import com.jogamp.opengl.util.Animator;
* @see GLWindow
*/
public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
- public static final boolean DEBUG = Debug.debug("GLAutoDrawable");
+ public static final boolean DEBUG = GLDrawableImpl.DEBUG;
protected final GLDrawableHelper helper = new GLDrawableHelper();
protected final FPSCounterImpl fpsCounter = new FPSCounterImpl();
protected volatile GLDrawableImpl drawable; // volatile: avoid locking for read-only access
protected GLContextImpl context;
- protected final boolean ownDevice;
+ protected final boolean ownsDevice;
protected int additionalCtxCreationFlags = 0;
protected volatile boolean sendReshape = false; // volatile: maybe written by WindowManager thread w/o locking
protected volatile boolean sendDestroy = false; // volatile: maybe written by WindowManager thread w/o locking
/**
- * @param drawable a valid {@link GLDrawableImpl}, may not be realized yet.
- * @param context a valid {@link GLContextImpl}, may not be made current (created) yet.
- * @param ownDevice pass <code>true</code> if {@link AbstractGraphicsDevice#close()} shall be issued,
- * otherwise pass <code>false</code>. Closing the device is required in case
- * the drawable is created w/ it's own new instance, e.g. offscreen drawables,
- * and no further lifecycle handling is applied.
+ * @param drawable upstream {@link GLDrawableImpl} instance, may be null for lazy initialization
+ * @param context upstream {@link GLContextImpl} instance, may be null for lazy initialization
+ * @param ownsDevice pass <code>true</code> if {@link AbstractGraphicsDevice#close()} shall be issued,
+ * otherwise pass <code>false</code>. Closing the device is required in case
+ * the drawable is created w/ it's own new instance, e.g. offscreen drawables,
+ * and no further lifecycle handling is applied.
*/
- public GLAutoDrawableBase(GLDrawableImpl drawable, GLContextImpl context, boolean ownDevice) {
+ public GLAutoDrawableBase(GLDrawableImpl drawable, GLContextImpl context, boolean ownsDevice) {
this.drawable = drawable;
this.context = context;
- this.ownDevice = ownDevice;
+ this.ownsDevice = ownsDevice;
resetFPSCounter();
}
+ /** Returns the recursive lock object of the upstream implementation, which synchronizes multithreaded access. */
protected abstract RecursiveLock getLock();
- /** Returns the delegated GLDrawable */
- public final GLDrawable getDelegatedDrawable() { return drawable; }
-
/** Default implementation to handle repaint events from the windowing system */
protected final void defaultWindowRepaintOp() {
final GLDrawable _drawable = drawable;
if( null != _drawable && _drawable.isRealized() ) {
- if( !_drawable.getNativeSurface().isSurfaceLockedByOtherThread() && !helper.isAnimatorAnimating() ) {
+ if( !_drawable.getNativeSurface().isSurfaceLockedByOtherThread() && !helper.isExternalAnimatorAnimating() ) {
display();
}
}
}
- /** Default implementation to handle resize events from the windowing system */
- protected final void defaultWindowResizedOp() {
- final GLDrawable _drawable = drawable;
+ /** Default implementation to handle resize events from the windowing system. All required locks are being claimed. */
+ protected final void defaultWindowResizedOp(int newWidth, int newHeight) throws NativeWindowException, GLException {
+ GLDrawableImpl _drawable = drawable;
if( null!=_drawable ) {
if(DEBUG) {
- System.err.println("GLAutoDrawableBase.sizeChanged: ("+Thread.currentThread().getName()+"): "+getWidth()+"x"+getHeight()+" - surfaceHandle 0x"+Long.toHexString(getNativeSurface().getSurfaceHandle()));
+ System.err.println("GLAutoDrawableBase.sizeChanged: ("+Thread.currentThread().getName()+"): "+newWidth+"x"+newHeight+" - surfaceHandle 0x"+Long.toHexString(getNativeSurface().getSurfaceHandle()));
+ }
+ if( ! _drawable.getChosenGLCapabilities().isOnscreen() ) {
+ final RecursiveLock _lock = getLock();
+ _lock.lock();
+ try {
+ final GLDrawableImpl _drawableNew = GLDrawableHelper.resizeOffscreenDrawable(_drawable, context, newWidth, newHeight);
+ if(_drawable != _drawableNew) {
+ // write back
+ _drawable = _drawableNew;
+ drawable = _drawableNew;
+ }
+ } finally {
+ _lock.unlock();
+ }
}
sendReshape = true; // async if display() doesn't get called below, but avoiding deadlock
if( _drawable.isRealized() ) {
- if( !_drawable.getNativeSurface().isSurfaceLockedByOtherThread() && !helper.isAnimatorAnimating() ) {
+ if( !_drawable.getNativeSurface().isSurfaceLockedByOtherThread() && !helper.isExternalAnimatorAnimating() ) {
display();
}
- }
+ }
}
}
-
+
/**
* Default implementation to handle destroy notifications from the windowing system.
*
* <p>
* If the {@link NativeSurface} does not implement {@link WindowClosingProtocol}
* or {@link WindowClosingMode#DISPOSE_ON_CLOSE} is enabled (default),
- * {@link #defaultDestroy()} is being called.
+ * a thread safe destruction is being induced.
* </p>
*/
protected final void defaultWindowDestroyNotifyOp() {
@@ -174,7 +186,7 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
ctrl.resume();
}
} else if (null != ns && ns.isSurfaceLockedByOtherThread()) {
- // surface is locked by another thread
+ // Surface is locked by another thread.
// Flag that destroy should be performed on the next
// attempt to display.
sendDestroy = true; // async, but avoiding deadlock
@@ -225,7 +237,7 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
}
_drawable.setRealized(false);
}
- if( ownDevice ) {
+ if( ownsDevice ) {
_drawable.getNativeSurface().getGraphicsConfiguration().getScreen().getDevice().close();
}
}
@@ -236,10 +248,9 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
public final void defaultSwapBuffers() throws GLException {
final RecursiveLock _lock = getLock();
_lock.lock();
- try {
- if(drawable!=null && context != null) {
+ try {
+ if(null != drawable) {
drawable.swapBuffers();
- helper.invokeGL(drawable, context, defaultSwapAction, defaultInitAction);
}
} finally {
_lock.unlock();
@@ -254,7 +265,7 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
@Override
public final void run() {
// Lock: Locked Surface/Window by MakeCurrent/Release
- helper.init(GLAutoDrawableBase.this);
+ helper.init(GLAutoDrawableBase.this, !sendReshape);
resetFPSCounter();
} };
@@ -276,7 +287,7 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
destroy();
return;
}
- final RecursiveLock _lock = getLock();
+ final RecursiveLock _lock = getLock();
_lock.lock();
try {
if( null != context ) {
@@ -288,12 +299,11 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
}
}
- protected final Runnable defaultSwapAction = new Runnable() {
- @Override
- public final void run() {
- drawable.swapBuffers();
- } } ;
-
+ @Override
+ public final GLDrawable getDelegatedDrawable() {
+ return drawable;
+ }
+
@Override
public final GLContext getContext() {
return context;
@@ -305,7 +315,7 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
lock.lock();
try {
final GLContext oldCtx = context;
- final boolean newCtxCurrent = helper.switchContext(drawable, oldCtx, newCtx, additionalCtxCreationFlags);
+ final boolean newCtxCurrent = GLDrawableHelper.switchContext(drawable, oldCtx, newCtx, additionalCtxCreationFlags);
context=(GLContextImpl)newCtx;
if(newCtxCurrent) {
context.makeCurrent();
@@ -490,8 +500,8 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
/**
* @param t the thread for which context release shall be skipped, usually the animation thread,
* ie. {@link Animator#getThread()}.
- * @deprecated this is an experimental feature,
- * intended for measuring performance in regards to GL context switch
+ * @deprecated This is an experimental feature,
+ * intended for measuring performance in regards to GL context switch.
*/
@Deprecated
public void setSkipContextReleaseThread(Thread t) {
@@ -529,4 +539,10 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
final GLDrawable _drawable = drawable;
return null != _drawable ? _drawable.getHandle() : 0;
}
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName()+"[ \n\tHelper: " + helper + ", \n\tDrawable: " + drawable +
+ ", \n\tContext: " + context + /** ", \n\tWindow: "+window+ ", \n\tFactory: "+factory+ */ "]";
+ }
}
diff --git a/src/jogl/classes/jogamp/opengl/GLBufferStateTracker.java b/src/jogl/classes/jogamp/opengl/GLBufferStateTracker.java
index 92e27cb..4a1a81b 100644
--- a/src/jogl/classes/jogamp/opengl/GLBufferStateTracker.java
+++ b/src/jogl/classes/jogamp/opengl/GLBufferStateTracker.java
@@ -100,7 +100,6 @@ public class GLBufferStateTracker {
public final void setBoundBufferObject(int target, int value) {
bindingMap.put(target, value);
if (DEBUG) {
- System.err.println();
System.err.println("GLBufferStateTracker.setBoundBufferObject() target 0x" +
Integer.toHexString(target) + " -> mapped bound buffer 0x" +
Integer.toHexString(value));
@@ -128,11 +127,16 @@ public class GLBufferStateTracker {
default: gotQueryTarget = false; break;
}
if (gotQueryTarget) {
+ final int glerrPre = caller.glGetError(); // clear
caller.glGetIntegerv(queryTarget, bufTmp, 0);
- value = bufTmp[0];
+ final int glerrPost = caller.glGetError(); // be safe, e.g. GL '3.0 Mesa 8.0.4' may produce an error querying GL_PIXEL_UNPACK_BUFFER_BINDING, ignore value
+ if(GL.GL_NO_ERROR == glerrPost) {
+ value = bufTmp[0];
+ } else {
+ value = 0;
+ }
if (DEBUG) {
- System.err.println();
- System.err.println("GLBufferStateTracker.getBoundBufferObject() [queried value]: target 0x" +
+ System.err.println("GLBufferStateTracker.getBoundBufferObject() glerr[pre 0x"+Integer.toHexString(glerrPre)+", post 0x"+Integer.toHexString(glerrPost)+"], [queried value]: target 0x" +
Integer.toHexString(target) + " / query 0x"+Integer.toHexString(queryTarget)+
" -> mapped bound buffer 0x" + Integer.toHexString(value));
}
@@ -142,7 +146,6 @@ public class GLBufferStateTracker {
return 0;
}
if (DEBUG) {
- System.err.println();
System.err.println("GLBufferStateTracker.getBoundBufferObject() [mapped value]: target 0x" +
Integer.toHexString(target) + " -> mapped bound buffer 0x" +
Integer.toHexString(value));
@@ -160,7 +163,6 @@ public class GLBufferStateTracker {
public final void clearBufferObjectState() {
bindingMap.clear();
if (DEBUG) {
- System.err.println();
System.err.println("GLBufferStateTracker.clearBufferObjectState()");
//Thread.dumpStack();
}
diff --git a/src/jogl/classes/jogamp/opengl/GLContextImpl.java b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
index bf6a0ee..65b5233 100644
--- a/src/jogl/classes/jogamp/opengl/GLContextImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
@@ -46,17 +46,21 @@ import java.util.HashMap;
import java.util.Map;
import com.jogamp.common.os.DynamicLookupHelper;
+import com.jogamp.common.os.Platform;
import com.jogamp.common.util.ReflectionUtil;
+import com.jogamp.common.util.VersionNumber;
import com.jogamp.gluegen.runtime.FunctionAddressResolver;
import com.jogamp.gluegen.runtime.ProcAddressTable;
import com.jogamp.gluegen.runtime.opengl.GLNameResolver;
import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver;
import com.jogamp.opengl.GLExtensions;
+import com.jogamp.opengl.GLRendererQuirks;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeSurface;
import javax.media.opengl.GL;
+import javax.media.opengl.GL2ES2;
import javax.media.opengl.GL2GL3;
import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLContext;
@@ -85,6 +89,7 @@ public abstract class GLContextImpl extends GLContext {
private String glRenderer;
private String glRendererLowerCase;
+ private String glVersion;
// Tracks creation and initialization of buffer objects to avoid
// repeated glGet calls upon glMapBuffer operations
@@ -93,7 +98,8 @@ public abstract class GLContextImpl extends GLContext {
private final GLStateTracker glStateTracker = new GLStateTracker();
private GLDebugMessageHandler glDebugHandler = null;
private final int[] boundFBOTarget = new int[] { 0, 0 }; // { draw, read }
-
+ private int defaultVAO = 0;
+
protected GLDrawableImpl drawable;
protected GLDrawableImpl drawableRead;
@@ -126,6 +132,9 @@ public abstract class GLContextImpl extends GLContext {
GLContextShareSet.synchronizeBufferObjectSharing(shareWith, this);
this.drawable = drawable;
+ if(null != drawable) {
+ drawable.associateContext(this, true);
+ }
this.drawableRead = drawable;
this.glDebugHandler = new GLDebugMessageHandler(this);
@@ -157,7 +166,7 @@ public abstract class GLContextImpl extends GLContext {
additionalCtxCreationFlags = 0;
glRenderer = "";
- glRendererLowerCase = glRenderer;
+ glRendererLowerCase = glRenderer;
if (boundFBOTarget != null) { // <init>
boundFBOTarget[0] = 0; // draw
@@ -205,8 +214,11 @@ public abstract class GLContextImpl extends GLContext {
if(!setWriteOnly || drawableRead==drawable) { // if !setWriteOnly || !explicitReadDrawable
drawableRead = (GLDrawableImpl) readWrite;
}
- final GLDrawable old = drawable;
+ final GLDrawableImpl old = drawable;
+ old.associateContext(this, false);
+ drawableRetargeted = null != drawable;
drawable = (GLDrawableImpl) readWrite ;
+ drawable.associateContext(this, true);
if(lockHeld) {
makeCurrent();
}
@@ -261,16 +273,21 @@ public abstract class GLContextImpl extends GLContext {
}
private void release(boolean inDestruction) throws GLException {
if(TRACE_SWITCH) {
- System.err.println(getThreadName() +": GLContext.ContextSwitch: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+" - release() - force: "+inDestruction+", "+lock);
+ System.err.println(getThreadName() +": GLContext.ContextSwitch: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+", surf "+toHexString(drawable.getHandle())+" - release() - force: "+inDestruction+", "+lock);
}
if ( !lock.isOwner(Thread.currentThread()) ) {
throw new GLException("Context not current on current thread "+Thread.currentThread().getName()+": "+this);
}
+ Throwable drawableContextMadeCurrentException = null;
final boolean actualRelease = ( inDestruction || lock.getHoldCount() == 1 ) && 0 != contextHandle;
try {
if( actualRelease ) {
if( !inDestruction ) {
- drawable.contextMadeCurrent(this, false);
+ try {
+ contextMadeCurrent(false);
+ } catch (Throwable t) {
+ drawableContextMadeCurrentException = t;
+ }
}
releaseImpl();
}
@@ -282,9 +299,13 @@ public abstract class GLContextImpl extends GLContext {
drawable.unlockSurface();
lock.unlock();
if(TRACE_SWITCH) {
- System.err.println(getThreadName() +": GLContext.ContextSwitch: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+" - "+(actualRelease?"switch":"keep ")+" - CONTEXT_RELEASE - "+lock);
+ System.err.println(getThreadName() +": GLContext.ContextSwitch: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+", surf "+toHexString(drawable.getHandle())+" - "+(actualRelease?"switch":"keep ")+" - CONTEXT_RELEASE - "+lock);
}
}
+ if(null != drawableContextMadeCurrentException) {
+ throw new GLException("GLContext.release(false) during GLDrawableImpl.contextMadeCurrent(this, false)", drawableContextMadeCurrentException);
+ }
+
}
protected abstract void releaseImpl() throws GLException;
@@ -292,7 +313,7 @@ public abstract class GLContextImpl extends GLContext {
public final void destroy() {
if (DEBUG || TRACE_SWITCH) {
System.err.println(getThreadName() + ": GLContextImpl.destroy.0: obj " + toHexString(hashCode()) + ", ctx " + toHexString(contextHandle) +
- ", isShared "+GLContextShareSet.isShared(this)+" - "+lock);
+ ", surf "+toHexString(drawable.getHandle())+", isShared "+GLContextShareSet.isShared(this)+" - "+lock);
}
if (contextHandle != 0) {
int lockRes = drawable.lockSurface();
@@ -300,6 +321,7 @@ public abstract class GLContextImpl extends GLContext {
// this would be odd ..
throw new GLException("Surface not ready to lock: "+drawable);
}
+ Throwable drawableContextRealizedException = null;
try {
// Must hold the lock around the destroy operation to make sure we
// don't destroy the context while another thread renders to it.
@@ -320,7 +342,18 @@ public abstract class GLContextImpl extends GLContext {
// needs current context to disable debug handler
makeCurrent();
}
- drawable.contextRealized(this, false);
+ try {
+ contextRealized(false);
+ drawable.associateContext(this, false);
+ } catch (Throwable t) {
+ drawableContextRealizedException = t;
+ }
+ if(0 != defaultVAO) {
+ int[] tmp = new int[] { defaultVAO };
+ gl.getGL2GL3().glBindVertexArray(0);
+ gl.getGL2GL3().glDeleteVertexArrays(1, tmp, 0);
+ defaultVAO = 0;
+ }
glDebugHandler.enable(false);
if(lock.getHoldCount() > 1) {
// pending release() after makeCurrent()
@@ -343,6 +376,9 @@ public abstract class GLContextImpl extends GLContext {
} finally {
drawable.unlockSurface();
}
+ if(null != drawableContextRealizedException) {
+ throw new GLException("GLContext.destroy() during GLDrawableImpl.contextRealized(this, false)", drawableContextRealizedException);
+ }
}
resetStates();
}
@@ -436,7 +472,7 @@ public abstract class GLContextImpl extends GLContext {
// For Mac OS X, however, we need to update the context to track resizes
drawableUpdatedNotify();
if(TRACE_SWITCH) {
- System.err.println(getThreadName() +": GLContext.ContextSwitch: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+" - keep - CONTEXT_CURRENT - "+lock);
+ System.err.println(getThreadName() +": GLContext.ContextSwitch: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+", surf "+toHexString(drawable.getHandle())+" - keep - CONTEXT_CURRENT - "+lock);
}
return CONTEXT_CURRENT;
} else {
@@ -476,7 +512,7 @@ public abstract class GLContextImpl extends GLContext {
if (res == CONTEXT_NOT_CURRENT) {
if(TRACE_SWITCH) {
- System.err.println(getThreadName() +": GLContext.ContextSwitch: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+" - switch - CONTEXT_NOT_CURRENT - "+lock);
+ System.err.println(getThreadName() +": GLContext.ContextSwitch: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+", surf "+toHexString(drawable.getHandle())+" - switch - CONTEXT_NOT_CURRENT - "+lock);
}
} else {
setCurrent(this);
@@ -497,19 +533,17 @@ public abstract class GLContextImpl extends GLContext {
gl = gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Trace", null, gl, new Object[] { System.err } ) );
}
- drawable.contextRealized(this, true);
+ contextRealized(true);
if(DEBUG || TRACE_SWITCH) {
- System.err.println(getThreadName() +": GLContext.ContextSwitch: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+" - switch - CONTEXT_CURRENT_NEW - "+lock);
- }
- } else {
- drawable.contextMadeCurrent(this, true);
-
- if(TRACE_SWITCH) {
- System.err.println(getThreadName() +": GLContext.ContextSwitch: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+" - switch - CONTEXT_CURRENT - "+lock);
+ System.err.println(getThreadName() +": GLContext.ContextSwitch: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+", surf "+toHexString(drawable.getHandle())+" - switch - CONTEXT_CURRENT_NEW - "+lock);
}
+ } else if(TRACE_SWITCH) {
+ System.err.println(getThreadName() +": GLContext.ContextSwitch: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+", surf "+toHexString(drawable.getHandle())+" - switch - CONTEXT_CURRENT - "+lock);
}
+ contextMadeCurrent(true);
+
/* FIXME: refactor dependence on Java 2D / JOGL bridge
// Try cleaning up any stale server-side OpenGL objects
@@ -536,6 +570,16 @@ public abstract class GLContextImpl extends GLContext {
final boolean created;
try {
created = createImpl(shareWith); // may throws exception if fails!
+ if( created && isGL3core() && ( ctxMajorVersion>3 || ctxMajorVersion==3 && ctxMinorVersion>=2 ) ) {
+ // Due to GL 3.2 core spec: E.2. DEPRECATED AND REMOVED FEATURES (p 331)
+ // There is no more default VAO buffer 0 bound, hence generating and binding one
+ // to avoid INVALID_OPERATION at VertexAttribPointer.
+ // More clear is GL 4.3 core spec: 10.4 (p 307).
+ final int[] tmp = new int[1];
+ gl.getGL2GL3().glGenVertexArrays(1, tmp, 0);
+ defaultVAO = tmp[0];
+ gl.getGL2GL3().glBindVertexArray(defaultVAO);
+ }
} finally {
if (null != shareWith) {
shareWith.getDrawableImpl().unlockSurface();
@@ -543,10 +587,10 @@ public abstract class GLContextImpl extends GLContext {
}
if (DEBUG || TRACE_SWITCH) {
if(created) {
- System.err.println(getThreadName() + ": Create GL context OK: obj " + toHexString(hashCode()) + ", ctx " + toHexString(contextHandle) + " for " + getClass().getName()+" - "+getGLVersion());
+ System.err.println(getThreadName() + ": Create GL context OK: obj " + toHexString(hashCode()) + ", ctx " + toHexString(contextHandle) + ", surf "+toHexString(drawable.getHandle())+" for " + getClass().getName()+" - "+getGLVersion());
// Thread.dumpStack();
} else {
- System.err.println(getThreadName() + ": Create GL context FAILED obj " + toHexString(hashCode()) + ", for " + getClass().getName());
+ System.err.println(getThreadName() + ": Create GL context FAILED obj " + toHexString(hashCode()) + ", surf "+toHexString(drawable.getHandle())+" for " + getClass().getName());
}
}
if(!created) {
@@ -592,6 +636,20 @@ public abstract class GLContextImpl extends GLContext {
protected abstract void makeCurrentImpl() throws GLException;
/**
+ * @see GLDrawableImpl#contextRealized(GLContext, boolean)
+ */
+ protected void contextRealized(boolean realized) {
+ drawable.contextRealized(this, realized);
+ }
+
+ /**
+ * @see GLDrawableImpl#contextMadeCurrent(GLContext, boolean)
+ */
+ protected void contextMadeCurrent(boolean current) {
+ drawable.contextMadeCurrent(this, current);
+ }
+
+ /**
* Platform dependent entry point for context creation.<br>
*
* This method is called from {@link #makeCurrentWithinLock()} .. {@link #makeCurrent()} .<br>
@@ -917,52 +975,58 @@ public abstract class GLContextImpl extends GLContext {
/**
* If major > 0 || minor > 0 : Use passed values, determined at creation time
- * If major==0 && minor == 0 : Use GL_VERSION
* Otherwise .. don't touch ..
*/
private final void setContextVersion(int major, int minor, int ctp, boolean setVersionString) {
- if (0==ctp) {
+ if ( 0 == ctp ) {
throw new GLException("Invalid GL Version "+major+"."+minor+", ctp "+toHexString(ctp));
}
- if(major>0 || minor>0) {
- if (!GLContext.isValidGLVersion(major, minor)) {
- GLException e = new GLException("Invalid GL Version "+major+"."+minor+", ctp "+toHexString(ctp));
- throw e;
- }
- ctxMajorVersion = major;
- ctxMinorVersion = minor;
- ctxOptions = ctp;
- if(setVersionString) {
- ctxVersionString = getGLVersion(ctxMajorVersion, ctxMinorVersion, ctxOptions, getGL().glGetString(GL.GL_VERSION));
- }
- return;
+
+ if (!GLContext.isValidGLVersion(major, minor)) {
+ throw new GLException("Invalid GL Version "+major+"."+minor+", ctp "+toHexString(ctp));
}
-
- if(major==0 && minor==0) {
- String versionStr = getGL().glGetString(GL.GL_VERSION);
- if(null==versionStr) {
- throw new GLException("GL_VERSION is NULL: "+this);
+ ctxMajorVersion = major;
+ ctxMinorVersion = minor;
+ ctxOptions = ctp;
+ if(setVersionString) {
+ ctxVersionString = getGLVersion(ctxMajorVersion, ctxMinorVersion, ctxOptions, gl.glGetString(GL.GL_VERSION));
+ ctxGLSLVersion = null;
+ if(ctxMajorVersion >= 2) { // >= ES2 || GL2.0
+ final String glslVersion = gl.glGetString(GL2ES2.GL_SHADING_LANGUAGE_VERSION);
+ if( null != glslVersion ) {
+ ctxGLSLVersion = new VersionNumber(glslVersion, ".");
+ if( ctxGLSLVersion.getMajor() < 1 ) {
+ ctxGLSLVersion = null; // failed ..
+ }
+ }
+ }
+ if( null == ctxGLSLVersion ){
+ final int[] sver = new int[2];
+ getStaticGLSLVersionNumber(ctxMajorVersion, ctxMinorVersion, ctxOptions, sver);
+ ctxGLSLVersion = new VersionNumber(sver[0], sver[1], 0);
}
- ctxOptions = ctp;
-
- // Set version
- GLVersionNumber version = new GLVersionNumber(versionStr);
+ }
+ }
+
+ private static final VersionNumber getGLVersionNumber(int ctp, String glVersionStr) {
+ if( null != glVersionStr ) {
+ final GLVersionNumber version = new GLVersionNumber(glVersionStr);
if (version.isValid()) {
- ctxMajorVersion = version.getMajor();
- ctxMinorVersion = version.getMinor();
- // We cannot promote a non ARB context to >= 3.1,
- // reduce it to 3.0 then.
- if ( ( ctxMajorVersion>3 || ctxMajorVersion==3 && ctxMinorVersion>=1 )
- && 0 == (ctxOptions & CTX_IS_ARB_CREATED) ) {
- ctxMajorVersion = 3;
- ctxMinorVersion = 0;
- }
- if(setVersionString) {
- ctxVersionString = getGLVersion(ctxMajorVersion, ctxMinorVersion, ctxOptions, versionStr);
- }
- return;
+ int major = version.getMajor();
+ int minor = version.getMinor();
+ // We cannot promote a non ARB context to >= 3.1,
+ // reduce it to 3.0 then.
+ if ( 0 == (ctp & CTX_IS_ARB_CREATED) &&
+ ( major > 3 || major == 3 && minor >= 1 ) ) {
+ major = 3;
+ minor = 0;
+ }
+ if ( GLContext.isValidGLVersion(major, minor) ) {
+ return new VersionNumber(major, minor, 0);
+ }
}
}
+ return null;
}
//----------------------------------------------------------------------
@@ -1002,14 +1066,18 @@ public abstract class GLContextImpl extends GLContext {
/**
* Pbuffer support; given that this is a GLContext associated with a
* pbuffer, binds this pbuffer to its texture target.
+ * @throws GLException if not implemented (default)
+ * @deprecated use FBO/GLOffscreenAutoDrawable instead of pbuffer
*/
- public abstract void bindPbufferToTexture();
+ public void bindPbufferToTexture() { throw new GLException("not implemented"); }
/**
* Pbuffer support; given that this is a GLContext associated with a
* pbuffer, releases this pbuffer from its texture target.
+ * @throws GLException if not implemented (default)
+ * @deprecated use FBO/GLOffscreenAutoDrawable instead of pbuffer
*/
- public abstract void releasePbufferFromTexture();
+ public void releasePbufferFromTexture() { throw new GLException("not implemented"); }
public abstract ByteBuffer glAllocateMemoryNV(int arg0, float arg1, float arg2, float arg3);
@@ -1047,7 +1115,7 @@ public abstract class GLContextImpl extends GLContext {
table.reset(getDrawableImpl().getGLDynamicLookupHelper() );
}
- private final boolean initGLRendererStrings() {
+ private final boolean initGLRendererAndGLVersionStrings() {
final GLDynamicLookupHelper glDynLookupHelper = getDrawableImpl().getGLDynamicLookupHelper();
final long _glGetString = glDynLookupHelper.dynamicLookupFunction("glGetString");
if(0 == _glGetString) {
@@ -1066,18 +1134,24 @@ public abstract class GLContextImpl extends GLContext {
Thread.dumpStack();
}
return false;
- } else {
- glRenderer = _glRenderer;
- glRendererLowerCase = glRenderer.toLowerCase();
- return true;
}
+ glRenderer = _glRenderer;
+ glRendererLowerCase = glRenderer.toLowerCase();
+
+ final String _glVersion = glGetStringInt(GL.GL_VERSION, _glGetString);
+ if(null == _glVersion) {
+ // FIXME
+ if(DEBUG) {
+ System.err.println("Warning: GL_VERSION is NULL.");
+ Thread.dumpStack();
+ }
+ return false;
+ }
+ glVersion = _glVersion;
+ return true;
}
}
- protected final String getGLRendererString(boolean lowerCase) {
- return lowerCase ? glRendererLowerCase : glRenderer;
- }
-
/**
* Sets the OpenGL implementation class and
* the cache of which GL functions are available for calling through this
@@ -1111,17 +1185,44 @@ public abstract class GLContextImpl extends GLContext {
final AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration();
final AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice();
- if( !initGLRendererStrings() && DEBUG) {
- System.err.println("Warning: intialization of GL renderer strings failed. "+adevice+" - "+GLContext.getGLVersion(major, minor, ctxProfileBits, null));
+ {
+ final boolean initGLRendererAndGLVersionStringsOK = initGLRendererAndGLVersionStrings();
+ if(DEBUG) {
+ if( !initGLRendererAndGLVersionStringsOK ) {
+ System.err.println("Warning: setGLFunctionAvailability: intialization of GL renderer strings failed. "+adevice+" - "+GLContext.getGLVersion(major, minor, ctxProfileBits, null));
+ } else {
+ System.err.println(getThreadName() + ": GLContext.setGLFuncAvail: Given "+adevice+" - "+GLContext.getGLVersion(major, minor, ctxProfileBits, glVersion));
+ }
+ }
}
if(!isCurrentContextHardwareRasterizer()) {
ctxProfileBits |= GLContext.CTX_IMPL_ACCEL_SOFT;
}
-
+
+ // Pick the version from the GL-version string,
+ // if smaller _or_ given major == 0.
+ final VersionNumber glVersionNumber;
+ {
+ final VersionNumber setGLVersionNumber = new VersionNumber(major, minor, 0);
+ final VersionNumber strGLVersionNumber = getGLVersionNumber(ctxProfileBits, glVersion);
+ if( null != strGLVersionNumber && ( strGLVersionNumber.compareTo(setGLVersionNumber) <= 0 || 0 == major ) ) {
+ glVersionNumber = strGLVersionNumber;
+ major = glVersionNumber.getMajor();
+ minor = glVersionNumber.getMinor();
+ } else {
+ glVersionNumber = setGLVersionNumber;
+ }
+ }
+ if ( !GLContext.isValidGLVersion(major, minor) ) {
+ throw new GLException("Invalid GL Version "+major+"."+minor+", ctp "+toHexString(ctxProfileBits)+", "+glVersion+", "+glVersionNumber);
+ }
+ if( 2 > major ) { // there is no ES2-compat for a profile w/ major < 2
+ ctxProfileBits &= ~GLContext.CTX_IMPL_ES2_COMPAT;
+ }
contextFQN = getContextFQN(adevice, major, minor, ctxProfileBits);
if (DEBUG) {
- System.err.println(getThreadName() + ": GLContext.setGLFuncAvail.0 FQN: "+contextFQN+" - "+GLContext.getGLVersion(major, minor, ctxProfileBits, null));
+ System.err.println(getThreadName() + ": GLContext.setGLFuncAvail.0 validated FQN: "+contextFQN+" - "+GLContext.getGLVersion(major, minor, ctxProfileBits, glVersion) + ", "+glVersionNumber);
}
//
@@ -1184,10 +1285,16 @@ public abstract class GLContextImpl extends GLContext {
ctxProfileBits |= CTX_IMPL_FBO;
}
+ if(FORCE_NO_FBO_SUPPORT) {
+ ctxProfileBits &= ~CTX_IMPL_FBO ;
+ }
+
//
// Set GL Version (complete w/ version string)
//
setContextVersion(major, minor, ctxProfileBits, true);
+
+ setRendererQuirks( 0 == ( ctxProfileBits & GLContext.CTX_IMPL_ACCEL_SOFT ) );
setDefaultSwapInterval();
@@ -1196,7 +1303,55 @@ public abstract class GLContextImpl extends GLContext {
}
}
- protected static final boolean hasFBOImpl(int major, int ctp, ExtensionAvailabilityCache extCache) {
+ private final void setRendererQuirks(boolean hwAccel) {
+ int[] quirks = new int[GLRendererQuirks.COUNT];
+ int i = 0;
+
+ // OS related quirks
+ if( Platform.getOSType() == Platform.OSType.MACOS ) {
+ final int quirk1 = GLRendererQuirks.NoOffscreenBitmap;
+ if(DEBUG) {
+ System.err.println("Quirk: "+GLRendererQuirks.toString(quirk1)+": cause: OS "+Platform.getOSType());
+ }
+ quirks[i++] = quirk1;
+ } else if( Platform.getOSType() == Platform.OSType.WINDOWS ) {
+ final int quirk = GLRendererQuirks.NoDoubleBufferedBitmap;
+ if(DEBUG) {
+ System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: OS "+Platform.getOSType());
+ }
+ quirks[i++] = quirk;
+ }
+
+ // Renderer related quirks, may also involve OS
+ if( Platform.OSType.ANDROID == Platform.getOSType() && glRendererLowerCase.contains("powervr") ) {
+ final int quirk = GLRendererQuirks.NoSetSwapInterval;
+ if(DEBUG) {
+ System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: OS "+Platform.getOSType() + " / Renderer " + glRenderer);
+ }
+ quirks[i++] = quirk;
+ }
+ if( glRendererLowerCase.contains("mesa") || glRendererLowerCase.contains("gallium") ) {
+ {
+ final int quirk = GLRendererQuirks.NoSetSwapIntervalPostRetarget;
+ if(DEBUG) {
+ System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: Renderer " + glRenderer);
+ }
+ quirks[i++] = quirk;
+ }
+ if( hwAccel /* glRendererLowerCase.contains("intel(r)") || glRendererLowerCase.contains("amd") */ )
+ {
+ final int quirk = GLRendererQuirks.NoDoubleBufferedPBuffer;
+ if(DEBUG) {
+ System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: Renderer " + glRenderer);
+ }
+ quirks[i++] = quirk;
+ }
+ }
+ glRendererQuirks = new GLRendererQuirks(quirks, 0, i);
+ }
+
+
+ private static final boolean hasFBOImpl(int major, int ctp, ExtensionAvailabilityCache extCache) {
return ( 0 != (ctp & CTX_PROFILE_ES) && major >= 2 ) || // ES >= 2.0
major >= 3 || // any >= 3.0 GL ctx
@@ -1212,7 +1367,7 @@ public abstract class GLContextImpl extends GLContext {
extCache.isExtensionAvailable(GLExtensions.OES_framebuffer_object) ) ; // OES_framebuffer_object excluded
}
- protected final void removeCachedVersion(int major, int minor, int ctxProfileBits) {
+ private final void removeCachedVersion(int major, int minor, int ctxProfileBits) {
if(!isCurrentContextHardwareRasterizer()) {
ctxProfileBits |= GLContext.CTX_IMPL_ACCEL_SOFT;
}
diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java b/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
index f780829..2bb22f7 100644
--- a/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
@@ -48,7 +48,7 @@ import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.OffscreenLayerSurface;
import javax.media.nativewindow.ProxySurface;
import javax.media.nativewindow.MutableSurface;
-import javax.media.nativewindow.ProxySurface.UpstreamSurfaceHook;
+import javax.media.nativewindow.UpstreamSurfaceHook;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesChooser;
import javax.media.opengl.GLCapabilitiesImmutable;
@@ -56,10 +56,15 @@ import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawable;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
+import javax.media.opengl.GLFBODrawable;
+import javax.media.opengl.GLOffscreenAutoDrawable;
import javax.media.opengl.GLPbuffer;
import javax.media.opengl.GLProfile;
import com.jogamp.nativewindow.MutableGraphicsConfiguration;
+import com.jogamp.nativewindow.DelegatedUpstreamSurfaceHookWithSurfaceSize;
+import com.jogamp.nativewindow.UpstreamSurfaceHookMutableSize;
+import com.jogamp.opengl.GLRendererQuirks;
/** Extends GLDrawableFactory with a few methods for handling
@@ -67,13 +72,23 @@ import com.jogamp.nativewindow.MutableGraphicsConfiguration;
Independent Bitmaps on Windows, pixmaps on X11). Direct access to
these GLDrawables is not supplied directly to end users, though
they may be instantiated by the GLJPanel implementation. */
+ at SuppressWarnings("deprecation")
public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
- protected static final boolean DEBUG = GLDrawableImpl.DEBUG;
+ protected static final boolean DEBUG = GLDrawableFactory.DEBUG; // allow package access
protected GLDrawableFactoryImpl() {
super();
}
+ @Override
+ public GLRendererQuirks getRendererQuirks(AbstractGraphicsDevice device) {
+ final GLContext ctx = getOrCreateSharedContextImpl(device);
+ if(null != ctx) {
+ return ctx.getRendererQuirks();
+ }
+ return null;
+ }
+
/**
* Returns the shared context mapped to the <code>device</code> {@link AbstractGraphicsDevice#getConnection()},
* either a pre-existing or newly created, or <code>null</code> if creation failed or not supported.<br>
@@ -98,24 +113,15 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
* @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared device to be used, may be <code>null</code> for the platform's default device.
*/
protected final AbstractGraphicsDevice getOrCreateSharedDevice(AbstractGraphicsDevice device) {
- if(null==device) {
- device = getDefaultDevice();
- if(null==device) {
- throw new InternalError("no default device");
- }
- if (GLProfile.DEBUG) {
- System.err.println("Info: GLDrawableFactoryImpl.getOrCreateSharedContext: using default device : "+device);
- }
- } else if( !getIsDeviceCompatible(device) ) {
- if (GLProfile.DEBUG) {
- System.err.println("Info: GLDrawableFactoryImpl.getOrCreateSharedContext: device not compatible : "+device);
- }
- return null;
+ device = validateDevice(device);
+ if( null != device) {
+ return getOrCreateSharedDeviceImpl(device);
}
- return getOrCreateSharedDeviceImpl(device);
+ return null;
}
protected abstract AbstractGraphicsDevice getOrCreateSharedDeviceImpl(AbstractGraphicsDevice device);
+
/**
* Returns the GLDynamicLookupHelper
* @param profile if EGL/ES, profile <code>1</code> refers to ES1 and <code>2</code> to ES2,
@@ -140,34 +146,34 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
try {
final OffscreenLayerSurface ols = NativeWindowFactory.getOffscreenLayerSurface(target, true);
if(null != ols) {
+ final GLCapabilitiesImmutable chosenCapsMod = GLGraphicsConfigurationUtil.fixOffscreenGLCapabilities(chosenCaps, this, adevice);
// layered surface -> Offscreen/[FBO|PBuffer]
- final GLCapabilities chosenCapsMod = (GLCapabilities) chosenCaps.cloneMutable();
- chosenCapsMod.setOnscreen(false);
- /* if( isFBOAvailable ) { // FIXME JAU: FBO n/a yet
- chosenCapsMod.setFBO(true);
- } else */
- if( canCreateGLPbuffer(adevice) ) {
- chosenCapsMod.setPBuffer(true);
- } else {
- chosenCapsMod.setFBO(false);
- chosenCapsMod.setPBuffer(false);
+ if( !chosenCapsMod.isFBO() && !chosenCapsMod.isPBuffer() ) {
+ throw new GLException("Neither FBO nor Pbuffer is available for "+chosenCapsMod+", "+target);
}
config.setChosenCapabilities(chosenCapsMod);
+ ols.setChosenCapabilities(chosenCapsMod);
if(DEBUG) {
- System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OnscreenDrawable -> Offscreen-Layer: "+target);
+ System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OnscreenDrawable -> Offscreen-Layer");
+ System.err.println("chosenCaps: "+chosenCaps);
+ System.err.println("chosenCapsMod: "+chosenCapsMod);
+ System.err.println("OffscreenLayerSurface: **** "+ols);
+ System.err.println("Target: **** "+target);
+ Thread.dumpStack();
}
if( ! ( target instanceof MutableSurface ) ) {
throw new IllegalArgumentException("Passed NativeSurface must implement SurfaceChangeable for offscreen layered surface: "+target);
}
- if( ((GLCapabilitiesImmutable)config.getRequestedCapabilities()).isFBO() && isFBOAvailable ) {
- // FIXME JAU: Need to revise passed MutableSurface to work w/ FBO ..
- final GLDrawableImpl dummyDrawable = createOnscreenDrawableImpl(target);
- result = new GLFBODrawableImpl(this, dummyDrawable, target, target.getWidth(), target.getHeight(), 0 /* textureUnit */);
+ if( chosenCapsMod.isFBO() ) {
+ // target surface is already a native one
+ result = createFBODrawableImpl(target, chosenCapsMod, 0);
} else {
result = createOffscreenDrawableImpl(target);
}
} else if(chosenCaps.isOnscreen()) {
// onscreen
+ final GLCapabilitiesImmutable chosenCapsMod = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(chosenCaps);
+ config.setChosenCapabilities(chosenCapsMod);
if(DEBUG) {
System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OnscreenDrawable: "+target);
}
@@ -175,15 +181,17 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
} else {
// offscreen
if(DEBUG) {
- System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OffScreenDrawable, FBO-chosen(-avail)/PBuffer: "+chosenCaps.isFBO()+"("+isFBOAvailable+")/"+chosenCaps.isPBuffer()+": "+target);
+ System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OffScreenDrawable, FBO chosen / avail, PBuffer: "+
+ chosenCaps.isFBO()+" / "+isFBOAvailable+", "+chosenCaps.isPBuffer()+": "+target);
}
if( ! ( target instanceof MutableSurface ) ) {
- throw new IllegalArgumentException("Passed NativeSurface must implement SurfaceChangeable for offscreen: "+target);
+ throw new IllegalArgumentException("Passed NativeSurface must implement MutableSurface for offscreen: "+target);
}
- if( ((GLCapabilitiesImmutable)config.getRequestedCapabilities()).isFBO() && isFBOAvailable ) {
- // FIXME JAU: Need to revise passed MutableSurface to work w/ FBO ..
- final GLDrawableImpl dummyDrawable = createOnscreenDrawableImpl(target);
- result = new GLFBODrawableImpl(this, dummyDrawable, target, target.getWidth(), target.getHeight(), 0 /* textureUnit */);
+ if( chosenCaps.isFBO() && isFBOAvailable ) {
+ // need to hook-up a native dummy surface since source may not have & use minimum GLCapabilities for it w/ same profile
+ final ProxySurface dummySurface = createDummySurfaceImpl(adevice, false, new GLCapabilities(chosenCaps.getGLProfile()), (GLCapabilitiesImmutable)config.getRequestedCapabilities(), null, 64, 64);
+ dummySurface.setUpstreamSurfaceHook(new DelegatedUpstreamSurfaceHookWithSurfaceSize(dummySurface.getUpstreamSurfaceHook(), target));
+ result = createFBODrawableImpl(dummySurface, chosenCaps, 0);
} else {
result = createOffscreenDrawableImpl(target);
}
@@ -206,7 +214,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
//---------------------------------------------------------------------------
//
- // PBuffer Offscreen GLDrawable construction
+ // PBuffer Offscreen GLAutoDrawable construction
//
@Override
@@ -234,7 +242,8 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
GLDrawableImpl drawable = null;
device.lock();
try {
- drawable = (GLDrawableImpl) createGLDrawable( createMutableSurfaceImpl(device, true, capsChosen, capsRequested, chooser, width, height, null) );
+ drawable = createOffscreenDrawableImpl( createMutableSurfaceImpl(device, true, capsChosen, capsRequested, chooser,
+ new UpstreamSurfaceHookMutableSize(width, height) ) );
if(null != drawable) {
drawable.setRealized(true);
}
@@ -242,10 +251,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
device.unlock();
}
- if(null==drawable) {
- throw new GLException("Could not create Pbuffer drawable for: "+device+", "+capsChosen+", "+width+"x"+height);
- }
- return new GLPbufferImpl( drawable, shareWith, true);
+ return new GLPbufferImpl( drawable, (GLContextImpl) drawable.createContext(shareWith) );
}
//---------------------------------------------------------------------------
@@ -253,6 +259,29 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
// Offscreen GLDrawable construction
//
+ public final boolean canCreateFBO(AbstractGraphicsDevice deviceReq, GLProfile glp) {
+ AbstractGraphicsDevice device = getOrCreateSharedDevice(deviceReq);
+ if(null == device) {
+ throw new GLException("No shared device for requested: "+deviceReq);
+ }
+ return GLContext.isFBOAvailable(device, glp);
+ }
+
+ @Override
+ public GLOffscreenAutoDrawable createOffscreenAutoDrawable(AbstractGraphicsDevice deviceReq,
+ GLCapabilitiesImmutable capsRequested,
+ GLCapabilitiesChooser chooser,
+ int width, int height,
+ GLContext shareWith) {
+ final GLDrawable drawable = createOffscreenDrawable( deviceReq, capsRequested, chooser, width, height );
+ drawable.setRealized(true);
+ final GLContext context = drawable.createContext(shareWith);
+ if(drawable instanceof GLFBODrawableImpl) {
+ return new GLOffscreenAutoDrawableImpl.FBOImpl( (GLFBODrawableImpl)drawable, context, null, null );
+ }
+ return new GLOffscreenAutoDrawableImpl( drawable, context, null, null);
+ }
+
@Override
public GLDrawable createOffscreenDrawable(AbstractGraphicsDevice deviceReq,
GLCapabilitiesImmutable capsRequested,
@@ -266,32 +295,33 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
throw new GLException("No shared device for requested: "+deviceReq);
}
- if( capsRequested.isFBO() && GLContext.isFBOAvailable(device, capsRequested.getGLProfile()) ) {
+ final GLCapabilitiesImmutable capsChosen = GLGraphicsConfigurationUtil.fixOffscreenGLCapabilities(capsRequested, this, device);
+
+ if( capsChosen.isFBO() ) {
device.lock();
try {
- return createFBODrawableImpl(device, capsRequested, chooser, width, height);
+ // Use minimum GLCapabilities for the dummy surface w/ same profile
+ final ProxySurface dummySurface = createDummySurfaceImpl(device, true, new GLCapabilities(capsChosen.getGLProfile()), capsRequested, null, width, height);
+ final GLDrawableImpl dummyDrawable = createOnscreenDrawableImpl(dummySurface);
+ return new GLFBODrawableImpl.ResizeableImpl(this, dummyDrawable, dummySurface, capsChosen, 0);
} finally {
device.unlock();
}
}
- final GLCapabilitiesImmutable capsChosen = GLGraphicsConfigurationUtil.fixOffscreenGLCapabilities(capsRequested, false, canCreateGLPbuffer(device));
device.lock();
try {
- return createOffscreenDrawableImpl( createMutableSurfaceImpl(device, true, capsChosen, capsRequested, chooser, width, height, null) );
+ return createOffscreenDrawableImpl( createMutableSurfaceImpl(device, true, capsChosen, capsRequested, chooser,
+ new UpstreamSurfaceHookMutableSize(width, height) ) );
} finally {
device.unlock();
}
}
- /** Creates a platform independent offscreen FBO GLDrawable implementation */
- protected GLDrawable createFBODrawableImpl(AbstractGraphicsDevice device, GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser,
- int initialWidth, int initialHeight) {
- final GLCapabilitiesImmutable dummyCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(requestedCaps);
- final NativeSurface dummySurface = createDummySurfaceImpl(device, true, dummyCaps, null, 64, 64);
+ /** Creates a platform independent FBO offscreen GLDrawable */
+ protected GLFBODrawable createFBODrawableImpl(NativeSurface dummySurface, GLCapabilitiesImmutable fboCaps, int textureUnit) {
final GLDrawableImpl dummyDrawable = createOnscreenDrawableImpl(dummySurface);
-
- return new GLFBODrawableImpl(this, dummyDrawable, dummySurface, initialWidth, initialHeight, 0 /* textureUnit */);
+ return new GLFBODrawableImpl(this, dummyDrawable, dummySurface, fboCaps, textureUnit);
}
/** Creates a platform dependent offscreen pbuffer/pixmap GLDrawable implementation */
@@ -311,15 +341,13 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
* @param capsChosen
* @param capsRequested
* @param chooser the custom chooser, may be null for default
- * @param width the initial width
- * @param height the initial height
- * @param lifecycleHook optional control of the surface's lifecycle
+ * @param upstreamHook surface size information and optional control of the surface's lifecycle
* @return the created {@link MutableSurface} instance w/o defined surface handle
*/
protected abstract ProxySurface createMutableSurfaceImpl(AbstractGraphicsDevice device, boolean createNewDevice,
GLCapabilitiesImmutable capsChosen,
GLCapabilitiesImmutable capsRequested,
- GLCapabilitiesChooser chooser, int width, int height, UpstreamSurfaceHook lifecycleHook);
+ GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstreamHook);
/**
* A dummy surface is not visible on screen and will not be used to render directly to,
@@ -334,9 +362,9 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
* @param width the initial width
* @param height the initial height
*
- * @return the created {@link MutableSurface} instance w/o defined surface handle
+ * @return the created {@link ProxySurface} instance w/o defined surface handle but platform specific {@link UpstreamSurfaceHook}.
*/
- public NativeSurface createDummySurface(AbstractGraphicsDevice deviceReq, GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser,
+ public ProxySurface createDummySurface(AbstractGraphicsDevice deviceReq, GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser,
int width, int height) {
final AbstractGraphicsDevice device = getOrCreateSharedDevice(deviceReq);
if(null == device) {
@@ -344,7 +372,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
}
device.lock();
try {
- return createDummySurfaceImpl(device, true, requestedCaps, chooser, width, height);
+ return createDummySurfaceImpl(device, true, requestedCaps, requestedCaps, chooser, width, height);
} finally {
device.unlock();
}
@@ -360,14 +388,17 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
* @param device a valid platform dependent target device.
* @param createNewDevice if <code>true</code> a new device instance is created using <code>device</code> details,
* otherwise <code>device</code> instance is used as-is.
+ * @param chosenCaps
* @param requestedCaps
* @param chooser the custom chooser, may be null for default
- * @param width the initial width
- * @param height the initial height
- * @return the created {@link MutableSurface} instance w/o defined surface handle
+ * @param width the initial width as returned by {@link NativeSurface#getWidth()}, not the actual dummy surface width.
+ * The latter is platform specific and small
+ * @param height the initial height as returned by {@link NativeSurface#getHeight()}, not the actual dummy surface height,
+ * The latter is platform specific and small
+ * @return the created {@link ProxySurface} instance w/o defined surface handle but platform specific {@link UpstreamSurfaceHook}.
*/
public abstract ProxySurface createDummySurfaceImpl(AbstractGraphicsDevice device, boolean createNewDevice,
- GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height);
+ GLCapabilitiesImmutable chosenCaps, GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height);
//---------------------------------------------------------------------------
//
@@ -412,24 +443,14 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
@Override
public GLContext createExternalGLContext() {
- NativeWindowFactory.getDefaultToolkitLock().lock();
- try {
- return createExternalGLContextImpl();
- } finally {
- NativeWindowFactory.getDefaultToolkitLock().unlock();
- }
+ return createExternalGLContextImpl();
}
protected abstract GLDrawable createExternalGLDrawableImpl();
@Override
public GLDrawable createExternalGLDrawable() {
- NativeWindowFactory.getDefaultToolkitLock().lock();
- try {
- return createExternalGLDrawableImpl();
- } finally {
- NativeWindowFactory.getDefaultToolkitLock().unlock();
- }
+ return createExternalGLDrawableImpl();
}
diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java b/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java
index 090c5fe..d4ff970 100644
--- a/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java
+++ b/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java
@@ -43,12 +43,18 @@ package jogamp.opengl;
import java.util.ArrayList;
import java.util.HashSet;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
import javax.media.opengl.GLAnimatorControl;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLException;
+import javax.media.opengl.GLFBODrawable;
import javax.media.opengl.GLRunnable;
import com.jogamp.opengl.util.Animator;
@@ -108,24 +114,27 @@ public class GLDrawableHelper {
/**
* Associate a new context to the drawable and also propagates the context/drawable switch by
* calling {@link GLContext#setGLDrawable(GLDrawable, boolean) newCtx.setGLDrawable(drawable, true);}.
- * <p>
- * If the old context's drawable was an {@link GLAutoDrawable}, it's reference to the given drawable
- * is being cleared by calling
- * {@link GLAutoDrawable#setContext(GLContext) ((GLAutoDrawable)oldCtx.getGLDrawable()).setContext(null)}.
- * </p>
* <p>
* If the old or new context was current on this thread, it is being released before switching the drawable.
* </p>
+ * <p>
+ * Be aware that the old context is still bound to the drawable,
+ * and that one context can only bound to one drawable at one time!
+ * </p>
+ * <p>
+ * No locking is being performed on the drawable, caller is required to take care of it.
+ * </p>
*
* @param drawable the drawable which context is changed
- * @param newCtx the new context
* @param oldCtx the old context
- * @return true if the newt context was current, otherwise false
+ * @param newCtx the new context
+ * @param newCtxCreationFlags additional creation flags if newCtx is not null and not been created yet, see {@link GLContext#setContextCreationFlags(int)}
+ * @return true if the new context was current, otherwise false
*
* @see GLAutoDrawable#setContext(GLContext)
*/
- public final boolean switchContext(GLDrawable drawable, GLContext oldCtx, GLContext newCtx, int additionalCtxCreationFlags) {
- if(null != oldCtx && oldCtx.isCurrent()) {
+ public static final boolean switchContext(GLDrawable drawable, GLContext oldCtx, GLContext newCtx, int newCtxCreationFlags) {
+ if( null != oldCtx && oldCtx.isCurrent() ) {
oldCtx.release();
}
final boolean newCtxCurrent;
@@ -134,17 +143,140 @@ public class GLDrawableHelper {
if(newCtxCurrent) {
newCtx.release();
}
- newCtx.setContextCreationFlags(additionalCtxCreationFlags);
+ newCtx.setContextCreationFlags(newCtxCreationFlags);
newCtx.setGLDrawable(drawable, true); // propagate context/drawable switch
} else {
newCtxCurrent = false;
}
- if(null!=oldCtx && oldCtx.getGLDrawable() instanceof GLAutoDrawable) {
- ((GLAutoDrawable)oldCtx.getGLDrawable()).setContext(null);
- }
return newCtxCurrent;
}
+ /**
+ * If the drawable is not realized, OP is a NOP.
+ * <ul>
+ * <li>release context if current</li>
+ * <li>destroy old drawable</li>
+ * <li>create new drawable</li>
+ * <li>attach new drawable to context</li>
+ * <li>make context current, if it was current</li>
+ * </ul>
+ * <p>
+ * No locking is being performed, caller is required to take care of it.
+ * </p>
+ *
+ * @param drawable
+ * @param context maybe null
+ * @return the new drawable
+ */
+ public static final GLDrawableImpl recreateGLDrawable(GLDrawableImpl drawable, GLContext context) {
+ if( ! drawable.isRealized() ) {
+ return drawable;
+ }
+ final boolean contextCurrent = null != context && context.isCurrent();
+ final GLDrawableFactory factory = drawable.getFactory();
+ final NativeSurface surface = drawable.getNativeSurface();
+ final ProxySurface proxySurface = (surface instanceof ProxySurface) ? (ProxySurface)surface : null;
+
+ if(contextCurrent) {
+ context.release();
+ }
+
+ if(null != proxySurface) {
+ proxySurface.enableUpstreamSurfaceHookLifecycle(false);
+ }
+ try {
+ drawable.setRealized(false);
+ drawable = (GLDrawableImpl) factory.createGLDrawable(surface); // [2]
+ drawable.setRealized(true);
+ } finally {
+ if(null != proxySurface) {
+ proxySurface.enableUpstreamSurfaceHookLifecycle(true);
+ }
+ }
+
+ if(null != context) {
+ context.setGLDrawable(drawable, true); // re-association
+ }
+
+ if(contextCurrent) {
+ context.makeCurrent();
+ }
+ return drawable;
+ }
+
+ /**
+ * Performs resize operation on the given drawable, assuming it is offscreen.
+ * <p>
+ * The {@link GLDrawableImpl}'s {@link NativeSurface} is being locked during operation.
+ * In case the holder is an auto drawable or similar, it's lock shall be claimed by the caller.
+ * </p>
+ * <p>
+ * May recreate the drawable via {@link #recreateGLDrawable(GLDrawableImpl, GLContext)}
+ * in case of a a pbuffer- or pixmap-drawable.
+ * </p>
+ * <p>
+ * FBO drawables are resized w/o drawable destruction.
+ * </p>
+ * <p>
+ * Offscreen resize operation is validated w/ drawable size in the end.
+ * An exception is thrown if not successful.
+ * </p>
+ *
+ * @param drawable
+ * @param context
+ * @param newWidth the new width, it's minimum is capped to 1
+ * @param newHeight the new height, it's minimum is capped to 1
+ * @return the new drawable in case of an pbuffer/pixmap drawable, otherwise the passed drawable is being returned.
+ * @throws NativeWindowException is drawable is not offscreen or it's surface lock couldn't be claimed
+ * @throws GLException may be thrown a resize operation
+ */
+ public static final GLDrawableImpl resizeOffscreenDrawable(GLDrawableImpl drawable, GLContext context, int newWidth, int newHeight)
+ throws NativeWindowException, GLException
+ {
+ if(drawable.getChosenGLCapabilities().isOnscreen()) {
+ throw new NativeWindowException("Drawable is not offscreen: "+drawable);
+ }
+ final NativeSurface ns = drawable.getNativeSurface();
+ final int lockRes = ns.lockSurface();
+ if (NativeSurface.LOCK_SURFACE_NOT_READY >= lockRes) {
+ throw new NativeWindowException("Could not lock surface of drawable: "+drawable);
+ }
+ boolean validateSize = true;
+ try {
+ if(DEBUG && ( 0>=newWidth || 0>=newHeight) ) {
+ System.err.println("WARNING: Odd size detected: "+newWidth+"x"+newHeight+", using safe size 1x1. Drawable "+drawable);
+ Thread.dumpStack();
+ }
+ if(0>=newWidth) { newWidth = 1; validateSize=false; }
+ if(0>=newHeight) { newHeight = 1; validateSize=false; }
+ // propagate new size
+ if(ns instanceof ProxySurface) {
+ final ProxySurface ps = (ProxySurface) ns;
+ final UpstreamSurfaceHook ush = ps.getUpstreamSurfaceHook();
+ if(ush instanceof UpstreamSurfaceHook.MutableSize) {
+ ((UpstreamSurfaceHook.MutableSize)ush).setSize(newWidth, newHeight);
+ } else if(DEBUG) { // we have to assume UpstreamSurfaceHook contains the new size already, hence size check @ bottom
+ System.err.println("GLDrawableHelper.resizeOffscreenDrawable: Drawable's offscreen ProxySurface n.a. UpstreamSurfaceHook.MutableSize, but "+ush.getClass().getName()+": "+ush);
+ }
+ } else if(DEBUG) { // we have to assume surface contains the new size already, hence size check @ bottom
+ System.err.println("GLDrawableHelper.resizeOffscreenDrawable: Drawable's offscreen surface n.a. ProxySurface, but "+ns.getClass().getName()+": "+ns);
+ }
+ if(drawable instanceof GLFBODrawable) {
+ if( null != context && context.isCreated() ) {
+ ((GLFBODrawable) drawable).resetSize(context.getGL());
+ }
+ } else {
+ drawable = GLDrawableHelper.recreateGLDrawable(drawable, context);
+ }
+ } finally {
+ ns.unlockSurface();
+ }
+ if( validateSize && ( drawable.getWidth() != newWidth || drawable.getHeight() != newHeight ) ) {
+ throw new InternalError("Incomplete resize operation: expected "+newWidth+"x"+newHeight+", has: "+drawable);
+ }
+ return drawable;
+ }
+
public final void addGLEventListener(GLEventListener listener) {
addGLEventListener(-1, listener);
}
@@ -196,32 +328,28 @@ public class GLDrawableHelper {
}
}
- private final boolean init(GLEventListener l, GLAutoDrawable drawable, boolean sendReshape) {
- if(listenersToBeInit.remove(l)) {
- l.init(drawable);
- if(sendReshape) {
- reshape(l, drawable, 0, 0, drawable.getWidth(), drawable.getHeight(), true /* setViewport */, false /* checkInit */);
- }
- return true;
+ private final void init(GLEventListener l, GLAutoDrawable drawable, boolean sendReshape) {
+ l.init(drawable);
+ if(sendReshape) {
+ reshape(l, drawable, 0, 0, drawable.getWidth(), drawable.getHeight(), true /* setViewport */, false /* checkInit */);
}
- return false;
}
- /** The default init action to be called once after ctx is being created @ 1st makeCurrent(). */
- public final void init(GLAutoDrawable drawable) {
+ /**
+ * The default init action to be called once after ctx is being created @ 1st makeCurrent().
+ * @param sendReshape set to true if the subsequent display call won't reshape, otherwise false to avoid double reshape.
+ **/
+ public final void init(GLAutoDrawable drawable, boolean sendReshape) {
synchronized(listenersLock) {
final ArrayList<GLEventListener> _listeners = listeners;
for (int i=0; i < _listeners.size(); i++) {
final GLEventListener listener = _listeners.get(i) ;
- // If make current ctx, invoked by invokGL(..), results in a new ctx, init gets called.
+ // If make ctx current, invoked by invokGL(..), results in a new ctx, init gets called.
// This may happen not just for initial setup, but for ctx recreation due to resource change (drawable/window),
- // hence the must always be initialized unconditional.
- listenersToBeInit.add(listener);
-
- if ( ! init( listener, drawable, true /* sendReshape */) ) {
- throw new GLException("GLEventListener "+listener+" already initialized: "+drawable);
- }
+ // hence it must be called unconditional, always.
+ listenersToBeInit.remove(listener); // remove if exist, avoiding dbl init
+ init( listener, drawable, sendReshape);
}
}
}
@@ -239,7 +367,9 @@ public class GLDrawableHelper {
final GLEventListener listener = _listeners.get(i) ;
// GLEventListener may need to be init,
// in case this one is added after the realization of the GLAutoDrawable
- init( listener, drawable, true /* sendReshape */) ;
+ if( listenersToBeInit.remove(listener) ) {
+ init( listener, drawable, true /* sendReshape */) ;
+ }
listener.display(drawable);
}
}
@@ -251,7 +381,9 @@ public class GLDrawableHelper {
// GLEventListener may need to be init,
// in case this one is added after the realization of the GLAutoDrawable
synchronized(listenersLock) {
- init( listener, drawable, false /* sendReshape */) ;
+ if( listenersToBeInit.remove(listener) ) {
+ init( listener, drawable, false /* sendReshape */) ;
+ }
}
}
if(setViewport) {
diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java b/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java
index abf2bf5..df7f742 100644
--- a/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java
@@ -43,6 +43,7 @@ package jogamp.opengl;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.ProxySurface;
+import javax.media.opengl.GL;
import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawable;
@@ -51,15 +52,17 @@ import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
public abstract class GLDrawableImpl implements GLDrawable {
- protected static final boolean DEBUG = Debug.debug("GLDrawable");
-
- protected GLDrawableImpl(GLDrawableFactory factory,
- NativeSurface comp,
- boolean realized) {
+ protected static final boolean DEBUG = GLDrawableFactoryImpl.DEBUG;
+
+ protected GLDrawableImpl(GLDrawableFactory factory, NativeSurface comp, boolean realized) {
+ this(factory, comp, (GLCapabilitiesImmutable) comp.getGraphicsConfiguration().getRequestedCapabilities(), realized);
+ }
+
+ protected GLDrawableImpl(GLDrawableFactory factory, NativeSurface comp, GLCapabilitiesImmutable requestedCapabilities, boolean realized) {
this.factory = factory;
this.surface = comp;
this.realized = realized;
- this.requestedCapabilities = (GLCapabilitiesImmutable) surface.getGraphicsConfiguration().getRequestedCapabilities();
+ this.requestedCapabilities = requestedCapabilities;
}
/**
@@ -76,31 +79,46 @@ public abstract class GLDrawableImpl implements GLDrawable {
if( !realized ) {
return; // destroyed already
}
- final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable)surface.getGraphicsConfiguration().getChosenCapabilities();
- if ( caps.getDoubleBuffered() ) {
- if(!surface.surfaceSwap()) {
- int lockRes = lockSurface(); // it's recursive, so it's ok within [makeCurrent .. release]
- if (NativeSurface.LOCK_SURFACE_NOT_READY == lockRes) {
- return;
+ int lockRes = lockSurface(); // it's recursive, so it's ok within [makeCurrent .. release]
+ if (NativeSurface.LOCK_SURFACE_NOT_READY == lockRes) {
+ return;
+ }
+ try {
+ if (NativeSurface.LOCK_SURFACE_CHANGED == lockRes) {
+ updateHandle();
+ }
+ final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable)surface.getGraphicsConfiguration().getChosenCapabilities();
+ if ( caps.getDoubleBuffered() ) {
+ if(!surface.surfaceSwap()) {
+ swapBuffersImpl(true);
}
- try {
- if (NativeSurface.LOCK_SURFACE_CHANGED == lockRes) {
- updateHandle();
- }
- swapBuffersImpl();
- } finally {
- unlockSurface();
+ } else {
+ final GLContext ctx = GLContext.getCurrent();
+ if(null!=ctx && ctx.getGLDrawable()==this) {
+ ctx.getGL().glFlush();
}
+ swapBuffersImpl(false);
}
- } else {
- GLContext ctx = GLContext.getCurrent();
- if(null!=ctx && ctx.getGLDrawable()==this) {
- ctx.getGL().glFinish();
- }
- }
+ } finally {
+ unlockSurface();
+ }
surface.surfaceUpdated(this, surface, System.currentTimeMillis());
}
- protected abstract void swapBuffersImpl();
+
+ /**
+ * Platform and implementation depending surface swap.
+ * <p>The surface is locked.</p>
+ * <p>
+ * If <code>doubleBuffered</code> is <code>true</code>,
+ * an actual platform dependent surface swap shall be executed.
+ * </p>
+ * <p>
+ * If <code>doubleBuffered</code> is <code>false</code>,
+ * {@link GL#glFlush()} has been called already and
+ * the implementation may execute implementation specific code.
+ * </p>
+ */
+ protected abstract void swapBuffersImpl(boolean doubleBuffered);
public final static String toHexString(long hex) {
return "0x" + Long.toHexString(hex);
@@ -181,6 +199,9 @@ public abstract class GLDrawableImpl implements GLDrawable {
System.err.println(getThreadName() + ": setRealized: "+getClass().getName()+" "+this.realized+" == "+realizedArg);
}
}
+ /**
+ * Platform specific realization of drawable
+ */
protected abstract void setRealizedImpl();
/**
@@ -189,7 +210,7 @@ public abstract class GLDrawableImpl implements GLDrawable {
* If <code>realized</code> is <code>true</code>, the context has just been created and made current.
* </p>
* <p>
- * If <code>realized</code> is <code>false</code>, the context is still current and will be release and destroyed after this method returns.
+ * If <code>realized</code> is <code>false</code>, the context is still current and will be released and destroyed after this method returns.
* </p>
* <p>
* @see #contextMadeCurrent(GLContext, boolean)
@@ -199,18 +220,27 @@ public abstract class GLDrawableImpl implements GLDrawable {
/**
* Callback for special implementations, allowing GLContext to trigger GL related lifecycle: <code>makeCurrent</code>, <code>release</code>.
* <p>
- * Will not be called if {@link #contextRealized(GLContext, boolean)} has been triggered.
- * </p>
- * <p>
* If <code>current</code> is <code>true</code>, the context has just been made current.
* </p>
* <p>
* If <code>current</code> is <code>false</code>, the context is still current and will be release after this method returns.
* </p>
+ * <p>
+ * Note: Will also be called after {@link #contextRealized(GLContext, boolean) contextRealized(ctx, true)}
+ * but not at context destruction, i.e. {@link #contextRealized(GLContext, boolean) contextRealized(ctx, false)}.
+ * </p>
* @see #contextRealized(GLContext, boolean)
*/
protected void contextMadeCurrent(GLContext glc, boolean current) { }
+ /**
+ * Callback for special implementations, allowing to associate bound context to this drawable (bound == true)
+ * or to remove such association (bound == false).
+ * @param ctx the just bounded or unbounded context
+ * @param bound if <code>true</code> create an association, otherwise remove it
+ */
+ protected void associateContext(GLContext ctx, boolean bound) { }
+
/** Callback for special implementations, allowing GLContext to fetch a custom default render framebuffer. Defaults to zero.*/
protected int getDefaultDrawFramebuffer() { return 0; }
/** Callback for special implementations, allowing GLContext to fetch a custom default read framebuffer. Defaults to zero. */
@@ -245,8 +275,8 @@ public abstract class GLDrawableImpl implements GLDrawable {
public String toString() {
return getClass().getSimpleName()+"[Realized "+isRealized()+
",\n\tFactory "+getFactory()+
- ",\n\thandle "+toHexString(getHandle())+
- ",\n\tWindow "+getNativeSurface()+"]";
+ ",\n\tHandle "+toHexString(getHandle())+
+ ",\n\tSurface "+getNativeSurface()+"]";
}
protected static String getThreadName() {
diff --git a/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java b/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java
index b7ea4f8..b5b723f 100644
--- a/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java
@@ -1,138 +1,551 @@
package jogamp.opengl;
import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
import javax.media.opengl.GL;
-import javax.media.opengl.GL2GL3;
+import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLException;
+import javax.media.opengl.GLFBODrawable;
+import com.jogamp.common.os.Platform;
+import com.jogamp.common.util.VersionUtil;
import com.jogamp.nativewindow.MutableGraphicsConfiguration;
import com.jogamp.opengl.FBObject;
import com.jogamp.opengl.FBObject.Attachment;
+import com.jogamp.opengl.FBObject.Colorbuffer;
import com.jogamp.opengl.FBObject.TextureAttachment;
+import com.jogamp.opengl.JoglVersion;
/**
- * Offscreen GLDrawable implementation using framebuffer object (FBO)
- * as it's offscreen rendering mechanism.
+ * {@link FBObject} offscreen GLDrawable implementation, i.e. {@link GLFBODrawable}.
+ * <p>
+ * It utilizes the context lifecycle hook {@link #contextRealized(GLContext, boolean)}
+ * to initialize the {@link FBObject} instance.
+ * </p>
+ * <p>
+ * It utilizes the context current hook {@link #contextMadeCurrent(GLContext, boolean) contextMadeCurrent(context, true)}
+ * to {@link FBObject#bind(GL) bind} the FBO.
+ * </p>
+ * See {@link GLFBODrawable} for double buffering details.
*
* @see GLDrawableImpl#contextRealized(GLContext, boolean)
* @see GLDrawableImpl#contextMadeCurrent(GLContext, boolean)
* @see GLDrawableImpl#getDefaultDrawFramebuffer()
* @see GLDrawableImpl#getDefaultReadFramebuffer()
*/
-public class GLFBODrawableImpl extends GLDrawableImpl {
- final GLDrawableImpl parent;
- final FBObject fbo;
- int texUnit;
- int samplesTexUnit = 0;
- int width=0, height=0, samples=0;
-
- protected GLFBODrawableImpl(GLDrawableFactoryImpl factory, GLDrawableImpl parent,
- NativeSurface surface, int initialWidth, int initialHeight, int textureUnit) {
- super(factory, surface, false);
+public class GLFBODrawableImpl extends GLDrawableImpl implements GLFBODrawable {
+ protected static final boolean DEBUG = GLDrawableImpl.DEBUG || Debug.debug("FBObject");
+
+ private final GLDrawableImpl parent;
+ private GLCapabilitiesImmutable origParentChosenCaps;
+
+ private boolean initialized;
+ private int texUnit;
+ private int samples;
+ private boolean fboResetQuirk;
+
+ private FBObject[] fbos;
+ private int fboIBack; // points to GL_BACK buffer
+ private int fboIFront; // points to GL_FRONT buffer
+ private int pendingFBOReset = -1;
+ private boolean fboBound;
+
+ private static volatile boolean resetQuirkInfoDumped = false;
+ private static final int bufferCount = 2; // number of FBOs for double buffering. TODO: Possible to configure!
+
+ // private DoubleBufferMode doubleBufferMode; // TODO: Add or remove TEXTURE (only) DoubleBufferMode support
+
+ private SwapBufferContext swapBufferContext;
+
+ public static interface SwapBufferContext {
+ public void swapBuffers(boolean doubleBuffered);
+ }
+
+ /**
+ * @param factory
+ * @param parent
+ * @param surface
+ * @param fboCaps the requested FBO capabilities
+ * @param textureUnit
+ */
+ protected GLFBODrawableImpl(GLDrawableFactoryImpl factory, GLDrawableImpl parent, NativeSurface surface,
+ GLCapabilitiesImmutable fboCaps, int textureUnit) {
+ super(factory, surface, fboCaps, false);
+ this.initialized = false;
+
this.parent = parent;
+ this.origParentChosenCaps = (GLCapabilitiesImmutable) getChosenGLCapabilities(); // just to avoid null, will be reset at initialize(..)
this.texUnit = textureUnit;
- final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) surface.getGraphicsConfiguration().getChosenCapabilities();
- this.width = initialWidth;
- this.height = initialHeight;
- this.samples = caps.getNumSamples();
- this.fbo = new FBObject();
+ this.samples = fboCaps.getNumSamples();
+ fboResetQuirk = false;
+
+ // default .. // TODO: Add or remove TEXTURE (only) DoubleBufferMode support
+ // this.doubleBufferMode = ( samples > 0 || fboCaps.getDoubleBuffered() ) ? DoubleBufferMode.FBO : DoubleBufferMode.NONE ;
+
+ this.swapBufferContext = null;
}
- @Override
- protected void contextRealized(GLContext glc, boolean realized) {
- final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) surface.getGraphicsConfiguration().getChosenCapabilities();
- final GL gl = glc.getGL();
- if(realized) {
- fbo.reset(gl, width, height, samples);
- samples = fbo.getNumSamples(); // update, maybe capped
+ private final void initialize(boolean realize, GL gl) {
+ if(realize) {
+ final GLCapabilities chosenFBOCaps = (GLCapabilities) getChosenGLCapabilities(); // cloned at setRealized(true)
+
+ final int maxSamples = gl.getMaxRenderbufferSamples();
+ {
+ final int newSamples = samples <= maxSamples ? samples : maxSamples;
+ if(DEBUG) {
+ System.err.println("GLFBODrawableImpl.initialize(): samples "+samples+" -> "+newSamples+"/"+maxSamples);
+ }
+ samples = newSamples;
+ }
+
+ final int fbosN;
if(samples > 0) {
- fbo.attachColorbuffer(gl, 0, caps.getAlphaBits()>0);
+ fbosN = 1;
+ } else if( chosenFBOCaps.getDoubleBuffered() ) {
+ fbosN = bufferCount;
} else {
- fbo.attachTexture2D(gl, 0, caps.getAlphaBits()>0);
+ fbosN = 1;
}
- if( caps.getStencilBits() > 0 ) {
- fbo.attachRenderbuffer(gl, Attachment.Type.DEPTH_STENCIL, 24);
- } else {
- fbo.attachRenderbuffer(gl, Attachment.Type.DEPTH, 24);
+
+ fbos = new FBObject[fbosN];
+ fboIBack = 0; // head
+ fboIFront = fbos.length - 1; // tail
+
+ for(int i=0; i<fbosN; i++) {
+ fbos[i] = new FBObject();
+ fbos[i].reset(gl, getWidth(), getHeight(), samples, false);
+ if(fbos[i].getNumSamples() != samples) {
+ throw new InternalError("Sample number mismatch: "+samples+", fbos["+i+"] "+fbos[i]);
+ }
+ if(samples > 0) {
+ fbos[i].attachColorbuffer(gl, 0, chosenFBOCaps.getAlphaBits()>0);
+ } else {
+ fbos[i].attachTexture2D(gl, 0, chosenFBOCaps.getAlphaBits()>0);
+ }
+ if( chosenFBOCaps.getStencilBits() > 0 ) {
+ fbos[i].attachRenderbuffer(gl, Attachment.Type.DEPTH_STENCIL, 24);
+ } else {
+ fbos[i].attachRenderbuffer(gl, Attachment.Type.DEPTH, 24);
+ }
}
- } else if(null != fbo) {
- fbo.destroy(gl);
- }
- }
-
- @Override
- protected void contextMadeCurrent(GLContext glc, boolean current) {
- final GL gl = glc.getGL();
- if(current) {
- fbo.bind(gl);
+ fbos[fboIFront].resetSamplingSink(gl);
+ fboBound = false;
+ fbos[0].formatToGLCapabilities(chosenFBOCaps);
+ chosenFBOCaps.setDoubleBuffered( chosenFBOCaps.getDoubleBuffered() || samples > 0 );
+
+ initialized = true;
} else {
- fbo.unbind(gl);
- gl.glActiveTexture(GL.GL_TEXTURE0 + texUnit);
- fbo.use(gl, samples > 0 ? fbo.getSamplingSink() : (TextureAttachment) fbo.getColorbuffer(0) );
- if( samples > 0) {
- gl.glBindFramebuffer(GL2GL3.GL_READ_FRAMEBUFFER, fbo.getReadFramebuffer());
+ initialized = false;
+
+ for(int i=0; i<fbos.length; i++) {
+ fbos[i].destroy(gl);
}
+ fbos=null;
+ fboBound = false;
+ pendingFBOReset = -1;
+ }
+ if(DEBUG) {
+ System.err.println("GLFBODrawableImpl.initialize("+realize+"): "+this);
+ Thread.dumpStack();
}
}
- @Override
- protected int getDefaultDrawFramebuffer() { return fbo.getWriteFramebuffer(); }
-
- @Override
- protected int getDefaultReadFramebuffer() { return fbo.getReadFramebuffer(); }
-
- public FBObject getFBObject() { return fbo; }
-
- public void setSize(GL gl, int newWidth, int newHeight) throws GLException {
- width = newWidth;
- height = newHeight;
- fbo.reset(gl, width, height, samples);
- samples = fbo.getNumSamples(); // update, maybe capped
+ public final void setSwapBufferContext(SwapBufferContext sbc) {
+ swapBufferContext = sbc;
}
-
- public void setSamples(GL gl, int newSamples) throws GLException {
- samples = newSamples;
- fbo.reset(gl, width, height, samples);
- samples = fbo.getNumSamples(); // update, maybe capped
+
+ private final void reset(GL gl, int idx, int width, int height, int samples, int alphaBits, int stencilBits) {
+ if( !fboResetQuirk ) {
+ try {
+ fbos[idx].reset(gl, width, height, samples, false);
+ if(fbos[idx].getNumSamples() != samples) {
+ throw new InternalError("Sample number mismatch: "+samples+", fbos["+idx+"] "+fbos[idx]);
+ }
+ return;
+ } catch (GLException e) {
+ if(DEBUG) {
+ e.printStackTrace();
+ }
+ if(!resetQuirkInfoDumped) { // dump info only once
+ resetQuirkInfoDumped = true;
+ System.err.println("GLFBODrawable: FBO Reset failed: "+e.getMessage());
+ System.err.println("GLFBODrawable: Enabling FBOResetQuirk, due to GL driver bug.");
+ final JoglVersion joglVersion = JoglVersion.getInstance();
+ if(DEBUG) {
+ System.err.println(VersionUtil.getPlatformInfo());
+ System.err.println(joglVersion.toString());
+ System.err.println(JoglVersion.getGLInfo(gl, null));
+ } else {
+ System.err.println(joglVersion.getBriefOSGLBuildInfo(gl, null));
+ }
+ }
+ fboResetQuirk = true;
+ // 'fallthrough' intended
+ }
+ }
+ // resetQuirk fallback
+ fbos[idx].destroy(gl);
+ fbos[idx] = new FBObject();
+ fbos[idx].reset(gl, getWidth(), getHeight(), samples, false);
+ if(fbos[idx].getNumSamples() != samples) {
+ throw new InternalError("Sample number mismatch: "+samples+", fbos["+idx+"] "+fbos[idx]);
+ }
+ if(samples > 0) {
+ fbos[idx].attachColorbuffer(gl, 0, alphaBits>0);
+ } else {
+ fbos[idx].attachTexture2D(gl, 0, alphaBits>0);
+ }
+ if( stencilBits > 0 ) {
+ fbos[idx].attachRenderbuffer(gl, Attachment.Type.DEPTH_STENCIL, 24);
+ } else {
+ fbos[idx].attachRenderbuffer(gl, Attachment.Type.DEPTH, 24);
+ }
+ }
+
+ private final void reset(GL gl, int newSamples) throws GLException {
+ if(!initialized) {
+ // NOP if not yet initializes
+ return;
+ }
+
+ final GLContext curContext = GLContext.getCurrent();
+ final GLContext ourContext = gl.getContext();
+ final boolean ctxSwitch = null != curContext && curContext != ourContext;
+ if(DEBUG) {
+ System.err.println("GLFBODrawableImpl.reset(newSamples "+newSamples+"): BEGIN - ctxSwitch "+ctxSwitch+", "+this);
+ Thread.dumpStack();
+ }
+ Throwable tFBO = null;
+ Throwable tGL = null;
+ ourContext.makeCurrent();
+ fboBound = false; // clear bound-flag immediatly, caused by contextMadeCurrent(..) - otherwise we would swap @ release
+ try {
+ final int maxSamples = gl.getMaxRenderbufferSamples();
+ newSamples = newSamples <= maxSamples ? newSamples : maxSamples;
+
+ if(0==samples && 0<newSamples || 0<samples && 0==newSamples) {
+ // MSAA on/off switch
+ if(DEBUG) {
+ System.err.println("GLFBODrawableImpl.reset(): samples [on/off] reconfig: "+samples+" -> "+newSamples+"/"+maxSamples);
+ }
+ initialize(false, gl);
+ samples = newSamples;
+ initialize(true, gl);
+ } else {
+ if(DEBUG) {
+ System.err.println("GLFBODrawableImpl.reset(): simple reconfig: "+samples+" -> "+newSamples+"/"+maxSamples);
+ }
+ final int nWidth = getWidth();
+ final int nHeight = getHeight();
+ samples = newSamples;
+ pendingFBOReset = ( 1 < fbos.length ) ? fboIFront : -1; // pending-front reset only w/ double buffering (or zero samples)
+ final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) surface.getGraphicsConfiguration().getChosenCapabilities();
+ for(int i=0; i<fbos.length; i++) {
+ if( pendingFBOReset != i ) {
+ reset(gl, i, nWidth, nHeight, samples, caps.getAlphaBits(), caps.getStencilBits());
+ }
+ }
+ final GLCapabilities fboCapsNative = (GLCapabilities) surface.getGraphicsConfiguration().getChosenCapabilities();
+ fbos[0].formatToGLCapabilities(fboCapsNative);
+ }
+ } catch (Throwable t) {
+ tFBO = t;
+ } finally {
+ try {
+ ourContext.release();
+ if(ctxSwitch) {
+ curContext.makeCurrent();
+ }
+ } catch (Throwable t) {
+ tGL = t;
+ }
+ }
+ if(null != tFBO) {
+ throw new GLException("GLFBODrawableImpl.reset(..) FBObject.reset(..) exception", tFBO);
+ }
+ if(null != tGL) {
+ throw new GLException("GLFBODrawableImpl.reset(..) GLContext.release() exception", tGL);
+ }
+ if(DEBUG) {
+ System.err.println("GLFBODrawableImpl.reset(newSamples "+newSamples+"): END "+this);
+ }
}
+ //
+ // GLDrawable
+ //
@Override
- public GLContext createContext(GLContext shareWith) {
+ public final GLContext createContext(GLContext shareWith) {
final GLContext ctx = parent.createContext(shareWith);
ctx.setGLDrawable(this, false);
return ctx;
}
+ //
+ // GLDrawableImpl
+ //
+
@Override
- public GLDynamicLookupHelper getGLDynamicLookupHelper() {
+ public final GLDynamicLookupHelper getGLDynamicLookupHelper() {
return parent.getGLDynamicLookupHelper();
}
@Override
- protected void swapBuffersImpl() {
- }
+ protected final int getDefaultDrawFramebuffer() { return initialized ? fbos[fboIBack].getWriteFramebuffer() : 0; }
+
+ @Override
+ protected final int getDefaultReadFramebuffer() { return initialized ? fbos[fboIFront].getReadFramebuffer() : 0; }
@Override
- protected void setRealizedImpl() {
- parent.setRealized(realized);
- if(realized) {
- final MutableGraphicsConfiguration msConfig = (MutableGraphicsConfiguration) surface.getGraphicsConfiguration();
- final GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable) msConfig.getChosenCapabilities();
- final GLCapabilitiesImmutable chosenFBOCaps = GLGraphicsConfigurationUtil.fixOffscreenGLCapabilities(chosenCaps, true /*FBO*/, false /*PBO*/);
+ protected final void setRealizedImpl() {
+ final MutableGraphicsConfiguration msConfig = (MutableGraphicsConfiguration) surface.getGraphicsConfiguration();
+ if(realized) {
+ parent.setRealized(true);
+ origParentChosenCaps = (GLCapabilitiesImmutable) msConfig.getChosenCapabilities();
+ final GLCapabilities chosenFBOCaps = (GLCapabilities) origParentChosenCaps.cloneMutable();
+ chosenFBOCaps.copyFrom(getRequestedGLCapabilities());
msConfig.setChosenCapabilities(chosenFBOCaps);
+ } else {
+ msConfig.setChosenCapabilities(origParentChosenCaps);
+ parent.setRealized(false);
}
}
-
+
@Override
- public int getWidth() {
- return width;
+ protected final void contextRealized(GLContext glc, boolean realized) {
+ initialize(realized, glc.getGL());
+ }
+
+ @Override
+ protected final void contextMadeCurrent(GLContext glc, boolean current) {
+ final GL gl = glc.getGL();
+ if(current) {
+ fbos[fboIBack].bind(gl);
+ fboBound = true;
+ } else {
+ if(fboBound) {
+ swapFBOImpl(glc);
+ swapFBOImplPost(glc);
+ fboBound=false;
+ if(DEBUG) {
+ System.err.println("Post FBO swap(@release): done");
+ }
+ }
+ }
+ }
+
+ @Override
+ protected void swapBuffersImpl(boolean doubleBuffered) {
+ final GLContext ctx = GLContext.getCurrent();
+ boolean doPostSwap = false;
+ if(null!=ctx && ctx.getGLDrawable()==this) {
+ if(fboBound) {
+ swapFBOImpl(ctx);
+ doPostSwap = true;
+ fboBound=false;
+ if(DEBUG) {
+ System.err.println("Post FBO swap(@swap): done");
+ }
+ }
+ }
+ if(null != swapBufferContext) {
+ swapBufferContext.swapBuffers(doubleBuffered);
+ }
+ if(doPostSwap) {
+ swapFBOImplPost(ctx);
+ }
+ }
+
+ private final void swapFBOImplPost(GLContext glc) {
+ // Safely reset the previous front FBO - after completing propagating swap
+ if(0 <= pendingFBOReset) {
+ final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) surface.getGraphicsConfiguration().getChosenCapabilities();
+ reset(glc.getGL(), pendingFBOReset, getWidth(), getHeight(), samples, caps.getAlphaBits(), caps.getStencilBits());
+ pendingFBOReset = -1;
+ }
+ }
+
+ private final void swapFBOImpl(GLContext glc) {
+ final GL gl = glc.getGL();
+ fbos[fboIBack].markUnbound(); // fast path, use(gl,..) is called below
+
+ if(DEBUG) {
+ int _fboIFront = ( fboIFront + 1 ) % fbos.length;
+ if(_fboIFront != fboIBack) { throw new InternalError("XXX: "+_fboIFront+"!="+fboIBack); }
+ }
+ fboIFront = fboIBack;
+ fboIBack = ( fboIBack + 1 ) % fbos.length;
+
+ final Colorbuffer colorbuffer = samples > 0 ? fbos[fboIFront].getSamplingSink() : fbos[fboIFront].getColorbuffer(0);
+ final TextureAttachment texAttachment;
+ if(colorbuffer instanceof TextureAttachment) {
+ texAttachment = (TextureAttachment) colorbuffer;
+ } else {
+ if(null == colorbuffer) {
+ throw new GLException("Front colorbuffer is null: samples "+samples+", "+this);
+ } else {
+ throw new GLException("Front colorbuffer is not a texture: "+colorbuffer.getClass().getName()+": samples "+samples+", "+colorbuffer+", "+this);
+ }
+ }
+ gl.glActiveTexture(GL.GL_TEXTURE0 + texUnit);
+ fbos[fboIFront].use(gl, texAttachment);
+
+ /* Included in above use command:
+ gl.glBindFramebuffer(GL2GL3.GL_DRAW_FRAMEBUFFER, fbos[fboIBack].getDrawFramebuffer());
+ gl.glBindFramebuffer(GL2GL3.GL_READ_FRAMEBUFFER, fbos[fboIFront].getReadFramebuffer());
+ } */
+
+ if(DEBUG) {
+ System.err.println("Post FBO swap(X): fboI back "+fboIBack+", front "+fboIFront+", num "+fbos.length);
+ }
}
+ //
+ // GLFBODrawable
+ //
+
@Override
- public int getHeight() {
- return height;
+ public final boolean isInitialized() {
+ return initialized;
+ }
+
+ @Override
+ public final void resetSize(GL gl) throws GLException {
+ reset(gl, samples);
}
+
+ @Override
+ public final int getTextureUnit() { return texUnit; }
+
+ @Override
+ public final void setTextureUnit(int u) { texUnit = u; }
+
+ @Override
+ public final int getNumSamples() { return samples; }
+
+ @Override
+ public void setNumSamples(GL gl, int newSamples) throws GLException {
+ if(samples != newSamples) {
+ reset(gl, newSamples);
+ }
+ }
+
+ /** // TODO: Add or remove TEXTURE (only) DoubleBufferMode support
+ @Override
+ public final DoubleBufferMode getDoubleBufferMode() {
+ return doubleBufferMode;
+ }
+
+ @Override
+ public final void setDoubleBufferMode(DoubleBufferMode mode) throws GLException {
+ if(initialized) {
+ throw new GLException("Not allowed past initialization: "+this);
+ }
+ final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) surface.getGraphicsConfiguration().getChosenCapabilities();
+ if(0 == samples && caps.getDoubleBuffered() && DoubleBufferMode.NONE != mode) {
+ doubleBufferMode = mode;
+ }
+ } */
+
+ @Override
+ public FBObject getFBObject(int bufferName) throws IllegalArgumentException {
+ if(!initialized) {
+ return null;
+ }
+ final FBObject res;
+ switch(bufferName) {
+ case GL.GL_FRONT:
+ if( samples > 0 ) {
+ res = fbos[0].getSamplingSinkFBO();
+ } else {
+ res = fbos[fboIFront];
+ }
+ break;
+ case GL.GL_BACK:
+ res = fbos[fboIBack];
+ break;
+ default:
+ throw new IllegalArgumentException(illegalBufferName+toHexString(bufferName));
+ }
+ return res;
+ }
+
+ @Override
+ public final TextureAttachment getTextureBuffer(int bufferName) throws IllegalArgumentException {
+ if(!initialized) {
+ return null;
+ }
+ final TextureAttachment res;
+ switch(bufferName) {
+ case GL.GL_FRONT:
+ if( samples > 0 ) {
+ res = fbos[0].getSamplingSink();
+ } else {
+ res = (TextureAttachment) fbos[fboIFront].getColorbuffer(0);
+ }
+ break;
+ case GL.GL_BACK:
+ if( samples > 0 ) {
+ throw new IllegalArgumentException("Cannot access GL_BACK buffer of MSAA FBO: "+this);
+ } else {
+ res = (TextureAttachment) fbos[fboIBack].getColorbuffer(0);
+ }
+ break;
+ default:
+ throw new IllegalArgumentException(illegalBufferName+toHexString(bufferName));
+ }
+ return res;
+ }
+ private static final String illegalBufferName = "Only GL_FRONT and GL_BACK buffer are allowed, passed ";
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName()+"[Initialized "+initialized+", realized "+isRealized()+", texUnit "+texUnit+", samples "+samples+
+ ",\n\tFactory "+getFactory()+
+ ",\n\tHandle "+toHexString(getHandle())+
+ ",\n\tCaps "+surface.getGraphicsConfiguration().getChosenCapabilities()+
+ ",\n\tfboI back "+fboIBack+", front "+fboIFront+", num "+(initialized ? fbos.length : 0)+
+ ",\n\tFBO front read "+getDefaultReadFramebuffer()+", "+getFBObject(GL.GL_FRONT)+
+ ",\n\tFBO back write "+getDefaultDrawFramebuffer()+", "+getFBObject(GL.GL_BACK)+
+ ",\n\tSurface "+getNativeSurface()+
+ "]";
+ }
+
+ public static class ResizeableImpl extends GLFBODrawableImpl implements GLFBODrawable.Resizeable {
+ protected ResizeableImpl(GLDrawableFactoryImpl factory, GLDrawableImpl parent, ProxySurface surface,
+ GLCapabilitiesImmutable fboCaps, int textureUnit) {
+ super(factory, parent, surface, fboCaps, textureUnit);
+ }
+
+ @Override
+ public final void setSize(GLContext context, int newWidth, int newHeight) throws NativeWindowException, GLException {
+ if(DEBUG) {
+ System.err.println("GLFBODrawableImpl.ResizeableImpl setSize: ("+Thread.currentThread().getName()+"): "+newWidth+"x"+newHeight+" - surfaceHandle 0x"+Long.toHexString(getNativeSurface().getSurfaceHandle()));
+ }
+ int lockRes = lockSurface();
+ if (NativeSurface.LOCK_SURFACE_NOT_READY >= lockRes) {
+ throw new NativeWindowException("Could not lock surface: "+this);
+ }
+ try {
+ // propagate new size
+ final ProxySurface ps = (ProxySurface) getNativeSurface();
+ final UpstreamSurfaceHook ush = ps.getUpstreamSurfaceHook();
+ if(ush instanceof UpstreamSurfaceHook.MutableSize) {
+ ((UpstreamSurfaceHook.MutableSize)ush).setSize(newWidth, newHeight);
+ } else {
+ throw new InternalError("GLFBODrawableImpl.ResizableImpl's ProxySurface doesn't hold a UpstreamSurfaceHookMutableSize but "+ush.getClass().getName()+", "+ps+", ush");
+ }
+ if( null != context && context.isCreated() ) {
+ resetSize(context.getGL());
+ }
+ } finally {
+ unlockSurface();
+ }
+ }
+ }
}
diff --git a/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java b/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java
index 3f38f33..31e52b8 100644
--- a/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java
+++ b/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java
@@ -28,17 +28,20 @@
package jogamp.opengl;
-import java.util.List;
-
+import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawableFactory;
+
+import com.jogamp.opengl.GLRendererQuirks;
public class GLGraphicsConfigurationUtil {
public static final String NV_coverage_sample = "NV_coverage_sample";
public static final int WINDOW_BIT = 1 << 0;
public static final int BITMAP_BIT = 1 << 1;
public static final int PBUFFER_BIT = 1 << 2;
- public static final int FBO_BIT = 1 << 3;
+ public static final int FBO_BIT = 1 << 3; // generic bit must be mapped to native one at impl. level
public static final int ALL_BITS = WINDOW_BIT | BITMAP_BIT | PBUFFER_BIT | FBO_BIT ;
public static final StringBuilder winAttributeBits2String(StringBuilder sb, int winattrbits) {
@@ -74,90 +77,173 @@ public class GLGraphicsConfigurationUtil {
}
/**
- * @param isFBO TODO
- * @return bitmask representing the input boolean in exclusive or logic, ie only one bit will be set
+ public static final int getWinAttributeBits(boolean isOnscreen, boolean isFBO, boolean isPBuffer, boolean isBitmap) {
+ int winattrbits = 0;
+ if(isOnscreen) {
+ winattrbits |= WINDOW_BIT;
+ }
+ if(isFBO) {
+ winattrbits |= FBO_BIT;
+ }
+ if(isPBuffer ){
+ winattrbits |= PBUFFER_BIT;
+ }
+ if(isBitmap) {
+ winattrbits |= BITMAP_BIT;
+ }
+ return winattrbits;
+ }
+ public static final int getWinAttributeBits(GLCapabilitiesImmutable caps) {
+ return getWinAttributeBits(caps.isOnscreen(), caps.isFBO(), caps.isPBuffer(), caps.isBitmap());
+ } */
+
+ /**
+ * @return bitmask representing the input boolean in exclusive or logic, ie only one bit will be set.
*/
- public static final int getWinAttributeBits(boolean isOnscreen, boolean isPBuffer, boolean isFBO) {
+ public static final int getExclusiveWinAttributeBits(boolean isOnscreen, boolean isFBO, boolean isPBuffer, boolean isBitmap) {
int winattrbits = 0;
if(isOnscreen) {
winattrbits |= WINDOW_BIT;
- } else {
- if(isFBO) {
- winattrbits |= FBO_BIT;
- }
- if (!isPBuffer) {
- winattrbits |= BITMAP_BIT;
- } else {
- winattrbits |= PBUFFER_BIT;
- }
+ } else if(isFBO) {
+ winattrbits |= FBO_BIT;
+ } else if(isPBuffer ){
+ winattrbits |= PBUFFER_BIT;
+ } else if(isBitmap) {
+ winattrbits |= BITMAP_BIT;
+ }
+ if(0 == winattrbits) {
+ throw new InternalError("Empty bitmask");
}
return winattrbits;
}
/**
- * @see #getWinAttributeBits(boolean, boolean, boolean)
+ * @see #getExclusiveWinAttributeBits(boolean, boolean, boolean, boolean)
*/
- public static final int getWinAttributeBits(GLCapabilitiesImmutable caps) {
- return getWinAttributeBits(caps.isOnscreen(), caps.isPBuffer(), false);
+ public static final int getExclusiveWinAttributeBits(GLCapabilitiesImmutable caps) {
+ return getExclusiveWinAttributeBits(caps.isOnscreen(), caps.isFBO(), caps.isPBuffer(), caps.isBitmap());
}
- public static final boolean addGLCapabilitiesPermutations(List<GLCapabilitiesImmutable> capsBucket, GLCapabilitiesImmutable temp, int winattrbits) {
- int preSize = capsBucket.size();
- if( 0 != ( WINDOW_BIT & winattrbits ) ) {
- GLCapabilities cpy = (GLCapabilities) temp.cloneMutable();
- cpy.setOnscreen(true);
- cpy.setPBuffer(false);
- cpy.setFBO(false);
- capsBucket.add(cpy);
- }
- if( 0 != ( PBUFFER_BIT & winattrbits ) || 0 != ( FBO_BIT & winattrbits ) ) {
- GLCapabilities cpy = (GLCapabilities) temp.cloneMutable();
- cpy.setFBO(0 != ( FBO_BIT & winattrbits ));
- cpy.setPBuffer(0 != ( PBUFFER_BIT & winattrbits ));
- capsBucket.add(cpy);
- }
- if( 0 != ( BITMAP_BIT & winattrbits ) ) {
- GLCapabilities cpy = (GLCapabilities) temp.cloneMutable();
- cpy.setOnscreen(false);
- cpy.setPBuffer(false);
- cpy.setFBO(false);
- capsBucket.add(cpy);
+ public static final GLCapabilities fixWinAttribBitsAndHwAccel(AbstractGraphicsDevice device, int winattrbits, GLCapabilities caps) {
+ caps.setBitmap ( 0 != ( BITMAP_BIT & winattrbits ) );
+ caps.setPBuffer ( 0 != ( PBUFFER_BIT & winattrbits ) );
+ caps.setFBO ( 0 != ( FBO_BIT & winattrbits ) );
+ // we reflect availability semantics, hence setting onscreen at last (maybe overwritten above)!
+ caps.setOnscreen( 0 != ( WINDOW_BIT & winattrbits ) );
+
+ final int accel = GLContext.isHardwareRasterizer( device, caps.getGLProfile() );
+ if(0 == accel && caps.getHardwareAccelerated() ) {
+ caps.setHardwareAccelerated(false);
}
- return capsBucket.size() > preSize;
- }
- public static GLCapabilitiesImmutable fixGLCapabilities(GLCapabilitiesImmutable capsRequested, boolean fboAvailable, boolean pbufferAvailable)
- {
+ return caps;
+ }
+
+ /**
+ * Fixes the requested {@link GLCapabilitiesImmutable} according to on- and offscreen usage.
+ * <p>
+ * No modification will be made for onscreen usage, for offscreen usage see
+ * {@link #fixOffscreenGLCapabilities(GLCapabilitiesImmutable, GLDrawableFactory, AbstractGraphicsDevice)}.
+ * </p>
+ * @param capsRequested the requested {@link GLCapabilitiesImmutable}
+ * @param factory the {@link GLDrawableFactory} used to validate the requested capabilities and later used to create the drawable.
+ * @param device the device on which the drawable will be created, maybe null for the {@link GLDrawableFactory#getDefaultDevice() default device}.
+ * @return either the given requested {@link GLCapabilitiesImmutable} instance if no modifications were required, or a modified {@link GLCapabilitiesImmutable} instance.
+ */
+ public static GLCapabilitiesImmutable fixGLCapabilities(GLCapabilitiesImmutable capsRequested,
+ GLDrawableFactory factory, AbstractGraphicsDevice device) {
if( !capsRequested.isOnscreen() ) {
- return fixOffscreenGLCapabilities(capsRequested, fboAvailable, pbufferAvailable);
+ return fixOffscreenGLCapabilities(capsRequested, factory, device);
}
- return fixOnscreenGLCapabilities(capsRequested);
+ return capsRequested;
}
-
+
public static GLCapabilitiesImmutable fixOnscreenGLCapabilities(GLCapabilitiesImmutable capsRequested)
{
- if( !capsRequested.isOnscreen() ) {
+ if( !capsRequested.isOnscreen() || capsRequested.isFBO() || capsRequested.isPBuffer() || capsRequested.isBitmap() ) {
// fix caps ..
- GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable();
+ final GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable();
+ caps2.setBitmap (false);
+ caps2.setPBuffer (false);
+ caps2.setFBO (false);
caps2.setOnscreen(true);
return caps2;
}
return capsRequested;
}
-
- public static GLCapabilitiesImmutable fixOffscreenGLCapabilities(GLCapabilitiesImmutable capsRequested, boolean fboAvailable, boolean pbufferAvailable)
+
+ public static GLCapabilitiesImmutable fixOffscreenBitOnly(GLCapabilitiesImmutable capsRequested)
{
- if( capsRequested.getDoubleBuffered() ||
- capsRequested.isOnscreen() ||
- ( fboAvailable != capsRequested.isFBO() ) ||
- ( pbufferAvailable != capsRequested.isPBuffer() ) )
+ if( capsRequested.isOnscreen() ) {
+ // fix caps ..
+ final GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable();
+ caps2.setOnscreen(false);
+ return caps2;
+ }
+ return capsRequested;
+ }
+
+ /**
+ * Fixes the requested {@link GLCapabilitiesImmutable} according to:
+ * <ul>
+ * <li>offscreen usage</li>
+ * <li>availability of FBO, PBuffer, Bitmap</li>
+ * <li>{@link GLRendererQuirks}</li>
+ * </ul>
+ * @param capsRequested the requested {@link GLCapabilitiesImmutable}
+ * @param factory the {@link GLDrawableFactory} used to validate the requested capabilities and later used to create the drawable.
+ * @param device the device on which the drawable will be created, maybe null for the {@link GLDrawableFactory#getDefaultDevice() default device}.
+ * @return either the given requested {@link GLCapabilitiesImmutable} instance if no modifications were required, or a modified {@link GLCapabilitiesImmutable} instance.
+ */
+ public static GLCapabilitiesImmutable fixOffscreenGLCapabilities(GLCapabilitiesImmutable capsRequested,
+ GLDrawableFactory factory, AbstractGraphicsDevice device) {
+ if(null == device) {
+ device = factory.getDefaultDevice();
+ }
+ final boolean fboAvailable = GLContext.isFBOAvailable(device, capsRequested.getGLProfile());
+ final boolean pbufferAvailable = factory.canCreateGLPbuffer(device);
+
+ final GLRendererQuirks glrq = factory.getRendererQuirks(device);
+ final boolean bitmapAvailable;
+ final boolean doubleBufferAvailable;
+
+ if(null != glrq) {
+ bitmapAvailable = !glrq.exist(GLRendererQuirks.NoOffscreenBitmap);
+ if( capsRequested.getDoubleBuffered() &&
+ ( capsRequested.isPBuffer() && glrq.exist(GLRendererQuirks.NoDoubleBufferedPBuffer) ) ||
+ ( capsRequested.isBitmap() && glrq.exist(GLRendererQuirks.NoDoubleBufferedBitmap) ) ) {
+ doubleBufferAvailable = false;
+ } else {
+ doubleBufferAvailable = true;
+ }
+ } else {
+ bitmapAvailable = true;
+ doubleBufferAvailable = true;
+ }
+
+ final boolean auto = !( fboAvailable && capsRequested.isFBO() ) &&
+ !( pbufferAvailable && capsRequested.isPBuffer() ) &&
+ !( bitmapAvailable && capsRequested.isBitmap() ) ;
+
+ final boolean useFBO = fboAvailable && ( auto || capsRequested.isFBO() ) ;
+ final boolean usePbuffer = !useFBO && pbufferAvailable && ( auto || capsRequested.isPBuffer() ) ;
+ final boolean useBitmap = !useFBO && !usePbuffer && bitmapAvailable && ( auto || capsRequested.isBitmap() ) ;
+
+ if( capsRequested.isOnscreen() ||
+ useFBO != capsRequested.isFBO() ||
+ usePbuffer != capsRequested.isPBuffer() ||
+ useBitmap != capsRequested.isBitmap() ||
+ !doubleBufferAvailable && capsRequested.getDoubleBuffered() )
{
// fix caps ..
- GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable();
- caps2.setDoubleBuffered(false); // FIXME DBLBUFOFFSCRN
+ final GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable();
caps2.setOnscreen(false);
- caps2.setFBO( fboAvailable );
- caps2.setPBuffer( pbufferAvailable );
+ caps2.setFBO( useFBO );
+ caps2.setPBuffer( usePbuffer );
+ caps2.setBitmap( useBitmap );
+ if( !doubleBufferAvailable ) {
+ caps2.setDoubleBuffered(false);
+ }
return caps2;
}
return capsRequested;
@@ -165,31 +251,40 @@ public class GLGraphicsConfigurationUtil {
public static GLCapabilitiesImmutable fixGLPBufferGLCapabilities(GLCapabilitiesImmutable capsRequested)
{
- if( capsRequested.getDoubleBuffered() || capsRequested.isOnscreen() || !capsRequested.isPBuffer() || capsRequested.isFBO() ) {
+ if( capsRequested.isOnscreen() ||
+ !capsRequested.isPBuffer() ||
+ capsRequested.isFBO() )
+ {
// fix caps ..
- GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable();
- caps2.setDoubleBuffered(false); // FIXME DBLBUFOFFSCRN - we don't need to be single buffered ..
+ final GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable();
caps2.setOnscreen(false);
- caps2.setPBuffer(true);
caps2.setFBO(false);
+ caps2.setPBuffer(true);
+ caps2.setBitmap(false);
return caps2;
}
return capsRequested;
}
/** Fix opaque setting while preserve alpha bits */
- public static GLCapabilitiesImmutable fixOpaqueGLCapabilities(GLCapabilitiesImmutable capsRequested, boolean isOpaque)
+ public static GLCapabilities fixOpaqueGLCapabilities(GLCapabilities capsRequested, boolean isOpaque)
{
- GLCapabilities caps2 = null;
-
if( capsRequested.isBackgroundOpaque() != isOpaque) {
final int alphaBits = capsRequested.getAlphaBits();
- caps2 = (GLCapabilities) capsRequested.cloneMutable();
- caps2.setBackgroundOpaque(isOpaque);
- caps2.setAlphaBits(alphaBits);
- return caps2;
+ capsRequested.setBackgroundOpaque(isOpaque);
+ capsRequested.setAlphaBits(alphaBits);
}
return capsRequested;
}
+ /** Fix double buffered setting */
+ public static GLCapabilitiesImmutable fixDoubleBufferedGLCapabilities(GLCapabilitiesImmutable capsRequested, boolean doubleBuffered)
+ {
+ if( capsRequested.getDoubleBuffered() != doubleBuffered) {
+ final GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable();
+ caps2.setDoubleBuffered(doubleBuffered);
+ return caps2;
+ }
+ return capsRequested;
+ }
}
diff --git a/src/jogl/classes/jogamp/opengl/GLOffscreenAutoDrawableImpl.java b/src/jogl/classes/jogamp/opengl/GLOffscreenAutoDrawableImpl.java
new file mode 100644
index 0000000..7701f20
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/GLOffscreenAutoDrawableImpl.java
@@ -0,0 +1,123 @@
+/**
+ * Copyright 2012 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community OR
+ * CONTRIBUTORS 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.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package jogamp.opengl;
+
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.opengl.GL;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLOffscreenAutoDrawable;
+
+import com.jogamp.common.util.locks.RecursiveLock;
+import com.jogamp.opengl.FBObject;
+import com.jogamp.opengl.GLAutoDrawableDelegate;
+
+import jogamp.opengl.GLFBODrawableImpl;
+
+public class GLOffscreenAutoDrawableImpl extends GLAutoDrawableDelegate implements GLOffscreenAutoDrawable {
+
+ /**
+ * @param drawable a valid and already realized {@link GLDrawable}
+ * @param context a valid {@link GLContext}, may not be made current (created) yet.
+ * @param upstreamWidget optional UI element holding this instance, see {@link #getUpstreamWidget()}.
+ * @param lock optional upstream lock, may be null
+ */
+ public GLOffscreenAutoDrawableImpl(GLDrawable drawable, GLContext context, Object upstreamWidget, RecursiveLock lock) {
+ super(drawable, context, upstreamWidget, true, lock);
+ }
+
+ @Override
+ public void setSize(int newWidth, int newHeight) throws NativeWindowException, GLException {
+ this.defaultWindowResizedOp(newWidth, newHeight);
+ }
+
+ public static class FBOImpl extends GLOffscreenAutoDrawableImpl implements GLOffscreenAutoDrawable.FBO {
+ /**
+ * @param drawable a valid and already realized {@link GLDrawable}
+ * @param context a valid {@link GLContext}, may not be made current (created) yet.
+ * @param upstreamWidget optional UI element holding this instance, see {@link #getUpstreamWidget()}.
+ * @param lock optional upstream lock, may be null
+ */
+ public FBOImpl(GLFBODrawableImpl drawable, GLContext context, Object upstreamWidget, RecursiveLock lock) {
+ super(drawable, context, upstreamWidget, lock);
+ }
+
+ @Override
+ public boolean isInitialized() {
+ return ((GLFBODrawableImpl)drawable).isInitialized();
+ }
+
+ @Override
+ public final int getTextureUnit() {
+ return ((GLFBODrawableImpl)drawable).getTextureUnit();
+ }
+
+ @Override
+ public final void setTextureUnit(int unit) {
+ ((GLFBODrawableImpl)drawable).setTextureUnit(unit);
+ }
+
+ @Override
+ public final int getNumSamples() {
+ return ((GLFBODrawableImpl)drawable).getNumSamples();
+ }
+
+ @Override
+ public final void setNumSamples(GL gl, int newSamples) throws GLException {
+ ((GLFBODrawableImpl)drawable).setNumSamples(gl, newSamples);
+ windowRepaintOp();
+ }
+
+ /** // TODO: Add or remove TEXTURE (only) DoubleBufferMode support
+ @Override
+ public DoubleBufferMode getDoubleBufferMode() {
+ return ((GLFBODrawableImpl)drawable).getDoubleBufferMode();
+ }
+
+ @Override
+ public void setDoubleBufferMode(DoubleBufferMode mode) throws GLException {
+ ((GLFBODrawableImpl)drawable).setDoubleBufferMode(mode);
+ } */
+
+ @Override
+ public final FBObject getFBObject(int bufferName) {
+ return ((GLFBODrawableImpl)drawable).getFBObject(bufferName);
+ }
+
+ public final FBObject.TextureAttachment getTextureBuffer(int bufferName) {
+ return ((GLFBODrawableImpl)drawable).getTextureBuffer(bufferName);
+ }
+
+ @Override
+ public void resetSize(GL gl) throws GLException {
+ ((GLFBODrawableImpl)drawable).resetSize(gl);
+ }
+ }
+}
diff --git a/src/jogl/classes/jogamp/opengl/GLPbufferImpl.java b/src/jogl/classes/jogamp/opengl/GLPbufferImpl.java
index 32f4cb6..b438131 100644
--- a/src/jogl/classes/jogamp/opengl/GLPbufferImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLPbufferImpl.java
@@ -40,9 +40,6 @@
package jogamp.opengl;
-import javax.media.opengl.GLCapabilitiesImmutable;
-import javax.media.opengl.GLContext;
-import javax.media.opengl.GLDrawable;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
import javax.media.opengl.GLPbuffer;
@@ -50,36 +47,18 @@ import javax.media.opengl.GLPbuffer;
import com.jogamp.common.util.locks.LockFactory;
import com.jogamp.common.util.locks.RecursiveLock;
-/** Platform-independent class exposing pbuffer functionality to
- applications. This class is not exposed in the public API as it
- would probably add no value; however it implements the GLDrawable
- interface so can be interacted with via its display() method. */
-
+ at SuppressWarnings("deprecation")
public class GLPbufferImpl extends GLAutoDrawableBase implements GLPbuffer {
private int floatMode;
- public GLPbufferImpl(GLDrawableImpl pbufferDrawable, GLContext sharedContext, boolean ownDevice) {
- super(pbufferDrawable, null, ownDevice); // drawable := pbufferDrawable
-
- GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable)
- drawable.getNativeSurface().getGraphicsConfiguration().getChosenCapabilities();
- if(caps.isOnscreen()) {
- if(caps.isPBuffer()) {
- throw new IllegalArgumentException("Error: Given drawable is Onscreen and Pbuffer: "+pbufferDrawable);
- }
- throw new IllegalArgumentException("Error: Given drawable is Onscreen: "+pbufferDrawable);
- } else {
- if(!caps.isPBuffer()) {
- throw new IllegalArgumentException("Error: Given drawable is not Pbuffer: "+pbufferDrawable);
- }
- }
- context = (GLContextImpl) drawable.createContext(sharedContext);
+ public GLPbufferImpl(GLDrawableImpl pbufferDrawable, GLContextImpl pbufferContext) {
+ super(pbufferDrawable, pbufferContext, true); // drawable := pbufferDrawable, context := pbufferContext
}
//
// pbuffer specifics
- //
-
+ //
+
@Override
public void bindTexture() {
// Doesn't make much sense to try to do this on the event dispatch
diff --git a/src/jogl/classes/jogamp/opengl/GLVersionNumber.java b/src/jogl/classes/jogamp/opengl/GLVersionNumber.java
index 5bd008f..1004f04 100644
--- a/src/jogl/classes/jogamp/opengl/GLVersionNumber.java
+++ b/src/jogl/classes/jogamp/opengl/GLVersionNumber.java
@@ -53,26 +53,26 @@ class GLVersionNumber extends VersionNumber {
tok.nextToken(); // GL_
tok.nextToken(); // VERSION_
if (!tok.hasMoreTokens()) {
- major = 0;
+ val[0] = 0;
return;
}
- major = Integer.valueOf(tok.nextToken()).intValue();
+ val[0] = Integer.valueOf(tok.nextToken()).intValue();
if (!tok.hasMoreTokens()) {
- minor = 0;
+ val[1] = 0;
return;
}
- minor = Integer.valueOf(tok.nextToken()).intValue();
+ val[1] = Integer.valueOf(tok.nextToken()).intValue();
if (!tok.hasMoreTokens()) {
- sub = 0;
+ val[2] = 0;
return;
}
- sub = Integer.valueOf(tok.nextToken()).intValue();
+ val[2] = Integer.valueOf(tok.nextToken()).intValue();
} else {
int radix = 10;
if (versionString.length() > 2) {
if (Character.isDigit(versionString.charAt(0)) && versionString.charAt(1) == '.' && Character.isDigit(versionString.charAt(2))) {
- major = Character.digit(versionString.charAt(0), radix);
- minor = Character.digit(versionString.charAt(2), radix);
+ val[0] = Character.digit(versionString.charAt(0), radix);
+ val[1] = Character.digit(versionString.charAt(2), radix);
// See if there's version-specific information which might
// imply a more recent OpenGL version
StringTokenizer tok = new StringTokenizer(versionString, " ");
@@ -90,9 +90,9 @@ class GLVersionNumber extends VersionNumber {
// Avoid possibly confusing situations by putting some
// constraints on the upgrades we do to the major and
// minor versions
- if ((altMajor == major && altMinor > minor) || altMajor == major + 1) {
- major = altMajor;
- minor = altMinor;
+ if ((altMajor == val[0] && altMinor > val[1]) || altMajor == val[0] + 1) {
+ val[0] = altMajor;
+ val[1] = altMinor;
}
}
}
@@ -106,8 +106,8 @@ class GLVersionNumber extends VersionNumber {
// FIXME: refactor desktop OpenGL dependencies and make this
// class work properly for OpenGL ES
System.err.println("Info: ExtensionAvailabilityCache: FunctionAvailabilityCache.Version.<init>: " + e);
- major = 1;
- minor = 0;
+ val[0] = 1;
+ val[1] = 0;
/*
throw (IllegalArgumentException)
new IllegalArgumentException(
diff --git a/src/test/com/jogamp/opengl/test/junit/util/InputEventCountAdapter.java b/src/jogl/classes/jogamp/opengl/GLXExtensions.java
similarity index 75%
copy from src/test/com/jogamp/opengl/test/junit/util/InputEventCountAdapter.java
copy to src/jogl/classes/jogamp/opengl/GLXExtensions.java
index 27f3d7e..36c6c46 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/InputEventCountAdapter.java
+++ b/src/jogl/classes/jogamp/opengl/GLXExtensions.java
@@ -1,16 +1,16 @@
/**
- * Copyright 2010 JogAmp Community. All rights reserved.
+ * Copyright 2012 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
- *
+ *
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
- *
+ *
* 2. 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.
- *
+ *
* THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community OR
@@ -20,16 +20,18 @@
* 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.
- *
+ *
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of JogAmp Community.
*/
-
-package com.jogamp.opengl.test.junit.util;
+package jogamp.opengl;
-public interface InputEventCountAdapter extends EventCountAdapter {
- int getCount();
- boolean isPressed();
+/**
+ * Class holding GLX/WGL/.. extension strings, commonly used by JOGL's implementation.
+ */
+public class GLXExtensions {
+ public static final String GLX_MESA_swap_control = "GLX_MESA_swap_control";
+ public static final String GLX_SGI_swap_control = "GLX_SGI_swap_control";
+ public static final String GLX_NV_swap_group = "GLX_NV_swap_group";
}
-
diff --git a/src/jogl/classes/jogamp/opengl/ProjectFloat.java b/src/jogl/classes/jogamp/opengl/ProjectFloat.java
index ce8405f..18fe3e7 100644
--- a/src/jogl/classes/jogamp/opengl/ProjectFloat.java
+++ b/src/jogl/classes/jogamp/opengl/ProjectFloat.java
@@ -135,7 +135,7 @@ import com.jogamp.opengl.FloatUtil;
* @author Sven Gothel
*/
public class ProjectFloat {
- public static final int getRequiredFloatBufferSize() { return 2*16+2*4+3*3; }
+ public static final int getRequiredFloatBufferSize() { return 1*16; }
// Note that we have cloned parts of the implementation in order to
// support incoming Buffers. The reason for this is to avoid loading
@@ -153,18 +153,14 @@ public class ProjectFloat {
private final float[] out = new float[4];
// Buffer-based implementation
- private FloatBuffer matrixBuf;
- private FloatBuffer tempInvertMatrixBuf;
+ private FloatBuffer matrixBuf; // 4x4
- private FloatBuffer inBuf;
- private FloatBuffer outBuf;
-
- private FloatBuffer forwardBuf;
- private FloatBuffer sideBuf;
- private FloatBuffer upBuf;
+ private final float[] forward = new float[3]; // 3
+ private final float[] side = new float[3]; // 3
+ private final float[] up = new float[3]; // 3
public ProjectFloat() {
- this(false);
+ this(true);
}
public ProjectFloat(boolean useBackingArray) {
@@ -182,33 +178,11 @@ public class ProjectFloat {
* @param floatOffset Offset for either of the given sources (buffer or array)
*/
public ProjectFloat(Buffer floatBuffer, float[] floatArray, int floatOffset) {
- int floatPos = floatOffset;
- int floatSize = 16;
- matrixBuf = Buffers.slice2Float(floatBuffer, floatArray, floatPos, floatSize);
- floatPos += floatSize;
- tempInvertMatrixBuf = Buffers.slice2Float(floatBuffer, floatArray, floatPos, floatSize);
- floatPos += floatSize;
- floatSize = 4;
- inBuf = Buffers.slice2Float(floatBuffer, floatArray, floatPos, floatSize);
- floatPos += floatSize;
- outBuf = Buffers.slice2Float(floatBuffer, floatArray, floatPos, floatSize);
- floatPos += floatSize;
- floatSize = 3;
- forwardBuf = Buffers.slice2Float(floatBuffer, floatArray, floatPos, floatSize);
- floatPos += floatSize;
- sideBuf = Buffers.slice2Float(floatBuffer, floatArray, floatPos, floatSize);
- floatPos += floatSize;
- upBuf = Buffers.slice2Float(floatBuffer, floatArray, floatPos, floatSize);
+ matrixBuf = Buffers.slice2Float(floatBuffer, floatArray, floatOffset, 16);
}
public void destroy() {
matrixBuf = null;
- tempInvertMatrixBuf = null;
- inBuf = null;
- outBuf = null;
- forwardBuf = null;
- sideBuf = null;
- upBuf = null;
}
/**
@@ -221,7 +195,7 @@ public class ProjectFloat {
public boolean gluInvertMatrixf(float[] src, int srcOffset, float[] inverse, int inverseOffset) {
int i, j, k, swap;
float t;
- float[][] temp = tempInvertMatrix;
+ final float[][] temp = tempInvertMatrix;
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
@@ -292,14 +266,14 @@ public class ProjectFloat {
int i, j, k, swap;
float t;
- int srcPos = src.position();
- int invPos = inverse.position();
-
- FloatBuffer temp = tempInvertMatrixBuf;
+ final int srcPos = src.position();
+ final int invPos = inverse.position();
+
+ final float[][] temp = tempInvertMatrix;
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
- temp.put(i*4+j, src.get(i*4+j + srcPos));
+ temp[i][j] = src.get(i*4+j + srcPos);
}
}
FloatUtil.makeIdentityf(inverse);
@@ -310,7 +284,7 @@ public class ProjectFloat {
//
swap = i;
for (j = i + 1; j < 4; j++) {
- if (Math.abs(temp.get(j*4+i)) > Math.abs(temp.get(i*4+i))) {
+ if (Math.abs(temp[j][i]) > Math.abs(temp[i][i])) {
swap = j;
}
}
@@ -320,17 +294,17 @@ public class ProjectFloat {
// Swap rows.
//
for (k = 0; k < 4; k++) {
- t = temp.get(i*4+k);
- temp.put(i*4+k, temp.get(swap*4+k));
- temp.put(swap*4+k, t);
-
+ t = temp[i][k];
+ temp[i][k] = temp[swap][k];
+ temp[swap][k] = t;
+
t = inverse.get(i*4+k + invPos);
inverse.put(i*4+k + invPos, inverse.get(swap*4+k + invPos));
inverse.put(swap*4+k + invPos, t);
}
}
- if (temp.get(i*4+i) == 0) {
+ if (temp[i][i] == 0) {
//
// No non-zero pivot. The matrix is singular, which shouldn't
// happen. This means the user gave us a bad matrix.
@@ -338,17 +312,19 @@ public class ProjectFloat {
return false;
}
- t = temp.get(i*4+i);
+ t = temp[i][i];
for (k = 0; k < 4; k++) {
- temp.put(i*4+k, temp.get(i*4+k) / t);
- inverse.put(i*4+k + invPos, inverse.get(i*4+k + invPos) / t);
+ temp[i][k] /= t;
+ final int z = i*4+k + invPos;
+ inverse.put(z, inverse.get(z) / t);
}
for (j = 0; j < 4; j++) {
if (j != i) {
- t = temp.get(j*4+i);
+ t = temp[j][i];
for (k = 0; k < 4; k++) {
- temp.put(j*4+k, temp.get(j*4+k) - temp.get(i*4+k) * t);
- inverse.put(j*4+k + invPos, inverse.get(j*4+k + invPos) - inverse.get(i*4+k + invPos) * t);
+ temp[j][k] -= temp[i][k] * t;
+ final int z = j*4+k + invPos;
+ inverse.put(z, inverse.get(z) - inverse.get(i*4+k + invPos) * t);
}
}
}
@@ -378,8 +354,8 @@ public class ProjectFloat {
* @param zFar
*/
public void gluPerspective(GLMatrixFunc gl, float fovy, float aspect, float zNear, float zFar) {
+ final float radians = fovy / 2 * (float) Math.PI / 180;
float sine, cotangent, deltaZ;
- float radians = fovy / 2 * (float) Math.PI / 180;
deltaZ = zFar - zNear;
sine = (float) Math.sin(radians);
@@ -391,13 +367,13 @@ public class ProjectFloat {
cotangent = (float) Math.cos(radians) / sine;
FloatUtil.makeIdentityf(matrixBuf);
-
- matrixBuf.put(0 * 4 + 0, cotangent / aspect);
- matrixBuf.put(1 * 4 + 1, cotangent);
- matrixBuf.put(2 * 4 + 2, - (zFar + zNear) / deltaZ);
- matrixBuf.put(2 * 4 + 3, -1);
- matrixBuf.put(3 * 4 + 2, -2 * zNear * zFar / deltaZ);
- matrixBuf.put(3 * 4 + 3, 0);
+ final int mPos = matrixBuf.position();
+ matrixBuf.put(0 * 4 + 0 + mPos, cotangent / aspect);
+ matrixBuf.put(1 * 4 + 1 + mPos, cotangent);
+ matrixBuf.put(2 * 4 + 2 + mPos, - (zFar + zNear) / deltaZ);
+ matrixBuf.put(2 * 4 + 3 + mPos, -1);
+ matrixBuf.put(3 * 4 + 2 + mPos, -2 * zNear * zFar / deltaZ);
+ matrixBuf.put(3 * 4 + 3 + mPos, 0);
gl.glMultMatrixf(matrixBuf);
}
@@ -419,17 +395,17 @@ public class ProjectFloat {
float eyex, float eyey, float eyez,
float centerx, float centery, float centerz,
float upx, float upy, float upz) {
- FloatBuffer forward = this.forwardBuf;
- FloatBuffer side = this.sideBuf;
- FloatBuffer up = this.upBuf;
+ final float[] forward = this.forward;
+ final float[] side = this.side;
+ final float[] up = this.up;
- forward.put(0, centerx - eyex);
- forward.put(1, centery - eyey);
- forward.put(2, centerz - eyez);
+ forward[0] = centerx - eyex;
+ forward[1] = centery - eyey;
+ forward[2] = centerz - eyez;
- up.put(0, upx);
- up.put(1, upy);
- up.put(2, upz);
+ up[0] = upx;
+ up[1] = upy;
+ up[2] = upz;
FloatUtil.normalize(forward);
@@ -441,24 +417,25 @@ public class ProjectFloat {
FloatUtil.cross(side, forward, up);
FloatUtil.makeIdentityf(matrixBuf);
- matrixBuf.put(0 * 4 + 0, side.get(0));
- matrixBuf.put(1 * 4 + 0, side.get(1));
- matrixBuf.put(2 * 4 + 0, side.get(2));
+ final int mPos = matrixBuf.position();
+ matrixBuf.put(0 * 4 + 0 + mPos, side[0]);
+ matrixBuf.put(1 * 4 + 0 + mPos, side[1]);
+ matrixBuf.put(2 * 4 + 0 + mPos, side[2]);
- matrixBuf.put(0 * 4 + 1, up.get(0));
- matrixBuf.put(1 * 4 + 1, up.get(1));
- matrixBuf.put(2 * 4 + 1, up.get(2));
+ matrixBuf.put(0 * 4 + 1 + mPos, up[0]);
+ matrixBuf.put(1 * 4 + 1 + mPos, up[1]);
+ matrixBuf.put(2 * 4 + 1 + mPos, up[2]);
- matrixBuf.put(0 * 4 + 2, -forward.get(0));
- matrixBuf.put(1 * 4 + 2, -forward.get(1));
- matrixBuf.put(2 * 4 + 2, -forward.get(2));
+ matrixBuf.put(0 * 4 + 2 + mPos, -forward[0]);
+ matrixBuf.put(1 * 4 + 2 + mPos, -forward[1]);
+ matrixBuf.put(2 * 4 + 2 + mPos, -forward[2]);
gl.glMultMatrixf(matrixBuf);
gl.glTranslatef(-eyex, -eyey, -eyez);
}
/**
- * Method gluProject
+ * Map object coordinates to window coordinates.
*
* @param objx
* @param objy
@@ -476,16 +453,16 @@ public class ProjectFloat {
int[] viewport, int viewport_offset,
float[] win_pos, int win_pos_offset ) {
- float[] in = this.in;
- float[] out = this.out;
+ final float[] in = this.in;
+ final float[] out = this.out;
in[0] = objx;
in[1] = objy;
in[2] = objz;
in[3] = 1.0f;
- FloatUtil.multMatrixVecf(modelMatrix, modelMatrix_offset, in, 0, out);
- FloatUtil.multMatrixVecf(projMatrix, projMatrix_offset, out, 0, in);
+ FloatUtil.multMatrixVecf(modelMatrix, modelMatrix_offset, in, 0, out, 0);
+ FloatUtil.multMatrixVecf(projMatrix, projMatrix_offset, out, 0, in, 0);
if (in[3] == 0.0f) {
return false;
@@ -506,44 +483,47 @@ public class ProjectFloat {
return true;
}
+ /**
+ * Map object coordinates to window coordinates.
+ */
public boolean gluProject(float objx, float objy, float objz,
FloatBuffer modelMatrix,
FloatBuffer projMatrix,
int[] viewport, int viewport_offset,
float[] win_pos, int win_pos_offset ) {
- FloatBuffer in = this.inBuf;
- FloatBuffer out = this.outBuf;
+ final float[] in = this.in;
+ final float[] out = this.out;
- in.put(0, objx);
- in.put(1, objy);
- in.put(2, objz);
- in.put(3, 1.0f);
+ in[0] = objx;
+ in[1] = objy;
+ in[2] = objz;
+ in[3] = 1.0f;
FloatUtil.multMatrixVecf(modelMatrix, in, out);
FloatUtil.multMatrixVecf(projMatrix, out, in);
- if (in.get(3) == 0.0f) {
+ if (in[3] == 0.0f) {
return false;
}
- in.put(3, (1.0f / in.get(3)) * 0.5f);
+ in[3] = (1.0f / in[3]) * 0.5f;
// Map x, y and z to range 0-1
- in.put(0, in.get(0) * in.get(3) + 0.5f);
- in.put(1, in.get(1) * in.get(3) + 0.5f);
- in.put(2, in.get(2) * in.get(3) + 0.5f);
+ in[0] = in[0] * in[3] + 0.5f;
+ in[1] = in[1] * in[3] + 0.5f;
+ in[2] = in[2] * in[3] + 0.5f;
// Map x,y to viewport
- win_pos[0+win_pos_offset] = in.get(0) * viewport[2+viewport_offset] + viewport[0+viewport_offset];
- win_pos[1+win_pos_offset] = in.get(1) * viewport[3+viewport_offset] + viewport[1+viewport_offset];
- win_pos[2+win_pos_offset] = in.get(2);
-
+ win_pos[0+win_pos_offset] = in[0] * viewport[2+viewport_offset] + viewport[0+viewport_offset];
+ win_pos[1+win_pos_offset] = in[1] * viewport[3+viewport_offset] + viewport[1+viewport_offset];
+ win_pos[2+win_pos_offset] = in[2];
+
return true;
}
/**
- * Method gluProject
+ * Map object coordinates to window coordinates.
*
* @param objx
* @param objy
@@ -561,41 +541,41 @@ public class ProjectFloat {
IntBuffer viewport,
FloatBuffer win_pos) {
- FloatBuffer in = this.inBuf;
- FloatBuffer out = this.outBuf;
+ final float[] in = this.in;
+ final float[] out = this.out;
- in.put(0, objx);
- in.put(1, objy);
- in.put(2, objz);
- in.put(3, 1.0f);
+ in[0] = objx;
+ in[1] = objy;
+ in[2] = objz;
+ in[3] = 1.0f;
FloatUtil.multMatrixVecf(modelMatrix, in, out);
FloatUtil.multMatrixVecf(projMatrix, out, in);
- if (in.get(3) == 0.0f) {
+ if (in[3] == 0.0f) {
return false;
}
- in.put(3, (1.0f / in.get(3)) * 0.5f);
+ in[3] = (1.0f / in[3]) * 0.5f;
// Map x, y and z to range 0-1
- in.put(0, in.get(0) * in.get(3) + 0.5f);
- in.put(1, in.get(1) * in.get(3) + 0.5f);
- in.put(2, in.get(2) * in.get(3) + 0.5f);
+ in[0] = in[0] * in[3] + 0.5f;
+ in[1] = in[1] * in[3] + 0.5f;
+ in[2] = in[2] * in[3] + 0.5f;
// Map x,y to viewport
- int vPos = viewport.position();
- int wPos = win_pos.position();
- win_pos.put(0+wPos, in.get(0) * viewport.get(2+vPos) + viewport.get(0+vPos));
- win_pos.put(1+wPos, in.get(1) * viewport.get(3+vPos) + viewport.get(1+vPos));
- win_pos.put(2+wPos, in.get(2));
+ final int vPos = viewport.position();
+ final int wPos = win_pos.position();
+ win_pos.put(0+wPos, in[0] * viewport.get(2+vPos) + viewport.get(0+vPos));
+ win_pos.put(1+wPos, in[1] * viewport.get(3+vPos) + viewport.get(1+vPos));
+ win_pos.put(2+wPos, in[2]);
return true;
}
/**
- * Method gluUnproject
+ * Map window coordinates to object coordinates.
*
* @param winx
* @param winy
@@ -612,8 +592,8 @@ public class ProjectFloat {
float[] projMatrix, int projMatrix_offset,
int[] viewport, int viewport_offset,
float[] obj_pos, int obj_pos_offset) {
- float[] in = this.in;
- float[] out = this.out;
+ final float[] in = this.in;
+ final float[] out = this.out;
FloatUtil.multMatrixf(projMatrix, projMatrix_offset, modelMatrix, modelMatrix_offset, matrix, 0);
@@ -651,13 +631,27 @@ public class ProjectFloat {
}
+ /**
+ * Map window coordinates to object coordinates.
+ *
+ * @param winx
+ * @param winy
+ * @param winz
+ * @param modelMatrix
+ * @param projMatrix
+ * @param viewport
+ * @param viewport_offset
+ * @param obj_pos
+ * @param obj_pos_offset
+ * @return
+ */
public boolean gluUnProject(float winx, float winy, float winz,
FloatBuffer modelMatrix,
FloatBuffer projMatrix,
int[] viewport, int viewport_offset,
float[] obj_pos, int obj_pos_offset) {
- FloatBuffer in = this.inBuf;
- FloatBuffer out = this.outBuf;
+ final float[] in = this.in;
+ final float[] out = this.out;
FloatUtil.multMatrixf(projMatrix, modelMatrix, matrixBuf);
@@ -665,37 +659,37 @@ public class ProjectFloat {
return false;
}
- in.put(0, winx);
- in.put(1, winy);
- in.put(2, winz);
- in.put(3, 1.0f);
+ in[0] = winx;
+ in[1] = winy;
+ in[2] = winz;
+ in[3] = 1.0f;
// Map x and y from window coordinates
- in.put(0, (in.get(0) - viewport[0+viewport_offset]) / viewport[2+viewport_offset]);
- in.put(1, (in.get(1) - viewport[1+viewport_offset]) / viewport[3+viewport_offset]);
-
+ in[0] = (in[0] - viewport[0+viewport_offset]) / viewport[2+viewport_offset];
+ in[1] = (in[1] - viewport[1+viewport_offset]) / viewport[3+viewport_offset];
+
// Map to range -1 to 1
- in.put(0, in.get(0) * 2 - 1);
- in.put(1, in.get(1) * 2 - 1);
- in.put(2, in.get(2) * 2 - 1);
+ in[0] = in[0] * 2 - 1;
+ in[1] = in[1] * 2 - 1;
+ in[2] = in[2] * 2 - 1;
FloatUtil.multMatrixVecf(matrixBuf, in, out);
-
- if (out.get(3) == 0.0f) {
+
+ if (out[3] == 0.0) {
return false;
}
- out.put(3, 1.0f / out.get(3));
+ out[3] = 1.0f / out[3];
- obj_pos[0+obj_pos_offset] = out.get(0) * out.get(3);
- obj_pos[1+obj_pos_offset] = out.get(1) * out.get(3);
- obj_pos[2+obj_pos_offset] = out.get(2) * out.get(3);
+ obj_pos[0+obj_pos_offset] = out[0] * out[3];
+ obj_pos[1+obj_pos_offset] = out[1] * out[3];
+ obj_pos[2+obj_pos_offset] = out[2] * out[3];
return true;
}
/**
- * Method gluUnproject
+ * Map window coordinates to object coordinates.
*
* @param winx
* @param winy
@@ -712,8 +706,8 @@ public class ProjectFloat {
FloatBuffer projMatrix,
IntBuffer viewport,
FloatBuffer obj_pos) {
- FloatBuffer in = this.inBuf;
- FloatBuffer out = this.outBuf;
+ final float[] in = this.in;
+ final float[] out = this.out;
FloatUtil.multMatrixf(projMatrix, modelMatrix, matrixBuf);
@@ -721,40 +715,40 @@ public class ProjectFloat {
return false;
}
- in.put(0, winx);
- in.put(1, winy);
- in.put(2, winz);
- in.put(3, 1.0f);
+ in[0] = winx;
+ in[1] = winy;
+ in[2] = winz;
+ in[3] = 1.0f;
// Map x and y from window coordinates
- int vPos = viewport.position();
- int oPos = obj_pos.position();
- in.put(0, (in.get(0) - viewport.get(0+vPos)) / viewport.get(2+vPos));
- in.put(1, (in.get(1) - viewport.get(1+vPos)) / viewport.get(3+vPos));
+ final int vPos = viewport.position();
+ final int oPos = obj_pos.position();
+ in[0] = (in[0] - viewport.get(0+vPos)) / viewport.get(2+vPos);
+ in[1] = (in[1] - viewport.get(1+vPos)) / viewport.get(3+vPos);
// Map to range -1 to 1
- in.put(0, in.get(0) * 2 - 1);
- in.put(1, in.get(1) * 2 - 1);
- in.put(2, in.get(2) * 2 - 1);
+ in[0] = in[0] * 2 - 1;
+ in[1] = in[1] * 2 - 1;
+ in[2] = in[2] * 2 - 1;
FloatUtil.multMatrixVecf(matrixBuf, in, out);
- if (out.get(3) == 0.0f) {
+ if (out[3] == 0.0) {
return false;
}
- out.put(3, 1.0f / out.get(3));
+ out[3] = 1.0f / out[3];
- obj_pos.put(0+oPos, out.get(0) * out.get(3));
- obj_pos.put(1+oPos, out.get(1) * out.get(3));
- obj_pos.put(2+oPos, out.get(2) * out.get(3));
+ obj_pos.put(0+oPos, out[0] * out[3]);
+ obj_pos.put(1+oPos, out[1] * out[3]);
+ obj_pos.put(2+oPos, out[2] * out[3]);
return true;
}
/**
- * Method gluUnproject4
+ * Map window coordinates to object coordinates.
*
* @param winx
* @param winy
@@ -783,8 +777,8 @@ public class ProjectFloat {
float far,
float[] obj_pos,
int obj_pos_offset ) {
- float[] in = this.in;
- float[] out = this.out;
+ final float[] in = this.in;
+ final float[] out = this.out;
FloatUtil.multMatrixf(projMatrix, projMatrix_offset, modelMatrix, modelMatrix_offset, matrix, 0);
@@ -808,8 +802,9 @@ public class ProjectFloat {
FloatUtil.multMatrixVecf(matrix, in, out);
- if (out[3] == 0.0f)
+ if (out[3] == 0.0f) {
return false;
+ }
obj_pos[0+obj_pos_offset] = out[0];
obj_pos[1+obj_pos_offset] = out[1];
@@ -819,7 +814,7 @@ public class ProjectFloat {
}
/**
- * Method gluUnproject4
+ * Map window coordinates to object coordinates.
*
* @param winx
* @param winy
@@ -844,40 +839,41 @@ public class ProjectFloat {
float near,
float far,
FloatBuffer obj_pos) {
- FloatBuffer in = this.inBuf;
- FloatBuffer out = this.outBuf;
+ final float[] in = this.in;
+ final float[] out = this.out;
FloatUtil.multMatrixf(projMatrix, modelMatrix, matrixBuf);
if (!gluInvertMatrixf(matrixBuf, matrixBuf))
return false;
- in.put(0, winx);
- in.put(1, winy);
- in.put(2, winz);
- in.put(3, clipw);
+ in[0] = winx;
+ in[1] = winy;
+ in[2] = winz;
+ in[3] = clipw;
// Map x and y from window coordinates
- int vPos = viewport.position();
- in.put(0, (in.get(0) - viewport.get(0+vPos)) / viewport.get(2+vPos));
- in.put(1, (in.get(1) - viewport.get(1+vPos)) / viewport.get(3+vPos));
- in.put(2, (in.get(2) - near) / (far - near));
-
+ final int vPos = viewport.position();
+ in[0] = (in[0] - viewport.get(0+vPos)) / viewport.get(2+vPos);
+ in[1] = (in[1] - viewport.get(1+vPos)) / viewport.get(3+vPos);
+ in[2] = (in[2] - near) / (far - near);
+
// Map to range -1 to 1
- in.put(0, in.get(0) * 2 - 1);
- in.put(1, in.get(1) * 2 - 1);
- in.put(2, in.get(2) * 2 - 1);
+ in[0] = in[0] * 2 - 1;
+ in[1] = in[1] * 2 - 1;
+ in[2] = in[2] * 2 - 1;
FloatUtil.multMatrixVecf(matrixBuf, in, out);
- if (out.get(3) == 0.0f)
+ if (out[3] == 0.0f) {
return false;
+ }
- int oPos = obj_pos.position();
- obj_pos.put(0+oPos, out.get(0));
- obj_pos.put(1+oPos, out.get(1));
- obj_pos.put(2+oPos, out.get(2));
- obj_pos.put(3+oPos, out.get(3));
+ final int oPos = obj_pos.position();
+ obj_pos.put(0+oPos, out[0]);
+ obj_pos.put(1+oPos, out[1]);
+ obj_pos.put(2+oPos, out[2]);
+ obj_pos.put(3+oPos, out[3]);
return true;
}
@@ -902,7 +898,7 @@ public class ProjectFloat {
}
/* Translate and scale the picked region to the entire window */
- int vPos = viewport.position();
+ final int vPos = viewport.position();
gl.glTranslatef((viewport.get(2+vPos) - 2 * (x - viewport.get(0+vPos))) / deltaX,
(viewport.get(3+vPos) - 2 * (y - viewport.get(1+vPos))) / deltaY,
0);
diff --git a/src/jogl/classes/jogamp/opengl/ThreadingImpl.java b/src/jogl/classes/jogamp/opengl/ThreadingImpl.java
index 61a4767..d55a2c9 100644
--- a/src/jogl/classes/jogamp/opengl/ThreadingImpl.java
+++ b/src/jogl/classes/jogamp/opengl/ThreadingImpl.java
@@ -89,8 +89,7 @@ public class ThreadingImpl {
// problems.
hasAWT = GLProfile.isAWTAvailable();
- String osType = NativeWindowFactory.getNativeWindowType(false);
- _isX11 = NativeWindowFactory.TYPE_X11.equals(osType);
+ _isX11 = NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(false);
// default setting
singleThreaded = true;
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
index c5d0df6..84aeaa9 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
@@ -42,6 +42,7 @@ import java.util.Map;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
@@ -50,9 +51,10 @@ import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLDrawableImpl;
import com.jogamp.common.nio.Buffers;
-import com.jogamp.common.os.Platform;
import com.jogamp.gluegen.runtime.ProcAddressTable;
import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver;
+import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
+import com.jogamp.opengl.GLRendererQuirks;
public abstract class EGLContext extends GLContextImpl {
private boolean eglQueryStringInitialized;
@@ -209,8 +211,8 @@ public abstract class EGLContext extends GLContextImpl {
",\n\tsharing with 0x" + Long.toHexString(shareWithHandle));
}
if (!EGL.eglMakeCurrent(eglDisplay, drawable.getHandle(), drawableRead.getHandle(), contextHandle)) {
- throw new GLException("Error making context 0x" +
- Long.toHexString(contextHandle) + " current: error code " + EGL.eglGetError());
+ throw new GLException("Error making context " +
+ toHexString(contextHandle) + " current: error code " + toHexString(EGL.eglGetError()));
}
setGLFunctionAvailability(true, glProfile.usesNativeGLES2() ? 2 : 1, 0, CTX_PROFILE_ES);
return true;
@@ -268,56 +270,51 @@ public abstract class EGLContext extends GLContextImpl {
@Override
protected boolean setSwapIntervalImpl(int interval) {
- // FIXME !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- // eglSwapInterval(..) issued:
- // Android 4.0.3 / Pandaboard ES / PowerVR SGX 540: crashes
- // FIXME !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- if( Platform.OSType.ANDROID == Platform.getOSType() && getGLRendererString(true).contains("powervr") ) {
- if(DEBUG) {
- System.err.println("Ignored: eglSwapInterval("+interval+") - cause: OS "+Platform.getOSType() + " / Renderer " + getGLRendererString(false));
- }
+ if( hasRendererQuirk(GLRendererQuirks.NoSetSwapInterval) ) {
return false;
}
return EGL.eglSwapInterval(drawable.getNativeSurface().getDisplayHandle(), interval);
}
- @Override
- public abstract void bindPbufferToTexture();
-
- @Override
- public abstract void releasePbufferFromTexture();
-
//
// Accessible ..
//
- /**
- * If context is an ES profile, map it to the given device
- * via {@link GLContext#mapAvailableGLVersion(AbstractGraphicsDevice, int, int, int, int, int)}.
- * <p>
- * We intentionally override a non native EGL device ES profile mapping,
- * i.e. this will override/modify an already 'set' X11/WGL/.. mapping.
- * </p>
- *
- * @param device
- */
- protected void mapCurrentAvailableGLVersion(AbstractGraphicsDevice device) {
- mapCurrentAvailableGLVersionImpl(device, ctxMajorVersion, ctxMinorVersion, ctxOptions);
+ /* pp */ void mapCurrentAvailableGLVersion(AbstractGraphicsDevice device) {
+ mapStaticGLVersion(device, ctxMajorVersion, ctxMinorVersion, ctxOptions);
}
-
- protected static void mapStaticGLESVersion(AbstractGraphicsDevice device, int major) {
+ /* pp */ int getContextOptions() { return ctxOptions; }
+ /* pp */ static void mapStaticGLESVersion(AbstractGraphicsDevice device, GLCapabilitiesImmutable caps) {
+ final GLProfile glp = caps.getGLProfile();
+ final int[] reqMajorCTP = new int[2];
+ GLContext.getRequestMajorAndCompat(glp, reqMajorCTP);
+ if(glp.isGLES() && reqMajorCTP[0] >= 2) {
+ reqMajorCTP[1] |= GLContext.CTX_IMPL_ES2_COMPAT | GLContext.CTX_IMPL_FBO ;
+ }
+ if(!caps.getHardwareAccelerated()) {
+ reqMajorCTP[1] |= GLContext.CTX_IMPL_ACCEL_SOFT;
+ }
+ mapStaticGLVersion(device, reqMajorCTP[0], 0, reqMajorCTP[1]);
+ }
+ /* pp */ static void mapStaticGLESVersion(AbstractGraphicsDevice device, int major) {
int ctp = ( 2 == major ) ? ( GLContext.CTX_PROFILE_ES | GLContext.CTX_IMPL_ES2_COMPAT | GLContext.CTX_IMPL_FBO ) : ( GLContext.CTX_PROFILE_ES );
- mapCurrentAvailableGLVersionImpl(device, major, 0, ctp);
+ mapStaticGLVersion(device, major, 0, ctp);
}
- private static void mapCurrentAvailableGLVersionImpl(AbstractGraphicsDevice device, int major, int minor, int ctp) {
+ /* pp */ static void mapStaticGLVersion(AbstractGraphicsDevice device, int major, int minor, int ctp) {
if( 0 != ( ctp & GLContext.CTX_PROFILE_ES) ) {
// ES1 or ES2
final int reqMajor = major;
final int reqProfile = GLContext.CTX_PROFILE_ES;
- GLContext.mapAvailableGLVersion(device, reqMajor, reqProfile,
- major, minor, ctp);
+ GLContext.mapAvailableGLVersion(device, reqMajor, reqProfile, major, minor, ctp);
+ if(! ( device instanceof EGLGraphicsDevice ) ) {
+ final EGLGraphicsDevice eglDevice = new EGLGraphicsDevice(device.getHandle(), EGL.EGL_NO_DISPLAY, device.getConnection(), device.getUnitID(), null);
+ GLContext.mapAvailableGLVersion(eglDevice, reqMajor, reqProfile, major, minor, ctp);
+ }
}
}
+ protected static String getGLVersion(int major, int minor, int ctp, String gl_version) {
+ return GLContext.getGLVersion(major, minor, ctp, gl_version);
+ }
protected static boolean getAvailableGLVersionsSet(AbstractGraphicsDevice device) {
return GLContext.getAvailableGLVersionsSet(device);
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java b/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java
index 432010f..1f6f49f 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java
@@ -29,6 +29,7 @@
package jogamp.opengl.egl;
import java.nio.IntBuffer;
+import java.util.Iterator;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeSurface;
@@ -51,7 +52,7 @@ import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
* </p>
*/
public class EGLDisplayUtil {
- protected static final boolean DEBUG = Debug.debug("EGL");
+ protected static final boolean DEBUG = Debug.debug("EGLDisplayUtil");
static LongIntHashMap eglDisplayCounter;
@@ -60,6 +61,31 @@ public class EGLDisplayUtil {
eglDisplayCounter.setKeyNotFoundValue(0);
}
+ /**
+ * @return number of unclosed EGL Displays.<br>
+ */
+ public static int shutdown(boolean verbose) {
+ if(DEBUG || verbose || eglDisplayCounter.size() > 0 ) {
+ System.err.println("EGLDisplayUtil.EGLDisplays: Shutdown (open: "+eglDisplayCounter.size()+")");
+ if(DEBUG) {
+ Thread.dumpStack();
+ }
+ if( eglDisplayCounter.size() > 0) {
+ dumpOpenDisplayConnections();
+ }
+ }
+ return eglDisplayCounter.size();
+ }
+
+ public static void dumpOpenDisplayConnections() {
+ System.err.println("EGLDisplayUtil: Open EGL Display Connections: "+eglDisplayCounter.size());
+ int i=0;
+ for(Iterator<LongIntHashMap.Entry> iter = eglDisplayCounter.iterator(); iter.hasNext(); i++) {
+ final LongIntHashMap.Entry e = iter.next();
+ System.err.println("EGLDisplayUtil: Open["+i+"]: 0x"+Long.toHexString(e.key)+": refCnt "+e.value);
+ }
+ }
+
public static long eglGetDisplay(long nativeDisplay_id) {
final long eglDisplay = EGL.eglGetDisplay(nativeDisplay_id);
if(DEBUG) {
@@ -70,29 +96,13 @@ public class EGLDisplayUtil {
return eglDisplay;
}
- public static synchronized boolean eglInitialize(long eglDisplay, int[] major, int major_offset, int[] minor, int minor_offset) {
- final boolean res;
- final int refCnt = eglDisplayCounter.get(eglDisplay) + 1; // 0 + 1 = 1 -> 1st init
- if(1==refCnt) {
- res = EGL.eglInitialize(eglDisplay, major, major_offset, minor, minor_offset);
- } else {
- res = true;
- }
- eglDisplayCounter.put(eglDisplay, refCnt);
- if(DEBUG) {
- System.err.println("EGL.eglInitialize(0x"+Long.toHexString(eglDisplay)+" ...): #"+refCnt+" = "+res);
- }
- return res;
- }
-
/**
- *
* @param eglDisplay
* @param major
* @param minor
- * @return true if the eglDisplay is valid and it's reference counter becomes one and {@link EGL#eglTerminate(long)} was successful, otherwise false
+ * @return true if the eglDisplay is valid and it's reference counter becomes one and {@link EGL#eglInitialize(long, IntBuffer, IntBuffer)} was successful, otherwise false
*
- * @see EGL#eglInitialize(long, int[], int, int[], int)}
+ * @see EGL#eglInitialize(long, IntBuffer, IntBuffer)
*/
public static synchronized boolean eglInitialize(long eglDisplay, IntBuffer major, IntBuffer minor) {
if( EGL.EGL_NO_DISPLAY == eglDisplay) {
@@ -104,15 +114,70 @@ public class EGLDisplayUtil {
res = EGL.eglInitialize(eglDisplay, major, minor);
} else {
res = true;
+ }
+ if(res) { // map if successfully initialized, only
+ eglDisplayCounter.put(eglDisplay, refCnt);
}
- eglDisplayCounter.put(eglDisplay, refCnt);
if(DEBUG) {
- System.err.println("EGL.eglInitialize(0x"+Long.toHexString(eglDisplay)+" ...): #"+refCnt+" = "+res);
+ System.err.println("EGLDisplayUtil.eglInitialize2("+EGLContext.toHexString(eglDisplay)+" ...): #"+refCnt+" = "+res);
+ // Thread.dumpStack();
}
return res;
}
/**
+ * @param nativeDisplayID
+ * @param eglDisplay array of size 1 holding return value if successful, otherwise {@link EGL#EGL_NO_DISPLAY}.
+ * @param eglErr array of size 1 holding the EGL error value as retrieved by {@link EGL#eglGetError()} if not successful.
+ * @param major
+ * @param minor
+ * @return {@link EGL#EGL_SUCCESS} if successful, otherwise {@link EGL#EGL_BAD_DISPLAY} if {@link #eglGetDisplay(long)} failed
+ * or {@link EGL#EGL_NOT_INITIALIZED} if {@link #eglInitialize(long, IntBuffer, IntBuffer)} failed.
+ *
+ * @see #eglGetDisplay(long)
+ * @see #eglInitialize(long, IntBuffer, IntBuffer)
+ */
+ public static synchronized int eglGetDisplayAndInitialize(long nativeDisplayID, long[] eglDisplay, int[] eglErr, IntBuffer major, IntBuffer minor) {
+ eglDisplay[0] = EGL.EGL_NO_DISPLAY;
+ final long _eglDisplay = EGLDisplayUtil.eglGetDisplay( nativeDisplayID );
+ if ( EGL.EGL_NO_DISPLAY == _eglDisplay ) {
+ eglErr[0] = EGL.eglGetError();
+ return EGL.EGL_BAD_DISPLAY;
+ }
+ if ( !EGLDisplayUtil.eglInitialize( _eglDisplay, major, minor) ) {
+ eglErr[0] = EGL.eglGetError();
+ return EGL.EGL_NOT_INITIALIZED;
+ }
+ eglDisplay[0] = _eglDisplay;
+ return EGL.EGL_SUCCESS;
+ }
+
+ /**
+ * @param nativeDisplayID in/out array of size 1, passing the requested nativeVisualID, may return a different revised nativeVisualID handle
+ * @return the initialized EGL display ID
+ * @throws GLException if not successful
+ */
+ public static synchronized long eglGetDisplayAndInitialize(long[] nativeDisplayID) {
+ final long[] eglDisplay = new long[1];
+ final int[] eglError = new int[1];
+ int eglRes = EGLDisplayUtil.eglGetDisplayAndInitialize(nativeDisplayID[0], eglDisplay, eglError, null, null);
+ if( EGL.EGL_SUCCESS == eglRes ) {
+ return eglDisplay[0];
+ }
+ if( EGL.EGL_DEFAULT_DISPLAY != nativeDisplayID[0] ) { // fallback to DEGAULT_DISPLAY
+ if(DEBUG) {
+ System.err.println("EGLDisplayUtil.eglGetAndInitDisplay failed with native "+EGLContext.toHexString(nativeDisplayID[0])+", error "+EGLContext.toHexString(eglRes)+"/"+EGLContext.toHexString(eglError[0])+" - fallback!");
+ }
+ eglRes = EGLDisplayUtil.eglGetDisplayAndInitialize(EGL.EGL_DEFAULT_DISPLAY, eglDisplay, eglError, null, null);
+ if( EGL.EGL_SUCCESS == eglRes ) {
+ nativeDisplayID[0] = EGL.EGL_DEFAULT_DISPLAY;
+ return eglDisplay[0];
+ }
+ }
+ throw new GLException("Failed to created/initialize EGL display incl. fallback default: native "+EGLContext.toHexString(nativeDisplayID[0])+", error "+EGLContext.toHexString(eglRes)+"/"+EGLContext.toHexString(eglError[0]));
+ }
+
+ /**
* @param eglDisplay the EGL display handle
* @return true if the eglDisplay is valid and it's reference counter becomes zero and {@link EGL#eglTerminate(long)} was successful, otherwise false
*/
@@ -124,28 +189,23 @@ public class EGLDisplayUtil {
final int refCnt = eglDisplayCounter.get(eglDisplay) - 1; // 1 - 1 = 0 -> final terminate
if(0==refCnt) { // no terminate if still in use or already terminated
res = EGL.eglTerminate(eglDisplay);
+ eglDisplayCounter.remove(eglDisplay);
} else {
+ if(0 < refCnt) { // no negative refCount
+ eglDisplayCounter.put(eglDisplay, refCnt);
+ }
res = true;
}
- if(0<=refCnt) { // no negative refCount
- eglDisplayCounter.put(eglDisplay, refCnt);
- }
if(DEBUG) {
- System.err.println("EGL.eglTerminate(0x"+Long.toHexString(eglDisplay)+" ...): #"+refCnt+" = "+res);
+ System.err.println("EGLDisplayUtil.eglTerminate("+EGLContext.toHexString(eglDisplay)+" ...): #"+refCnt+" = "+res);
+ // Thread.dumpStack();
}
return res;
}
public static final EGLGraphicsDevice.EGLDisplayLifecycleCallback eglLifecycleCallback = new EGLGraphicsDevice.EGLDisplayLifecycleCallback() {
- public long eglGetAndInitDisplay(long nativeDisplayID) {
- long eglDisplay = EGLDisplayUtil.eglGetDisplay(nativeDisplayID);
- if (eglDisplay == EGL.EGL_NO_DISPLAY) {
- throw new GLException("Failed to created EGL display: 0x"+Long.toHexString(nativeDisplayID)+", error 0x"+Integer.toHexString(EGL.eglGetError()));
- }
- if (!EGLDisplayUtil.eglInitialize(eglDisplay, null, null)) {
- throw new GLException("eglInitialize failed"+", error 0x"+Integer.toHexString(EGL.eglGetError()));
- }
- return eglDisplay;
+ public long eglGetAndInitDisplay(long[] nativeDisplayID) {
+ return eglGetDisplayAndInitialize(nativeDisplayID);
}
public void eglTerminate(long eglDisplayHandle) {
EGLDisplayUtil.eglTerminate(eglDisplayHandle);
@@ -161,39 +221,26 @@ public class EGLDisplayUtil {
* @see EGLGraphicsDevice#EGLGraphicsDevice(long, long, String, int, com.jogamp.nativewindow.egl.EGLGraphicsDevice.EGLDisplayLifecycleCallback)
*/
public static EGLGraphicsDevice eglCreateEGLGraphicsDevice(long nativeDisplayID, String connection, int unitID) {
- final EGLGraphicsDevice eglDisplay = new EGLGraphicsDevice(nativeDisplayID, 0, connection, unitID, eglLifecycleCallback);
+ final EGLGraphicsDevice eglDisplay = new EGLGraphicsDevice(nativeDisplayID, EGL.EGL_NO_DISPLAY, connection, unitID, eglLifecycleCallback);
eglDisplay.open();
return eglDisplay;
}
/**
* @param surface
- * @param allowFallBackToDefault
* @return an initialized EGLGraphicsDevice
- * @throws GLException if {@link EGL#eglGetDisplay(long)} or {@link EGL#eglInitialize(long, int[], int, int[], int)} fails
+ * @throws GLException if {@link EGL#eglGetDisplay(long)} or {@link EGL#eglInitialize(long, int[], int, int[], int)} fails incl fallback
*/
- public static EGLGraphicsDevice eglCreateEGLGraphicsDevice(NativeSurface surface, boolean allowFallBackToDefault) {
- long nativeDisplayID;
- if( NativeWindowFactory.TYPE_WINDOWS.equals(NativeWindowFactory.getNativeWindowType(false)) ) {
+ public static EGLGraphicsDevice eglCreateEGLGraphicsDevice(NativeSurface surface) {
+ final long nativeDisplayID;
+ if( NativeWindowFactory.TYPE_WINDOWS == NativeWindowFactory.getNativeWindowType(false) ) {
nativeDisplayID = surface.getSurfaceHandle(); // don't even ask ..
} else {
nativeDisplayID = surface.getDisplayHandle(); // 0 == EGL.EGL_DEFAULT_DISPLAY
}
- long eglDisplay = EGLDisplayUtil.eglGetDisplay(nativeDisplayID);
- if (eglDisplay == EGL.EGL_NO_DISPLAY && nativeDisplayID != EGL.EGL_DEFAULT_DISPLAY && allowFallBackToDefault) {
- if(DEBUG) {
- System.err.println("EGLDisplayUtil.eglGetDisplay(): Fall back to EGL_DEFAULT_DISPLAY");
- }
- nativeDisplayID = EGL.EGL_DEFAULT_DISPLAY;
- eglDisplay = EGLDisplayUtil.eglGetDisplay(nativeDisplayID);
- }
- if (eglDisplay == EGL.EGL_NO_DISPLAY) {
- throw new GLException("Failed to created EGL display: "+surface+", error 0x"+Integer.toHexString(EGL.eglGetError()));
- }
- if (!EGLDisplayUtil.eglInitialize(eglDisplay, null, null)) {
- throw new GLException("eglInitialize failed"+", error 0x"+Integer.toHexString(EGL.eglGetError()));
- }
final AbstractGraphicsDevice adevice = surface.getGraphicsConfiguration().getScreen().getDevice();
- return new EGLGraphicsDevice(nativeDisplayID, eglDisplay, adevice.getConnection(), adevice.getUnitID(), eglLifecycleCallback);
+ final EGLGraphicsDevice eglDevice = new EGLGraphicsDevice(nativeDisplayID, EGL.EGL_NO_DISPLAY, adevice.getConnection(), adevice.getUnitID(), eglLifecycleCallback);
+ eglDevice.open();
+ return eglDevice;
}
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java
index 383b61f..167eebf 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java
@@ -36,7 +36,8 @@
package jogamp.opengl.egl;
-import javax.media.nativewindow.MutableSurface;
+import java.nio.IntBuffer;
+
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.NativeWindow;
import javax.media.nativewindow.ProxySurface;
@@ -46,10 +47,10 @@ import javax.media.opengl.GLException;
import jogamp.opengl.GLDrawableImpl;
import jogamp.opengl.GLDynamicLookupHelper;
+import com.jogamp.common.nio.Buffers;
import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
public abstract class EGLDrawable extends GLDrawableImpl {
- private boolean ownEGLSurface = false; // for destruction
protected EGLDrawable(EGLDrawableFactory factory, NativeSurface component) throws GLException {
super(factory, component, false);
@@ -58,21 +59,14 @@ public abstract class EGLDrawable extends GLDrawableImpl {
@Override
public abstract GLContext createContext(GLContext shareWith);
- protected abstract long createSurface(EGLGraphicsConfiguration config, long nativeSurfaceHandle);
+ protected abstract long createSurface(EGLGraphicsConfiguration config, int width, int height, long nativeSurfaceHandle);
- private final void recreateSurface() {
- final EGLGraphicsConfiguration eglConfig = (EGLGraphicsConfiguration) surface.getGraphicsConfiguration();
- final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) eglConfig.getScreen().getDevice();
- if(DEBUG) {
- System.err.println(getThreadName() + ": createSurface using "+eglConfig);
- }
- if( EGL.EGL_NO_SURFACE != surface.getSurfaceHandle() ) {
- EGL.eglDestroySurface(eglDevice.getHandle(), surface.getSurfaceHandle());
- }
+ private final long createEGLSurface() {
+ final EGLWrappedSurface eglws = (EGLWrappedSurface) surface;
+ final EGLGraphicsConfiguration eglConfig = (EGLGraphicsConfiguration) eglws.getGraphicsConfiguration();
+ final NativeSurface upstreamSurface = eglws.getUpstreamSurface();
- final EGLUpstreamSurfaceHook upstreamHook = (EGLUpstreamSurfaceHook) ((ProxySurface)surface).getUpstreamSurfaceHook();
- final NativeSurface upstreamSurface = upstreamHook.getUpstreamSurface();
- long eglSurface = createSurface(eglConfig, upstreamSurface.getSurfaceHandle());
+ long eglSurface = createSurface(eglConfig, eglws.getWidth(), eglws.getHeight(), upstreamSurface.getSurfaceHandle());
int eglError0;
if (EGL.EGL_NO_SURFACE == eglSurface) {
@@ -86,7 +80,7 @@ public abstract class EGLDrawable extends GLDrawableImpl {
if(DEBUG) {
System.err.println(getThreadName() + ": Info: Creation of window surface w/ surface handle failed: "+eglConfig+", error "+toHexString(eglError0)+", retry w/ windowHandle");
}
- eglSurface = createSurface(eglConfig, nw.getWindowHandle());
+ eglSurface = createSurface(eglConfig, eglws.getWidth(), eglws.getHeight(), nw.getWindowHandle());
if (EGL.EGL_NO_SURFACE == eglSurface) {
eglError0 = EGL.eglGetError();
}
@@ -99,85 +93,73 @@ public abstract class EGLDrawable extends GLDrawableImpl {
if (EGL.EGL_NO_SURFACE == eglSurface) {
throw new GLException("Creation of window surface failed: "+eglConfig+", "+surface+", error "+toHexString(eglError0));
}
-
if(DEBUG) {
- System.err.println(getThreadName() + ": setSurface using component: handle "+toHexString(surface.getSurfaceHandle())+" -> "+toHexString(eglSurface));
+ System.err.println(getThreadName() + ": createEGLSurface handle "+toHexString(eglSurface));
}
-
- ((MutableSurface)surface).setSurfaceHandle(eglSurface);
+ return eglSurface;
}
@Override
protected final void updateHandle() {
- if(ownEGLSurface) {
- recreateSurface();
+ final EGLWrappedSurface eglws = (EGLWrappedSurface) surface;
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": updateHandle of "+eglws);
+ }
+ if( eglws.containsUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE ) ) {
+ if( EGL.EGL_NO_SURFACE != eglws.getSurfaceHandle() ) {
+ throw new InternalError("Set surface but claimed to be invalid: "+eglws);
+ }
+ eglws.setSurfaceHandle( createEGLSurface() );
+ } else if( EGL.EGL_NO_SURFACE == eglws.getSurfaceHandle() ) {
+ throw new InternalError("Nil surface but claimed to be valid: "+eglws);
+ }
+ }
+
+ protected void destroyHandle() {
+ final EGLWrappedSurface eglws = (EGLWrappedSurface) surface;
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": destroyHandle of "+eglws);
+ }
+ if( EGL.EGL_NO_SURFACE == eglws.getSurfaceHandle() ) {
+ throw new InternalError("Nil surface but claimed to be valid: "+eglws);
+ }
+ final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) eglws.getGraphicsConfiguration().getScreen().getDevice();
+ if( eglws.containsUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE ) ) {
+ EGL.eglDestroySurface(eglDevice.getHandle(), eglws.getSurfaceHandle());
+ eglws.setSurfaceHandle(EGL.EGL_NO_SURFACE);
}
}
- @Override
- protected final void setRealizedImpl() {
- final EGLGraphicsConfiguration eglConfig = (EGLGraphicsConfiguration) surface.getGraphicsConfiguration();
- final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) eglConfig.getScreen().getDevice();
- if (realized) {
- final long eglDisplayHandle = eglDevice.getHandle();
- if (EGL.EGL_NO_DISPLAY == eglDisplayHandle) {
- throw new GLException("Invalid EGL display in EGLGraphicsDevice "+eglDevice);
- }
- int[] tmp = new int[1];
- boolean eglSurfaceValid = 0 != surface.getSurfaceHandle();
- if(eglSurfaceValid) {
- eglSurfaceValid = EGL.eglQuerySurface(eglDisplayHandle, surface.getSurfaceHandle(), EGL.EGL_CONFIG_ID, tmp, 0);
- if(!eglSurfaceValid) {
- if(DEBUG) {
- System.err.println(getThreadName() + ": EGLDrawable.setRealizedImpl eglQuerySuface failed: "+toHexString(EGL.eglGetError())+", "+surface);
- }
- }
- }
- if(eglSurfaceValid) {
- // surface holds valid EGLSurface
- if(DEBUG) {
- System.err.println(getThreadName() + ": EGLDrawable.setRealizedImpl re-using component's EGLSurface: handle "+toHexString(surface.getSurfaceHandle()));
- }
- ownEGLSurface=false;
- } else {
- // EGLSurface is ours - subsequent updateHandle() will issue recreateSurface();
- // However .. let's validate the surface object first
- if( ! (surface instanceof ProxySurface) ) {
- throw new InternalError("surface not ProxySurface: "+surface.getClass().getName()+", "+surface);
- }
- final ProxySurface.UpstreamSurfaceHook upstreamHook = ((ProxySurface)surface).getUpstreamSurfaceHook();
- if( null == upstreamHook ) {
- throw new InternalError("null upstreamHook of: "+surface);
- }
- if( ! (upstreamHook instanceof EGLUpstreamSurfaceHook) ) {
- throw new InternalError("upstreamHook not EGLUpstreamSurfaceHook: Surface: "+surface.getClass().getName()+", "+surface+"; UpstreamHook: "+upstreamHook.getClass().getName()+", "+upstreamHook);
- }
- if( null == ((EGLUpstreamSurfaceHook)upstreamHook).getUpstreamSurface() ) {
- throw new InternalError("null upstream surface");
- }
- ownEGLSurface=true;
- if(DEBUG) {
- System.err.println(getThreadName() + ": EGLDrawable.setRealizedImpl owning EGLSurface");
- }
- }
- } else if (ownEGLSurface && surface.getSurfaceHandle() != EGL.EGL_NO_SURFACE) {
+ protected static boolean isValidEGLSurface(long eglDisplayHandle, long surfaceHandle) {
+ if( 0 == surfaceHandle ) {
+ return false;
+ }
+ final IntBuffer val = Buffers.newDirectIntBuffer(1);
+ final boolean eglSurfaceValid = EGL.eglQuerySurface(eglDisplayHandle, surfaceHandle, EGL.EGL_CONFIG_ID, val);
+ if( !eglSurfaceValid ) {
+ final int eglErr = EGL.eglGetError();
if(DEBUG) {
- System.err.println(getThreadName() + ": EGLDrawable.setRealized(false): ownSurface "+ownEGLSurface+", "+eglDevice+", eglSurface: "+toHexString(surface.getSurfaceHandle()));
- }
- // Destroy the window surface
- if (!EGL.eglDestroySurface(eglDevice.getHandle(), surface.getSurfaceHandle())) {
- throw new GLException("Error destroying window surface (eglDestroySurface)");
+ System.err.println(getThreadName() + ": EGLDrawable.isValidEGLSurface eglQuerySuface failed: error "+toHexString(eglErr)+", "+toHexString(surfaceHandle));
}
- ((MutableSurface)surface).setSurfaceHandle(EGL.EGL_NO_SURFACE);
+ }
+ return eglSurfaceValid;
+ }
+
+ @Override
+ protected final void setRealizedImpl() {
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": EGLDrawable.setRealized("+realized+"): NOP - "+surface);
}
}
@Override
- protected final void swapBuffersImpl() {
- final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) surface.getGraphicsConfiguration().getScreen().getDevice();
- // single-buffer is already filtered out @ GLDrawableImpl#swapBuffers()
- if(!EGL.eglSwapBuffers(eglDevice.getHandle(), surface.getSurfaceHandle())) {
- throw new GLException("Error swapping buffers, eglError "+toHexString(EGL.eglGetError())+", "+this);
+ protected final void swapBuffersImpl(boolean doubleBuffered) {
+ if(doubleBuffered) {
+ final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) surface.getGraphicsConfiguration().getScreen().getDevice();
+ // single-buffer is already filtered out @ GLDrawableImpl#swapBuffers()
+ if(!EGL.eglSwapBuffers(eglDevice.getHandle(), surface.getSurfaceHandle())) {
+ throw new GLException("Error swapping buffers, eglError "+toHexString(EGL.eglGetError())+", "+this);
+ }
}
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
index c848e3e..ad305ab 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
@@ -36,11 +36,14 @@
package jogamp.opengl.egl;
+import java.nio.IntBuffer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
+import java.util.Set;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.AbstractGraphicsDevice;
@@ -50,8 +53,7 @@ import javax.media.nativewindow.MutableSurface;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.ProxySurface;
-import javax.media.nativewindow.ProxySurface.UpstreamSurfaceHook;
-import javax.media.nativewindow.VisualIDHolder.VIDType;
+import javax.media.nativewindow.UpstreamSurfaceHook;
import javax.media.nativewindow.VisualIDHolder;
import javax.media.opengl.GL;
import javax.media.opengl.GLCapabilities;
@@ -62,8 +64,8 @@ import javax.media.opengl.GLDrawable;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
-import javax.media.opengl.GLProfile.ShutdownType;
+import jogamp.nativewindow.WrappedSurface;
import jogamp.opengl.Debug;
import jogamp.opengl.GLDrawableFactoryImpl;
import jogamp.opengl.GLDrawableImpl;
@@ -71,18 +73,20 @@ import jogamp.opengl.GLDynamicLookupHelper;
import jogamp.opengl.GLGraphicsConfigurationUtil;
import com.jogamp.common.JogampRuntimeException;
+import com.jogamp.common.nio.Buffers;
+import com.jogamp.common.nio.PointerBuffer;
import com.jogamp.common.os.Platform;
import com.jogamp.common.util.ReflectionUtil;
-import com.jogamp.nativewindow.WrappedSurface;
import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
+import com.jogamp.opengl.GLRendererQuirks;
public class EGLDrawableFactory extends GLDrawableFactoryImpl {
- /* package */ static final boolean QUERY_EGL_ES = !Debug.isPropertyDefined("jogl.debug.EGLDrawableFactory.DontQuery", true);
+ protected static final boolean DEBUG = GLDrawableFactoryImpl.DEBUG; // allow package access
+
/* package */ static final boolean QUERY_EGL_ES_NATIVE_TK = Debug.isPropertyDefined("jogl.debug.EGLDrawableFactory.QueryNativeTK", true);
private static GLDynamicLookupHelper eglES1DynamicLookupHelper = null;
private static GLDynamicLookupHelper eglES2DynamicLookupHelper = null;
- private static boolean isANGLE = false;
private static final boolean isANGLE(GLDynamicLookupHelper dl) {
if(Platform.OSType.WINDOWS == Platform.OS_TYPE) {
@@ -95,6 +99,12 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
}
}
+ private static final boolean includesES1(GLDynamicLookupHelper dl) {
+ return 0 != dl.dynamicLookupFunction("glLoadIdentity") &&
+ 0 != dl.dynamicLookupFunction("glEnableClientState") &&
+ 0 != dl.dynamicLookupFunction("glColorPointer");
+ }
+
public EGLDrawableFactory() {
super();
@@ -103,42 +113,17 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
EGLGraphicsConfigurationFactory.registerFactory();
// Check for other underlying stuff ..
- if(NativeWindowFactory.TYPE_X11.equals(NativeWindowFactory.getNativeWindowType(true))) {
+ if(NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(true)) {
try {
ReflectionUtil.createInstance("jogamp.opengl.x11.glx.X11GLXGraphicsConfigurationFactory", EGLDrawableFactory.class.getClassLoader());
} catch (JogampRuntimeException jre) { /* n/a .. */ }
}
- defaultDevice = new EGLGraphicsDevice(AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
-
// 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.
synchronized(EGLDrawableFactory.class) {
- /**
- * Currently AMD's EGL impl. crashes at eglGetDisplay(EGL_DEFAULT_DISPLAY)
- *
- // Check Desktop ES2 Availability first (AMD, ..)
- if(null==eglES2DynamicLookupHelper) {
- GLDynamicLookupHelper tmp=null;
- try {
- tmp = new GLDynamicLookupHelper(new DesktopES2DynamicLibraryBundleInfo());
- } catch (GLException gle) {
- if(DEBUG) {
- gle.printStackTrace();
- }
- }
- if(null!=tmp && tmp.isLibComplete()) {
- eglES2DynamicLookupHelper = tmp;
- EGL.resetProcAddressTable(eglES2DynamicLookupHelper);
- if (GLProfile.DEBUG) {
- System.err.println("Info: EGLDrawableFactory: Desktop ES2 - OK");
- }
- } else if (GLProfile.DEBUG) {
- System.err.println("Info: EGLDrawableFactory: Desktop ES2 - NOPE");
- }
- } */
final boolean hasDesktopES2 = null != eglES2DynamicLookupHelper;
if(!hasDesktopES2 && null==eglES1DynamicLookupHelper) {
@@ -155,11 +140,11 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
EGL.resetProcAddressTable(eglES1DynamicLookupHelper);
final boolean isANGLEES1 = isANGLE(eglES1DynamicLookupHelper);
isANGLE |= isANGLEES1;
- if (GLProfile.DEBUG) {
+ if (DEBUG || GLProfile.DEBUG) {
System.err.println("Info: EGLDrawableFactory: EGL ES1 - OK, isANGLE: "+isANGLEES1);
}
- } else if (GLProfile.DEBUG) {
- System.err.println("Info: EGLDrawableFactory: EGL ES1 - NOPE");
+ } else if (DEBUG || GLProfile.DEBUG) {
+ System.err.println("Info: EGLDrawableFactory: EGL ES1 - NOPE (ES1 lib)");
}
}
if(!hasDesktopES2 && null==eglES2DynamicLookupHelper) {
@@ -174,75 +159,150 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
if(null!=tmp && tmp.isLibComplete()) {
eglES2DynamicLookupHelper = tmp;
EGL.resetProcAddressTable(eglES2DynamicLookupHelper);
+ final boolean includesES1 = null == eglES1DynamicLookupHelper && includesES1(eglES2DynamicLookupHelper);
+ if(includesES1) {
+ eglES1DynamicLookupHelper = tmp;
+ }
final boolean isANGLEES2 = isANGLE(eglES2DynamicLookupHelper);
isANGLE |= isANGLEES2;
- if (GLProfile.DEBUG) {
- System.err.println("Info: EGLDrawableFactory: EGL ES2 - OK, isANGLE: "+isANGLEES2);
+ if (DEBUG || GLProfile.DEBUG) {
+ System.err.println("Info: EGLDrawableFactory: EGL ES2 - OK (includesES1 "+includesES1+", isANGLE: "+isANGLEES2+")");
+ if(includesES1) {
+ System.err.println("Info: EGLDrawableFactory: EGL ES1 - OK (ES2 lib)");
+ }
}
- } else if (GLProfile.DEBUG) {
+ } else if (DEBUG || GLProfile.DEBUG) {
System.err.println("Info: EGLDrawableFactory: EGL ES2 - NOPE");
}
}
+ if( null != eglES2DynamicLookupHelper || null != eglES1DynamicLookupHelper ) {
+ if(isANGLE && !enableANGLE) {
+ if(DEBUG || GLProfile.DEBUG) {
+ System.err.println("Info: EGLDrawableFactory.init - EGL/ES2 ANGLE disabled");
+ }
+ } else {
+ if( isANGLE && ( DEBUG || GLProfile.DEBUG ) ) {
+ System.err.println("Info: EGLDrawableFactory.init - EGL/ES2 ANGLE enabled");
+ }
+ sharedMap = new HashMap<String /*uniqueKey*/, SharedResource>();
+ sharedMapCreateAttempt = new HashSet<String>();
+
+ // FIXME: Following triggers eglInitialize(..) which crashed on Windows w/ Chrome/Angle, FF/Angle!
+ defaultDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(EGL.EGL_DEFAULT_DISPLAY, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
+ }
+ }
}
}
@Override
- protected final void destroy(ShutdownType shutdownType) {
+ protected final boolean isComplete() {
+ return null != sharedMap; // null != eglES2DynamicLookupHelper || null != eglES1DynamicLookupHelper;
+ }
+
+
+ @Override
+ protected final void destroy() {
if(null != sharedMap) {
+ if(DEBUG) {
+ System.err.println("EGLDrawableFactory.destroy() .. ");
+ dumpMap();
+ }
Collection<SharedResource> srl = sharedMap.values();
for(Iterator<SharedResource> sri = srl.iterator(); sri.hasNext(); ) {
SharedResource sr = sri.next();
if(DEBUG) {
- System.err.println("EGLDrawableFactory.destroy("+shutdownType+"): "+sr.device.toString());
+ System.err.println("EGLDrawableFactory.destroy(): "+sr.device.toString());
}
sr.device.close();
}
sharedMap.clear();
+ sharedMapCreateAttempt.clear();
sharedMap = null;
+ sharedMapCreateAttempt = null;
+ }
+ if(null != defaultSharedResource) {
+ defaultSharedResource = null;
+ }
+ if(null != defaultDevice) {
+ defaultDevice.close();
+ defaultDevice = null;
}
- defaultDevice = null;
/**
* Pulling away the native library may cause havoc ..
*/
- if(ShutdownType.COMPLETE == shutdownType) {
- if(null != eglES1DynamicLookupHelper) {
- // eglES1DynamicLookupHelper.destroy();
- eglES1DynamicLookupHelper = null;
- }
- if(null != eglES2DynamicLookupHelper) {
- // eglES2DynamicLookupHelper.destroy();
- eglES2DynamicLookupHelper = null;
- }
+ if(null != eglES1DynamicLookupHelper) {
+ // eglES1DynamicLookupHelper.destroy();
+ eglES1DynamicLookupHelper = null;
+ }
+ if(null != eglES2DynamicLookupHelper) {
+ // eglES2DynamicLookupHelper.destroy();
+ eglES2DynamicLookupHelper = null;
}
EGLGraphicsConfigurationFactory.unregisterFactory();
+ EGLDisplayUtil.shutdown(DEBUG);
+ }
+
+ private void dumpMap() {
+ synchronized(sharedMap) {
+ System.err.println("EGLDrawableFactory.map "+sharedMap.size());
+ int i=0;
+ Set<String> keys = sharedMap.keySet();
+ for(Iterator<String> keyI = keys.iterator(); keyI.hasNext(); i++) {
+ String key = keyI.next();
+ SharedResource sr = sharedMap.get(key);
+ System.err.println("EGLDrawableFactory.map["+i+"] "+key+" -> "+sr.getDevice()+", "+
+ "es1 [avail "+sr.wasES1ContextAvailable()+", pbuffer "+sr.hasES1PBuffer()+", quirks "+sr.getGLRendererQuirksES1()+", ctp "+EGLContext.getGLVersion(1, 0, sr.getCtpES1(), null)+"], "+
+ "es2 [avail "+sr.wasES2ContextAvailable()+", pbuffer "+sr.hasES2PBuffer()+", quirks "+sr.getGLRendererQuirksES1()+", ctp "+EGLContext.getGLVersion(2, 0, sr.getCtpES2(), null)+"]");
+ }
+ ;
+ }
}
- private HashMap<String /*connection*/, SharedResource> sharedMap = new HashMap<String /*connection*/, SharedResource>();
- private EGLGraphicsDevice defaultDevice;
+ private HashMap<String /*uniqueKey*/, SharedResource> sharedMap = null;
+ private HashSet<String> sharedMapCreateAttempt = null;
+ private EGLGraphicsDevice defaultDevice = null;
+ private SharedResource defaultSharedResource = null;
+ private boolean isANGLE = false;
static class SharedResource {
private final EGLGraphicsDevice device;
- // private final EGLDrawable drawable;
// private final EGLContext contextES1;
// private final EGLContext contextES2;
+ private final GLRendererQuirks rendererQuirksES1;
+ private final GLRendererQuirks rendererQuirksES2;
+ private final int ctpES1;
+ private final int ctpES2;
private final boolean wasES1ContextCreated;
private final boolean wasES2ContextCreated;
+ private final boolean hasPBufferES1;
+ private final boolean hasPBufferES2;
- SharedResource(EGLGraphicsDevice dev, boolean wasContextES1Created, boolean wasContextES2Created
- /*EGLDrawable draw, EGLContext ctxES1, EGLContext ctxES2 */) {
+ SharedResource(EGLGraphicsDevice dev,
+ boolean wasContextES1Created, boolean hasPBufferES1, GLRendererQuirks rendererQuirksES1, int ctpES1,
+ boolean wasContextES2Created, boolean hasPBufferES2, GLRendererQuirks rendererQuirksES2, int ctpES2) {
this.device = dev;
- // this.drawable = draw;
// this.contextES1 = ctxES1;
// this.contextES2 = ctxES2;
+ this.rendererQuirksES1 = rendererQuirksES1;
+ this.rendererQuirksES2 = rendererQuirksES2;
+ this.ctpES1 = ctpES1;
+ this.ctpES2 = ctpES2;
this.wasES1ContextCreated = wasContextES1Created;
this.wasES2ContextCreated = wasContextES2Created;
+ this.hasPBufferES1= hasPBufferES1;
+ this.hasPBufferES2= hasPBufferES2;
}
final EGLGraphicsDevice getDevice() { return device; }
- // final EGLDrawable getDrawable() { return drawable; }
// final EGLContext getContextES1() { return contextES1; }
// final EGLContext getContextES2() { return contextES2; }
+ final GLRendererQuirks getGLRendererQuirksES1() { return rendererQuirksES1; }
+ final GLRendererQuirks getGLRendererQuirksES2() { return rendererQuirksES2; }
+ final int getCtpES1() { return ctpES1; }
+ final int getCtpES2() { return ctpES2; }
final boolean wasES1ContextAvailable() { return wasES1ContextCreated; }
- final boolean wasES2ContextAvailable() { return wasES2ContextCreated; }
+ final boolean wasES2ContextAvailable() { return wasES2ContextCreated; }
+ final boolean hasES1PBuffer() { return hasPBufferES1; }
+ final boolean hasES2PBuffer() { return hasPBufferES2; }
}
@Override
@@ -253,72 +313,148 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
@Override
public final boolean getIsDeviceCompatible(AbstractGraphicsDevice device) {
// via mappings (X11/WGL/.. -> EGL) we shall be able to handle all types.
- return null!=eglES2DynamicLookupHelper || null!=eglES1DynamicLookupHelper;
+ return null != sharedMap ; // null!=eglES2DynamicLookupHelper || null!=eglES1DynamicLookupHelper;
}
- private boolean isEGLContextAvailable(AbstractGraphicsDevice adevice, EGLGraphicsDevice sharedEGLDevice, String profileString) {
- if( !GLProfile.isAvailable(adevice, profileString) ) {
+ private static List<GLCapabilitiesImmutable> getAvailableEGLConfigs(EGLGraphicsDevice eglDisplay, GLCapabilitiesImmutable caps) {
+ final IntBuffer numConfigs = Buffers.newDirectIntBuffer(1);
+ if(!EGL.eglGetConfigs(eglDisplay.getHandle(), null, 0, numConfigs)) {
+ throw new GLException("EGLDrawableFactory.getAvailableEGLConfigs: Get maxConfigs (eglGetConfigs) call failed, error "+EGLContext.toHexString(EGL.eglGetError()));
+ }
+ if(0 < numConfigs.get(0)) {
+ final PointerBuffer configs = PointerBuffer.allocateDirect(numConfigs.get(0));
+ final IntBuffer attrs = EGLGraphicsConfiguration.GLCapabilities2AttribList(caps);
+ final int winattrmask = GLGraphicsConfigurationUtil.getExclusiveWinAttributeBits(caps);
+ if( EGL.eglChooseConfig(eglDisplay.getHandle(), attrs, configs, configs.capacity(), numConfigs) && numConfigs.get(0) > 0) {
+ return EGLGraphicsConfigurationFactory.eglConfigs2GLCaps(eglDisplay, caps.getGLProfile(), configs, numConfigs.get(0), winattrmask, false /* forceTransparentFlag */);
+ }
+ }
+ return new ArrayList<GLCapabilitiesImmutable>(0);
+ }
+
+ private boolean mapAvailableEGLESConfig(AbstractGraphicsDevice adevice, int esProfile,
+ boolean[] hasPBuffer, GLRendererQuirks[] rendererQuirks, int[] ctp) {
+ final String profileString;
+ switch( esProfile ) {
+ case 1:
+ profileString = GLProfile.GLES1; break;
+ case 2:
+ default:
+ profileString = GLProfile.GLES2; break;
+ }
+ if ( !GLProfile.isAvailable(adevice, profileString) ) {
return false;
}
final GLProfile glp = GLProfile.get(adevice, profileString) ;
final GLDrawableFactoryImpl desktopFactory = (GLDrawableFactoryImpl) GLDrawableFactory.getDesktopFactory();
+ final boolean mapsADeviceToDefaultDevice = !QUERY_EGL_ES_NATIVE_TK || null == desktopFactory || adevice instanceof EGLGraphicsDevice ;
+
EGLGraphicsDevice eglDevice = null;
NativeSurface surface = null;
ProxySurface upstreamSurface = null; // X11, GLX, ..
boolean success = false;
boolean deviceFromUpstreamSurface = false;
try {
- final GLCapabilities caps = new GLCapabilities(glp);
- caps.setRedBits(5); caps.setGreenBits(5); caps.setBlueBits(5); caps.setAlphaBits(0);
- if(adevice instanceof EGLGraphicsDevice || null == desktopFactory || !QUERY_EGL_ES_NATIVE_TK) {
- eglDevice = sharedEGLDevice; // reuse
- surface = createDummySurfaceImpl(eglDevice, false, caps, null, 64, 64); // egl pbuffer offscreen
- upstreamSurface = (ProxySurface)surface;
- upstreamSurface.createNotify();
- deviceFromUpstreamSurface = false;
+ final GLCapabilities reqCapsAny = new GLCapabilities(glp);
+ reqCapsAny.setRedBits(5); reqCapsAny.setGreenBits(5); reqCapsAny.setBlueBits(5); reqCapsAny.setAlphaBits(0);
+ reqCapsAny.setDoubleBuffered(false);
+
+ if( mapsADeviceToDefaultDevice ) {
+ // In this branch, any non EGL device is mapped to EGL default shared resources (default behavior).
+ // Only one default shared resource instance is ever be created.
+ final GLCapabilitiesImmutable reqCapsPBuffer = GLGraphicsConfigurationUtil.fixGLPBufferGLCapabilities(reqCapsAny);
+ final List<GLCapabilitiesImmutable> availablePBufferCapsL = getAvailableEGLConfigs(defaultDevice, reqCapsPBuffer);
+ hasPBuffer[0] = availablePBufferCapsL.size() > 0;
+
+ // 1st case: adevice is not the EGL default device, map default shared resources
+ if( adevice != defaultDevice ) {
+ if(null == defaultSharedResource) {
+ return false;
+ }
+ switch(esProfile) {
+ case 1:
+ rendererQuirks[0] = defaultSharedResource.rendererQuirksES1;
+ ctp[0] = defaultSharedResource.ctpES1;
+ break;
+ case 2:
+ rendererQuirks[0] = defaultSharedResource.rendererQuirksES2;
+ ctp[0] = defaultSharedResource.ctpES2;
+ break;
+ }
+ EGLContext.mapStaticGLVersion(adevice, esProfile, 0, ctp[0]);
+ return true;
+ }
+
+ // attempt to created the default shared resources ..
+
+ eglDevice = defaultDevice; // reuse
+
+ if( hasPBuffer[0] ) {
+ // 2nd case create defaultDevice shared resource using pbuffer surface
+ surface = createDummySurfaceImpl(eglDevice, false, reqCapsPBuffer, reqCapsPBuffer, null, 64, 64); // egl pbuffer offscreen
+ upstreamSurface = (ProxySurface)surface;
+ upstreamSurface.createNotify();
+ deviceFromUpstreamSurface = false;
+ } else {
+ // 3rd case fake creation of defaultDevice shared resource, no pbuffer available
+ final List<GLCapabilitiesImmutable> capsAnyL = getAvailableEGLConfigs(eglDevice, reqCapsAny);
+ if(capsAnyL.size() > 0) {
+ final GLCapabilitiesImmutable chosenCaps = capsAnyL.get(0);
+ EGLContext.mapStaticGLESVersion(eglDevice, chosenCaps);
+ success = true;
+ }
+ if(DEBUG) {
+ System.err.println("EGLDrawableFactory.isEGLContextAvailable() no pbuffer config available, detected !pbuffer config: "+success);
+ EGLGraphicsConfigurationFactory.printCaps("!PBufferCaps", capsAnyL, System.err);
+ }
+ }
} else {
- surface = desktopFactory.createDummySurface(adevice, caps, null, 64, 64); // X11, WGL, .. dummy window
+ // 4th case always creates a true mapping of given device to EGL
+ surface = desktopFactory.createDummySurface(adevice, reqCapsAny, null, 64, 64); // X11, WGL, .. dummy window
upstreamSurface = ( surface instanceof ProxySurface ) ? (ProxySurface)surface : null ;
if(null != upstreamSurface) {
upstreamSurface.createNotify();
}
- eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(surface, true);
+ eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(surface);
deviceFromUpstreamSurface = true;
+ hasPBuffer[0] = true;
}
-
- final EGLDrawable drawable = (EGLDrawable) createOnscreenDrawableImpl ( surface );
- drawable.setRealized(true);
- final EGLContext context = (EGLContext) drawable.createContext(null);
- if (null != context) {
- try {
- context.makeCurrent(); // could cause exception
- success = context.isCurrent();
- if(success) {
- final String glVersion = context.getGL().glGetString(GL.GL_VERSION);
- if(null == glVersion) {
- // Oops .. something is wrong
- if(DEBUG) {
- System.err.println("EGLDrawableFactory.isEGLContextAvailable: "+eglDevice+", "+context.getGLVersion()+" - VERSION is null, dropping availability!");
+
+ if(null != surface) {
+ final EGLDrawable drawable = (EGLDrawable) createOnscreenDrawableImpl ( surface ); // works w/ implicit pbuffer surface via proxy-hook
+ drawable.setRealized(true);
+ final EGLContext context = (EGLContext) drawable.createContext(null);
+ if (null != context) {
+ try {
+ context.makeCurrent(); // could cause exception
+ if(context.isCurrent()) {
+ final String glVersion = context.getGL().glGetString(GL.GL_VERSION);
+ if(null != glVersion) {
+ context.mapCurrentAvailableGLVersion(eglDevice);
+ if(eglDevice != adevice) {
+ context.mapCurrentAvailableGLVersion(adevice);
+ }
+ rendererQuirks[0] = context.getRendererQuirks();
+ ctp[0] = context.getContextOptions();
+ success = true;
+ } else {
+ // Oops .. something is wrong
+ if(DEBUG) {
+ System.err.println("EGLDrawableFactory.isEGLContextAvailable: "+eglDevice+", "+context.getGLVersion()+" - VERSION is null, dropping availability!");
+ }
}
- success = false;
}
- }
- if(success) {
- context.mapCurrentAvailableGLVersion(eglDevice);
- if(eglDevice != adevice) {
- context.mapCurrentAvailableGLVersion(adevice);
+ } catch (GLException gle) {
+ if (DEBUG) {
+ System.err.println("EGLDrawableFactory.createShared: INFO: context create/makeCurrent failed");
+ gle.printStackTrace();
}
+ } finally {
+ context.destroy();
}
- } catch (GLException gle) {
- if (DEBUG) {
- System.err.println("EGLDrawableFactory.createShared: INFO: context create/makeCurrent failed");
- gle.printStackTrace();
- }
- } finally {
- context.destroy();
}
+ drawable.setRealized(false);
}
- drawable.setRealized(false);
} catch (Throwable t) {
if(DEBUG) {
System.err.println("Catched Exception:");
@@ -326,7 +462,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
}
success = false;
} finally {
- if(eglDevice == sharedEGLDevice) {
+ if(eglDevice == defaultDevice) {
if(null != upstreamSurface) {
upstreamSurface.destroyNotify();
}
@@ -349,54 +485,101 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
return success;
}
- /* package */ SharedResource getOrCreateEGLSharedResource(AbstractGraphicsDevice adevice) {
- if(null == eglES1DynamicLookupHelper && null == eglES2DynamicLookupHelper) {
- return null;
- }
- final String connection = adevice.getConnection();
- SharedResource sr;
+ private final boolean needsToCreateSharedResource(String key, SharedResource[] existing) {
synchronized(sharedMap) {
- sr = sharedMap.get(connection);
- }
- if(null==sr) {
- final boolean madeCurrentES1;
- final boolean madeCurrentES2;
- final EGLGraphicsDevice sharedDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(EGL.EGL_DEFAULT_DISPLAY, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
-
- if(QUERY_EGL_ES) {
- madeCurrentES1 = isEGLContextAvailable(adevice, sharedDevice, GLProfile.GLES1);
- madeCurrentES2 = isEGLContextAvailable(adevice, sharedDevice, GLProfile.GLES2);
- } else {
- madeCurrentES1 = true;
- madeCurrentES2 = true;
- EGLContext.mapStaticGLESVersion(sharedDevice, 1);
- if(sharedDevice != adevice) {
- EGLContext.mapStaticGLESVersion(adevice, 1);
+ final SharedResource sr = sharedMap.get(key);
+ if( null == sr ) {
+ final boolean createAttempted = sharedMapCreateAttempt.contains(key);
+ if(!createAttempted) {
+ sharedMapCreateAttempt.add(key);
}
- EGLContext.mapStaticGLESVersion(sharedDevice, 2);
- if(sharedDevice != adevice) {
- EGLContext.mapStaticGLESVersion(adevice, 2);
+ return !createAttempted;
+ } else {
+ if(null != existing) {
+ existing[0] = sr;
}
+ return false;
}
-
- if( !EGLContext.getAvailableGLVersionsSet(adevice) ) {
- // Even though we override the non EGL native mapping intentionally,
- // avoid exception due to double 'set' - carefull exception of the rule.
- EGLContext.setAvailableGLVersionsSet(adevice);
+ }
+ }
+
+ /* package */ SharedResource getOrCreateEGLSharedResource(AbstractGraphicsDevice adevice) {
+ if(null == sharedMap) { // null == eglES1DynamicLookupHelper && null == eglES2DynamicLookupHelper
+ return null;
+ }
+
+ if( needsToCreateSharedResource(defaultDevice.getUniqueID(), null) ) {
+ if (DEBUG) {
+ System.err.println("EGLDrawableFactory.createShared: (defaultDevice): req. device: "+adevice+", defaultDevice "+defaultDevice);
+ Thread.dumpStack();
}
- sr = new SharedResource(sharedDevice, madeCurrentES1, madeCurrentES2);
-
- synchronized(sharedMap) {
- sharedMap.put(connection, sr);
- if(adevice != sharedDevice) {
- sharedMap.put(sharedDevice.getConnection(), sr);
- }
+ if(null != defaultSharedResource) {
+ dumpMap();
+ throw new InternalError("defaultSharedResource already exist: "+defaultSharedResource);
}
- if (DEBUG) {
- System.err.println("EGLDrawableFactory.createShared: devices: queried " + QUERY_EGL_ES + "[nativeTK "+QUERY_EGL_ES_NATIVE_TK+"], " + adevice + ", " + sharedDevice);
- System.err.println("EGLDrawableFactory.createShared: context ES1: " + madeCurrentES1);
- System.err.println("EGLDrawableFactory.createShared: context ES2: " + madeCurrentES2);
+ defaultSharedResource = createEGLSharedResourceImpl(defaultDevice);
+ }
+
+ final String key = adevice.getUniqueID();
+ if( defaultDevice.getUniqueID().equals(key) ) {
+ return defaultSharedResource;
+ } else {
+ if( null == defaultSharedResource) { // defaultDevice must be initialized before host-device
+ dumpMap();
+ throw new InternalError("defaultSharedResource does not exist");
}
+ final SharedResource[] existing = new SharedResource[] { null };
+ if ( !needsToCreateSharedResource(key, existing) ) {
+ return existing[0];
+ }
+ return createEGLSharedResourceImpl(adevice);
+ }
+ }
+
+ private SharedResource createEGLSharedResourceImpl(AbstractGraphicsDevice adevice) {
+ final boolean madeCurrentES1;
+ final boolean madeCurrentES2;
+ boolean[] hasPBufferES1 = new boolean[] { false };
+ boolean[] hasPBufferES2 = new boolean[] { false };
+ // EGLContext[] eglCtxES1 = new EGLContext[] { null };
+ // EGLContext[] eglCtxES2 = new EGLContext[] { null };
+ GLRendererQuirks[] rendererQuirksES1 = new GLRendererQuirks[] { null };
+ GLRendererQuirks[] rendererQuirksES2 = new GLRendererQuirks[] { null };
+ int[] ctpES1 = new int[] { -1 };
+ int[] ctpES2 = new int[] { -1 };
+
+
+ if (DEBUG) {
+ System.err.println("EGLDrawableFactory.createShared(): device "+adevice);
+ }
+
+ if( null != eglES1DynamicLookupHelper ) {
+ madeCurrentES1 = mapAvailableEGLESConfig(adevice, 1, hasPBufferES1, rendererQuirksES1, ctpES1);
+ } else {
+ madeCurrentES1 = false;
+ }
+ if( null != eglES2DynamicLookupHelper ) {
+ madeCurrentES2 = mapAvailableEGLESConfig(adevice, 2, hasPBufferES2, rendererQuirksES2, ctpES2);
+ } else {
+ madeCurrentES2 = false;
+ }
+
+ if( !EGLContext.getAvailableGLVersionsSet(adevice) ) {
+ // Even though we override the non EGL native mapping intentionally,
+ // avoid exception due to double 'set' - carefull exception of the rule.
+ EGLContext.setAvailableGLVersionsSet(adevice);
+ }
+ final SharedResource sr = new SharedResource(defaultDevice, madeCurrentES1, hasPBufferES1[0], rendererQuirksES1[0], ctpES1[0],
+ madeCurrentES2, hasPBufferES2[0], rendererQuirksES2[0], ctpES2[0]);
+
+ synchronized(sharedMap) {
+ sharedMap.put(adevice.getUniqueID(), sr);
+ }
+ if (DEBUG) {
+ System.err.println("EGLDrawableFactory.createShared: devices: queried nativeTK "+QUERY_EGL_ES_NATIVE_TK+", adevice " + adevice + ", defaultDevice " + defaultDevice);
+ System.err.println("EGLDrawableFactory.createShared: context ES1: " + madeCurrentES1 + ", hasPBuffer "+hasPBufferES1[0]);
+ System.err.println("EGLDrawableFactory.createShared: context ES2: " + madeCurrentES2 + ", hasPBuffer "+hasPBufferES2[0]);
+ dumpMap();
}
return sr;
}
@@ -424,9 +607,18 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
@Override
protected final GLContext getOrCreateSharedContextImpl(AbstractGraphicsDevice device) {
- return null; // n/a for EGL .. since we don't keep the resources
+ return null; // FIXME: n/a ..
}
-
+
+ @Override
+ public GLRendererQuirks getRendererQuirks(AbstractGraphicsDevice device) {
+ SharedResource sr = getOrCreateEGLSharedResource(device);
+ if(null!=sr) {
+ return null != sr.getGLRendererQuirksES2() ? sr.getGLRendererQuirksES2() : sr.getGLRendererQuirksES1() ;
+ }
+ return null;
+ }
+
@Override
protected AbstractGraphicsDevice getOrCreateSharedDeviceImpl(AbstractGraphicsDevice device) {
SharedResource sr = getOrCreateEGLSharedResource(device);
@@ -453,7 +645,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
@Override
protected List<GLCapabilitiesImmutable> getAvailableCapabilitiesImpl(AbstractGraphicsDevice device) {
- if(null == eglES1DynamicLookupHelper && null == eglES2DynamicLookupHelper) {
+ if(null == sharedMap) { // null == eglES1DynamicLookupHelper && null == eglES2DynamicLookupHelper
return new ArrayList<GLCapabilitiesImmutable>(); // null
}
return EGLGraphicsConfigurationFactory.getAvailableCapabilities(this, device);
@@ -464,50 +656,9 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
if (target == null) {
throw new IllegalArgumentException("Null target");
}
- return new EGLOnscreenDrawable(this, getEGLSurface(target));
+ return new EGLOnscreenDrawable(this, EGLWrappedSurface.get(target));
}
- protected static NativeSurface getEGLSurface(NativeSurface surface) {
- AbstractGraphicsConfiguration aConfig = surface.getGraphicsConfiguration();
- AbstractGraphicsDevice aDevice = aConfig.getScreen().getDevice();
- if( aDevice instanceof EGLGraphicsDevice && aConfig instanceof EGLGraphicsConfiguration ) {
- // already in native EGL format
- if(DEBUG) {
- System.err.println(getThreadName() + ": getEGLSurface - already in EGL format - use as-is: "+aConfig);
- }
- return surface;
- }
- // create EGL instance out of platform native types
- final EGLGraphicsDevice eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(surface, true);
- final AbstractGraphicsScreen eglScreen = new DefaultGraphicsScreen(eglDevice, aConfig.getScreen().getIndex());
- final GLCapabilitiesImmutable capsRequested = (GLCapabilitiesImmutable) aConfig.getRequestedCapabilities();
- final EGLGraphicsConfiguration eglConfig;
- if( aConfig instanceof EGLGraphicsConfiguration ) {
- // Config is already in EGL type - reuse ..
- final EGLGLCapabilities capsChosen = (EGLGLCapabilities) aConfig.getChosenCapabilities();
- if( 0 == capsChosen.getEGLConfig() ) {
- // 'refresh' the native EGLConfig handle
- capsChosen.setEGLConfig(EGLGraphicsConfiguration.EGLConfigId2EGLConfig(eglDevice.getHandle(), capsChosen.getEGLConfigID()));
- if( 0 == capsChosen.getEGLConfig() ) {
- throw new GLException("Refreshing native EGLConfig handle failed: "+capsChosen+" of "+aConfig);
- }
- }
- eglConfig = new EGLGraphicsConfiguration(eglScreen, capsChosen, capsRequested, null);
- if(DEBUG) {
- System.err.println(getThreadName() + ": getEGLSurface - Reusing chosenCaps: "+eglConfig);
- }
- } else {
- eglConfig = EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(
- capsRequested, capsRequested, null, eglScreen, aConfig.getVisualID(VIDType.NATIVE), false);
-
- if (null == eglConfig) {
- throw new GLException("Couldn't create EGLGraphicsConfiguration from "+eglScreen);
- } else if(DEBUG) {
- System.err.println(getThreadName() + ": getEGLSurface - Chosen eglConfig: "+eglConfig);
- }
- }
- return new WrappedSurface(eglConfig, EGL.EGL_NO_SURFACE, surface.getWidth(), surface.getHeight(), new EGLUpstreamSurfaceHook(surface));
- }
static String getThreadName() { return Thread.currentThread().getName(); }
@Override
@@ -521,83 +672,45 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
throw new GLException("Non pbuffer not yet implemented");
}
// PBuffer GLDrawable Creation
- return new EGLPbufferDrawable(this, target);
+ return new EGLPbufferDrawable(this, EGLWrappedSurface.get(target));
}
@Override
public boolean canCreateGLPbuffer(AbstractGraphicsDevice device) {
+ // SharedResource sr = getOrCreateEGLSharedResource(device);
+ // return sr.hasES1PBuffer() || sr.hasES2PBuffer();
return true;
}
@Override
protected ProxySurface createMutableSurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice,
GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested,
- GLCapabilitiesChooser chooser, int width, int height, UpstreamSurfaceHook lifecycleHook) {
+ GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstreamHook) {
+ final boolean ownDevice;
final EGLGraphicsDevice device;
- if(createNewDevice) {
- final EGLGraphicsDevice eglDeviceReq = (EGLGraphicsDevice) deviceReq;
- device = EGLDisplayUtil.eglCreateEGLGraphicsDevice(eglDeviceReq.getNativeDisplayID(), deviceReq.getConnection(), deviceReq.getUnitID());
+ if( createNewDevice || ! (deviceReq instanceof EGLGraphicsDevice) ) {
+ final long nativeDisplayID = ( deviceReq instanceof EGLGraphicsDevice) ?
+ ( (EGLGraphicsDevice) deviceReq ).getNativeDisplayID() : deviceReq.getHandle() ;
+ device = EGLDisplayUtil.eglCreateEGLGraphicsDevice(nativeDisplayID, deviceReq.getConnection(), deviceReq.getUnitID());
+ ownDevice = true;
} else {
device = (EGLGraphicsDevice) deviceReq;
+ ownDevice = false;
}
final DefaultGraphicsScreen screen = new DefaultGraphicsScreen(device, 0);
final EGLGraphicsConfiguration config = EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsChosen, capsRequested, chooser, screen, VisualIDHolder.VID_UNDEFINED, false);
if(null == config) {
throw new GLException("Choosing GraphicsConfiguration failed w/ "+capsChosen+" on "+screen);
}
- return new WrappedSurface(config, 0, width, height, lifecycleHook);
+ return new WrappedSurface(config, 0, upstreamHook, ownDevice);
}
@Override
public final ProxySurface createDummySurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice,
- GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height) {
- final GLCapabilitiesImmutable chosenCaps = GLGraphicsConfigurationUtil.fixOffscreenGLCapabilities(requestedCaps, false, canCreateGLPbuffer(deviceReq));
- return createMutableSurfaceImpl(deviceReq, createNewDevice, chosenCaps, requestedCaps, chooser, width, height, dummySurfaceLifecycleHook);
- }
- private static final ProxySurface.UpstreamSurfaceHook dummySurfaceLifecycleHook = new ProxySurface.UpstreamSurfaceHook() {
- @Override
- public final void create(ProxySurface s) {
- if( EGL.EGL_NO_SURFACE == s.getSurfaceHandle() ) {
- final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) s.getGraphicsConfiguration().getScreen().getDevice();
- if(0 == eglDevice.getHandle()) {
- eglDevice.open();
- s.setImplBitfield(ProxySurface.OWN_DEVICE);
- }
- createPBufferSurfaceImpl(s, false);
- if(DEBUG) {
- System.err.println("EGLDrawableFactory.dummySurfaceLifecycleHook.create: "+s);
- }
- }
- }
- @Override
- public final void destroy(ProxySurface s) {
- if( EGL.EGL_NO_SURFACE != s.getSurfaceHandle() ) {
- final EGLGraphicsConfiguration config = (EGLGraphicsConfiguration) s.getGraphicsConfiguration();
- final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) config.getScreen().getDevice();
- EGL.eglDestroySurface(eglDevice.getHandle(), s.getSurfaceHandle());
- s.setSurfaceHandle(EGL.EGL_NO_SURFACE);
- if( 0 != ( ProxySurface.OWN_DEVICE & s.getImplBitfield() ) ) {
- eglDevice.close();
- }
- if(DEBUG) {
- System.err.println("EGLDrawableFactory.dummySurfaceLifecycleHook.create: "+s);
- }
- }
- }
- @Override
- public final int getWidth(ProxySurface s) {
- return s.initialWidth;
- }
- @Override
- public final int getHeight(ProxySurface s) {
- return s.initialHeight;
- }
- @Override
- public String toString() {
- return "EGLSurfaceLifecycleHook[]";
- }
-
- };
+ GLCapabilitiesImmutable chosenCaps, GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height) {
+ chosenCaps = GLGraphicsConfigurationUtil.fixOffscreenBitOnly(chosenCaps); // complete validation in EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(..) above
+ return createMutableSurfaceImpl(deviceReq, createNewDevice, chosenCaps, requestedCaps, chooser, new EGLDummyUpstreamSurfaceHook(width, height));
+ }
/**
* @param ms {@link MutableSurface} which dimensions and config are being used to create the pbuffer surface.
@@ -606,7 +719,9 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
* @return the passed {@link MutableSurface} which now has the EGL pbuffer surface set as it's handle
*/
protected static MutableSurface createPBufferSurfaceImpl(MutableSurface ms, boolean useTexture) {
- final EGLGraphicsConfiguration config = (EGLGraphicsConfiguration) ms.getGraphicsConfiguration();
+ return null;
+ }
+ protected static long createPBufferSurfaceImpl(EGLGraphicsConfiguration config, int width, int height, boolean useTexture) {
final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) config.getScreen().getDevice();
final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
final int texFormat;
@@ -621,15 +736,14 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
System.out.println("Pbuffer config: " + config);
}
- final int[] attrs = EGLGraphicsConfiguration.CreatePBufferSurfaceAttribList(ms.getWidth(), ms.getHeight(), texFormat);
- final long surf = EGL.eglCreatePbufferSurface(eglDevice.getHandle(), config.getNativeConfig(), attrs, 0);
+ final IntBuffer attrs = EGLGraphicsConfiguration.CreatePBufferSurfaceAttribList(width, height, texFormat);
+ final long surf = EGL.eglCreatePbufferSurface(eglDevice.getHandle(), config.getNativeConfig(), attrs);
if (EGL.EGL_NO_SURFACE==surf) {
- throw new GLException("Creation of window surface (eglCreatePbufferSurface) failed, dim "+ms.getWidth()+"x"+ms.getHeight()+", error 0x"+Integer.toHexString(EGL.eglGetError()));
+ throw new GLException("Creation of window surface (eglCreatePbufferSurface) failed, dim "+width+"x"+height+", "+eglDevice+", "+config+", error 0x"+Integer.toHexString(EGL.eglGetError()));
} else if(DEBUG) {
System.err.println("PBuffer setSurface result: eglSurface 0x"+Long.toHexString(surf));
}
- ms.setSurfaceHandle(surf);
- return ms;
+ return surf;
}
@Override
@@ -638,7 +752,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
final EGLGraphicsDevice device = EGLDisplayUtil.eglCreateEGLGraphicsDevice(eglDeviceReq.getNativeDisplayID(), deviceReq.getConnection(), deviceReq.getUnitID());
final DefaultGraphicsScreen screen = new DefaultGraphicsScreen(device, screenIdx);
final EGLGraphicsConfiguration cfg = EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsRequested, capsRequested, chooser, screen, VisualIDHolder.VID_UNDEFINED, false);
- return new WrappedSurface(cfg, windowHandle, 0, 0, upstream);
+ return new WrappedSurface(cfg, windowHandle, upstream, true);
}
@Override
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDummyUpstreamSurfaceHook.java b/src/jogl/classes/jogamp/opengl/egl/EGLDummyUpstreamSurfaceHook.java
new file mode 100644
index 0000000..162e716
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDummyUpstreamSurfaceHook.java
@@ -0,0 +1,59 @@
+package jogamp.opengl.egl;
+
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
+
+import com.jogamp.nativewindow.UpstreamSurfaceHookMutableSize;
+import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
+
+public class EGLDummyUpstreamSurfaceHook extends UpstreamSurfaceHookMutableSize {
+ /**
+ * @param width the initial width as returned by {@link NativeSurface#getWidth()} via {@link UpstreamSurfaceHook#getWidth(ProxySurface)},
+ * not the actual dummy surface width.
+ * The latter is platform specific and small
+ * @param height the initial height as returned by {@link NativeSurface#getHeight()} via {@link UpstreamSurfaceHook#getHeight(ProxySurface)},
+ * not the actual dummy surface height,
+ * The latter is platform specific and small
+ */
+ public EGLDummyUpstreamSurfaceHook(int width, int height) {
+ super(width, height);
+ }
+
+ @Override
+ public final void create(ProxySurface s) {
+ final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) s.getGraphicsConfiguration().getScreen().getDevice();
+ eglDevice.lock();
+ try {
+ if(0 == eglDevice.getHandle()) {
+ eglDevice.open();
+ s.addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_DEVICE );
+ }
+ if( EGL.EGL_NO_SURFACE == s.getSurfaceHandle() ) {
+ s.setSurfaceHandle( EGLDrawableFactory.createPBufferSurfaceImpl((EGLGraphicsConfiguration)s.getGraphicsConfiguration(), 64, 64, false) );
+ s.addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );
+ }
+ s.addUpstreamOptionBits(ProxySurface.OPT_UPSTREAM_WINDOW_INVISIBLE);
+ } finally {
+ eglDevice.unlock();
+ }
+ }
+
+ @Override
+ public final void destroy(ProxySurface s) {
+ if( s.containsUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE ) ) {
+ final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) s.getGraphicsConfiguration().getScreen().getDevice();
+ if( EGL.EGL_NO_SURFACE == s.getSurfaceHandle() ) {
+ throw new InternalError("Owns upstream surface, but no EGL surface: "+s);
+ }
+ eglDevice.lock();
+ try {
+ EGL.eglDestroySurface(eglDevice.getHandle(), s.getSurfaceHandle());
+ s.setSurfaceHandle(EGL.EGL_NO_SURFACE);
+ s.clearUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );
+ } finally {
+ eglDevice.unlock();
+ }
+ }
+ }
+}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLExternalContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLExternalContext.java
index 585638d..84bd705 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLExternalContext.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLExternalContext.java
@@ -79,15 +79,4 @@ public class EGLExternalContext extends EGLContext {
@Override
protected void destroyImpl() throws GLException {
}
-
- @Override
- public void bindPbufferToTexture() {
- throw new GLException("Should not call this");
- }
-
- @Override
- public void releasePbufferFromTexture() {
- throw new GLException("Should not call this");
- }
-
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGLCapabilities.java b/src/jogl/classes/jogamp/opengl/egl/EGLGLCapabilities.java
index 70a5701..f857c6b 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLGLCapabilities.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLGLCapabilities.java
@@ -33,6 +33,8 @@ import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
+import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
+
public class EGLGLCapabilities extends GLCapabilities {
private long eglcfg;
@@ -45,18 +47,18 @@ public class EGLGLCapabilities extends GLCapabilities {
* @param eglcfg
* @param eglcfgid
* @param visualID native visualID if valid, otherwise VisualIDHolder.VID_UNDEFINED
- * @param glp desired GLProfile, or null if determined by renderableType
+ * @param glp desired GLProfile
* @param renderableType actual EGL renderableType
*
* May throw GLException if given GLProfile is not compatible w/ renderableType
*/
public EGLGLCapabilities(long eglcfg, int eglcfgid, int visualID, GLProfile glp, int renderableType) {
- super( ( null != glp ) ? glp : getCompatible(renderableType) );
+ super( glp );
this.eglcfg = eglcfg;
this.eglcfgid = eglcfgid;
if(!isCompatible(glp, renderableType)) {
- throw new GLException("Incompatible "+glp+
- " with EGL-RenderableType["+renderableTypeToString(null, renderableType)+"]");
+ throw new GLException("Requested GLProfile "+glp+
+ " not compatible with EGL-RenderableType["+renderableTypeToString(null, renderableType)+"]");
}
this.renderableType = renderableType;
this.nativeVisualID = visualID;
@@ -111,15 +113,15 @@ public class EGLGLCapabilities extends GLCapabilities {
return false;
}
- public static GLProfile getCompatible(int renderableType) {
- if(0 != (renderableType & EGL.EGL_OPENGL_ES2_BIT) && GLProfile.isAvailable(GLProfile.GLES2)) {
- return GLProfile.get(GLProfile.GLES2);
+ public static GLProfile getCompatible(EGLGraphicsDevice device, int renderableType) {
+ if(0 != (renderableType & EGL.EGL_OPENGL_ES2_BIT) && GLProfile.isAvailable(device, GLProfile.GLES2)) {
+ return GLProfile.get(device, GLProfile.GLES2);
}
- if(0 != (renderableType & EGL.EGL_OPENGL_ES_BIT) && GLProfile.isAvailable(GLProfile.GLES1)) {
- return GLProfile.get(GLProfile.GLES1);
+ if(0 != (renderableType & EGL.EGL_OPENGL_ES_BIT) && GLProfile.isAvailable(device, GLProfile.GLES1)) {
+ return GLProfile.get(device, GLProfile.GLES1);
}
if(0 != (renderableType & EGL.EGL_OPENGL_BIT)) {
- return GLProfile.getDefault();
+ return GLProfile.getDefault(device);
}
return null;
}
@@ -129,6 +131,7 @@ public class EGLGLCapabilities extends GLCapabilities {
sink = new StringBuilder();
}
boolean first=true;
+ sink.append("0x").append(Integer.toHexString(renderableType)).append(": ");
if(0 != (renderableType & EGL.EGL_OPENGL_BIT)) {
sink.append("GL"); first=false;
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
index 716a6e6..71dfe1d 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
@@ -37,8 +37,6 @@
package jogamp.opengl.egl;
import java.nio.IntBuffer;
-import java.util.ArrayList;
-import java.util.List;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.AbstractGraphicsScreen;
@@ -85,7 +83,8 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple
}
final long cfg = EGLConfigId2EGLConfig(dpy, cfgID);
if(0 < cfg) {
- final EGLGLCapabilities caps = EGLConfig2Capabilities(capsRequested.getGLProfile(), dpy, cfg, false, capsRequested.isOnscreen(), capsRequested.isPBuffer(), false);
+ final int winattrmask = GLGraphicsConfigurationUtil.getExclusiveWinAttributeBits(capsRequested);
+ final EGLGLCapabilities caps = EGLConfig2Capabilities((EGLGraphicsDevice)absDevice, capsRequested.getGLProfile(), cfg, winattrmask, false);
return new EGLGraphicsConfiguration(absScreen, caps, capsRequested, new DefaultGLCapabilitiesChooser());
}
return null;
@@ -111,67 +110,74 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple
}
public static long EGLConfigId2EGLConfig(long display, int configID) {
- int[] attrs = new int[] {
+ final IntBuffer attrs = Buffers.newDirectIntBuffer(new int[] {
EGL.EGL_CONFIG_ID, configID,
EGL.EGL_NONE
- };
- PointerBuffer configs = PointerBuffer.allocateDirect(1);
- int[] numConfigs = new int[1];
+ });
+ final PointerBuffer configs = PointerBuffer.allocateDirect(1);
+ final IntBuffer numConfigs = Buffers.newDirectIntBuffer(1);
if (!EGL.eglChooseConfig(display,
- attrs, 0,
+ attrs,
configs, 1,
- numConfigs, 0)) {
+ numConfigs)) {
return 0;
}
- if (numConfigs[0] == 0) {
+ if (numConfigs.get(0) == 0) {
return 0;
}
return configs.get(0);
}
- static int EGLConfigDrawableTypeBits(final long display, final long config) {
+ public static boolean isEGLConfigValid(long display, long config) {
+ if(0 == config) {
+ return false;
+ }
+ final IntBuffer val = Buffers.newDirectIntBuffer(1);
+
+ // get the configID
+ if(!EGL.eglGetConfigAttrib(display, config, EGL.EGL_CONFIG_ID, val)) {
+ final int eglErr = EGL.eglGetError();
+ if(DEBUG) {
+ System.err.println("Info: Couldn't retrieve EGL ConfigID for config "+toHexString(config)+", error "+toHexString(eglErr));
+ }
+ return false;
+ }
+ return true;
+ }
+
+ static int EGLConfigDrawableTypeBits(final EGLGraphicsDevice device, final long config) {
int val = 0;
- int[] stype = new int[1];
- if(! EGL.eglGetConfigAttrib(display, config, EGL.EGL_SURFACE_TYPE, stype, 0)) {
+ final IntBuffer stype = Buffers.newDirectIntBuffer(1);
+ if(! EGL.eglGetConfigAttrib(device.getHandle(), config, EGL.EGL_SURFACE_TYPE, stype)) {
throw new GLException("Could not determine EGL_SURFACE_TYPE");
}
- if ( 0 != ( stype[0] & EGL.EGL_WINDOW_BIT ) ) {
+ final int _stype = stype.get(0);
+ if ( 0 != ( _stype & EGL.EGL_WINDOW_BIT ) ) {
val |= GLGraphicsConfigurationUtil.WINDOW_BIT;
}
- if ( 0 != ( stype[0] & EGL.EGL_PIXMAP_BIT ) ) {
+ if ( 0 != ( _stype & EGL.EGL_PIXMAP_BIT ) ) {
val |= GLGraphicsConfigurationUtil.BITMAP_BIT;
}
- if ( 0 != ( stype[0] & EGL.EGL_PBUFFER_BIT ) ) {
- val |= GLGraphicsConfigurationUtil.PBUFFER_BIT;
+ if ( 0 != ( _stype & EGL.EGL_PBUFFER_BIT ) ) {
+ val |= GLGraphicsConfigurationUtil.PBUFFER_BIT |
+ GLGraphicsConfigurationUtil.FBO_BIT;
}
-
return val;
}
- public static EGLGLCapabilities EGLConfig2Capabilities(GLProfile glp, long display, long config,
- boolean relaxed, boolean onscreen, boolean usePBuffer, boolean forceTransparentFlag) {
- List<GLCapabilitiesImmutable> bucket = new ArrayList<GLCapabilitiesImmutable>();
- final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer, false);
- if( EGLConfig2Capabilities(bucket, glp, display, config, winattrmask, forceTransparentFlag) ) {
- return (EGLGLCapabilities) bucket.get(0);
- } else if ( relaxed && EGLConfig2Capabilities(bucket, glp, display, config, GLGraphicsConfigurationUtil.ALL_BITS, forceTransparentFlag) ) {
- return (EGLGLCapabilities) bucket.get(0);
- }
- return null;
- }
-
- public static boolean EGLConfig2Capabilities(List<GLCapabilitiesImmutable> capsBucket,
- GLProfile glp, long display, long config,
- int winattrmask, boolean forceTransparentFlag) {
- final int allDrawableTypeBits = EGLConfigDrawableTypeBits(display, config);
- final int drawableTypeBits = winattrmask & allDrawableTypeBits;
-
- if( 0 == drawableTypeBits ) {
- return false;
- }
-
+ /**
+ * @param device
+ * @param glp desired GLProfile, may be null
+ * @param config
+ * @param winattrmask
+ * @param forceTransparentFlag
+ * @return
+ */
+ public static EGLGLCapabilities EGLConfig2Capabilities(EGLGraphicsDevice device, GLProfile glp, long config,
+ int winattrmask, boolean forceTransparentFlag) {
+ final long display = device.getHandle();
final IntBuffer val = Buffers.newDirectIntBuffer(1);
final int cfgID;
final int rType;
@@ -183,7 +189,7 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple
// FIXME: this happens on a ATI PC Emulation ..
System.err.println("EGL couldn't retrieve ConfigID for config "+toHexString(config)+", error "+toHexString(EGL.eglGetError()));
}
- return false;
+ return null;
}
cfgID = val.get(0);
@@ -191,10 +197,10 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple
if(DEBUG) {
System.err.println("EGL couldn't retrieve EGL_RENDERABLE_TYPE for config "+toHexString(config)+", error "+toHexString(EGL.eglGetError()));
}
- return false;
+ return null;
}
rType = val.get(0);
-
+
if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_NATIVE_VISUAL_ID, val)) {
visualID = val.get(0);
} else {
@@ -203,14 +209,29 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple
EGLGLCapabilities caps = null;
try {
+ if(null == glp) {
+ glp = EGLGLCapabilities.getCompatible(device, rType);
+ }
+ if(!EGLGLCapabilities.isCompatible(glp, rType)) {
+ if(DEBUG) {
+ System.err.println("config "+toHexString(config)+": Requested GLProfile "+glp+
+ " not compatible with EGL-RenderableType["+EGLGLCapabilities.renderableTypeToString(null, rType)+"]");
+ }
+ return null;
+ }
caps = new EGLGLCapabilities(config, cfgID, visualID, glp, rType);
} catch (GLException gle) {
if(DEBUG) {
System.err.println("config "+toHexString(config)+": "+gle);
}
- return false;
+ return null;
}
+ if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_CONFIG_CAVEAT, val)) {
+ if( EGL.EGL_SLOW_CONFIG == val.get(0) ) {
+ caps.setHardwareAccelerated(false);
+ }
+ }
if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_SAMPLES, val)) {
caps.setSampleBuffers(val.get(0)>0?true:false);
caps.setNumSamples(val.get(0));
@@ -265,107 +286,129 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple
if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_DEPTH_SIZE, val)) {
caps.setDepthBits(val.get(0));
}
- return GLGraphicsConfigurationUtil.addGLCapabilitiesPermutations(capsBucket, caps, drawableTypeBits );
+
+ // Since the passed GLProfile may be null,
+ // we use EGL_RENDERABLE_TYPE derived profile as created in the EGLGLCapabilities constructor.
+ final int availableTypeBits = EGLConfigDrawableTypeBits(device, config);
+ final int drawableTypeBits = winattrmask & availableTypeBits;
+
+ if( 0 == drawableTypeBits ) {
+ return null;
+ }
+
+ return (EGLGLCapabilities) GLGraphicsConfigurationUtil.fixWinAttribBitsAndHwAccel(device, drawableTypeBits, caps);
}
- public static int[] GLCapabilities2AttribList(GLCapabilitiesImmutable caps) {
- int[] attrs = new int[32];
+ public static IntBuffer GLCapabilities2AttribList(GLCapabilitiesImmutable caps) {
+ final IntBuffer attrs = Buffers.newDirectIntBuffer(32);
int idx=0;
- attrs[idx++] = EGL.EGL_SURFACE_TYPE;
- attrs[idx++] = caps.isOnscreen() ? ( EGL.EGL_WINDOW_BIT ) : ( caps.isPBuffer() ? EGL.EGL_PBUFFER_BIT : EGL.EGL_PIXMAP_BIT ) ;
+ attrs.put(idx++, EGL.EGL_SURFACE_TYPE);
+ final int surfaceType;
+ if( caps.isOnscreen() ) {
+ surfaceType = EGL.EGL_WINDOW_BIT;
+ } else if( caps.isFBO() ) {
+ surfaceType = EGL.EGL_PBUFFER_BIT; // native replacement!
+ } else if( caps.isPBuffer() ) {
+ surfaceType = EGL.EGL_PBUFFER_BIT;
+ } else if( caps.isBitmap() ) {
+ surfaceType = EGL.EGL_PIXMAP_BIT;
+ } else {
+ throw new GLException("no surface type set in caps: "+caps);
+ }
+ attrs.put(idx++, surfaceType);
- attrs[idx++] = EGL.EGL_RED_SIZE;
- attrs[idx++] = caps.getRedBits();
+ attrs.put(idx++, EGL.EGL_RED_SIZE);
+ attrs.put(idx++, caps.getRedBits());
- attrs[idx++] = EGL.EGL_GREEN_SIZE;
- attrs[idx++] = caps.getGreenBits();
+ attrs.put(idx++, EGL.EGL_GREEN_SIZE);
+ attrs.put(idx++, caps.getGreenBits());
- attrs[idx++] = EGL.EGL_BLUE_SIZE;
- attrs[idx++] = caps.getBlueBits();
+ attrs.put(idx++, EGL.EGL_BLUE_SIZE);
+ attrs.put(idx++, caps.getBlueBits());
if(caps.getAlphaBits()>0) {
- attrs[idx++] = EGL.EGL_ALPHA_SIZE;
- attrs[idx++] = caps.getAlphaBits();
+ attrs.put(idx++, EGL.EGL_ALPHA_SIZE);
+ attrs.put(idx++, caps.getAlphaBits());
}
if(caps.getStencilBits()>0) {
- attrs[idx++] = EGL.EGL_STENCIL_SIZE;
- attrs[idx++] = caps.getStencilBits();
+ attrs.put(idx++, EGL.EGL_STENCIL_SIZE);
+ attrs.put(idx++, caps.getStencilBits());
}
- attrs[idx++] = EGL.EGL_DEPTH_SIZE;
- attrs[idx++] = caps.getDepthBits();
+ attrs.put(idx++, EGL.EGL_DEPTH_SIZE);
+ attrs.put(idx++, caps.getDepthBits());
if(caps.getSampleBuffers()) {
if(caps.getSampleExtension().equals(GLGraphicsConfigurationUtil.NV_coverage_sample)) {
- attrs[idx++] = EGLExt.EGL_COVERAGE_BUFFERS_NV;
- attrs[idx++] = 1;
- attrs[idx++] = EGLExt.EGL_COVERAGE_SAMPLES_NV;
- attrs[idx++] = caps.getNumSamples();
+ attrs.put(idx++, EGLExt.EGL_COVERAGE_BUFFERS_NV);
+ attrs.put(idx++, 1);
+ attrs.put(idx++, EGLExt.EGL_COVERAGE_SAMPLES_NV);
+ attrs.put(idx++, caps.getNumSamples());
} else {
// try default ..
- attrs[idx++] = EGL.EGL_SAMPLE_BUFFERS;
- attrs[idx++] = 1;
- attrs[idx++] = EGL.EGL_SAMPLES;
- attrs[idx++] = caps.getNumSamples();
+ attrs.put(idx++, EGL.EGL_SAMPLE_BUFFERS);
+ attrs.put(idx++, 1);
+ attrs.put(idx++, EGL.EGL_SAMPLES);
+ attrs.put(idx++, caps.getNumSamples());
}
}
- attrs[idx++] = EGL.EGL_TRANSPARENT_TYPE;
- attrs[idx++] = caps.isBackgroundOpaque() ? EGL.EGL_NONE : EGL.EGL_TRANSPARENT_TYPE;
+ attrs.put(idx++, EGL.EGL_TRANSPARENT_TYPE);
+ attrs.put(idx++, caps.isBackgroundOpaque() ? EGL.EGL_NONE : EGL.EGL_TRANSPARENT_TYPE);
// 22
if(!caps.isBackgroundOpaque()) {
- attrs[idx++] = EGL.EGL_TRANSPARENT_RED_VALUE;
- attrs[idx++] = caps.getTransparentRedValue()>=0?caps.getTransparentRedValue():EGL.EGL_DONT_CARE;
+ attrs.put(idx++, EGL.EGL_TRANSPARENT_RED_VALUE);
+ attrs.put(idx++, caps.getTransparentRedValue()>=0?caps.getTransparentRedValue():EGL.EGL_DONT_CARE);
- attrs[idx++] = EGL.EGL_TRANSPARENT_GREEN_VALUE;
- attrs[idx++] = caps.getTransparentGreenValue()>=0?caps.getTransparentGreenValue():EGL.EGL_DONT_CARE;
+ attrs.put(idx++, EGL.EGL_TRANSPARENT_GREEN_VALUE);
+ attrs.put(idx++, caps.getTransparentGreenValue()>=0?caps.getTransparentGreenValue():EGL.EGL_DONT_CARE);
- attrs[idx++] = EGL.EGL_TRANSPARENT_BLUE_VALUE;
- attrs[idx++] = caps.getTransparentBlueValue()>=0?caps.getTransparentBlueValue():EGL.EGL_DONT_CARE;
+ attrs.put(idx++, EGL.EGL_TRANSPARENT_BLUE_VALUE);
+ attrs.put(idx++, caps.getTransparentBlueValue()>=0?caps.getTransparentBlueValue():EGL.EGL_DONT_CARE);
/** Not define in EGL
- attrs[idx++] = EGL.EGL_TRANSPARENT_ALPHA_VALUE;
- attrs[idx++] = caps.getTransparentAlphaValue()>=0?caps.getTransparentAlphaValue():EGL.EGL_DONT_CARE; */
+ attrs.put(idx++, EGL.EGL_TRANSPARENT_ALPHA_VALUE;
+ attrs.put(idx++, caps.getTransparentAlphaValue()>=0?caps.getTransparentAlphaValue():EGL.EGL_DONT_CARE; */
}
// 28
- attrs[idx++] = EGL.EGL_RENDERABLE_TYPE;
+ attrs.put(idx++, EGL.EGL_RENDERABLE_TYPE);
if(caps.getGLProfile().usesNativeGLES1()) {
- attrs[idx++] = EGL.EGL_OPENGL_ES_BIT;
+ attrs.put(idx++, EGL.EGL_OPENGL_ES_BIT);
} else if(caps.getGLProfile().usesNativeGLES2()) {
- attrs[idx++] = EGL.EGL_OPENGL_ES2_BIT;
+ attrs.put(idx++, EGL.EGL_OPENGL_ES2_BIT);
} else {
- attrs[idx++] = EGL.EGL_OPENGL_BIT;
+ attrs.put(idx++, EGL.EGL_OPENGL_BIT);
}
// 30
- attrs[idx++] = EGL.EGL_NONE;
+ attrs.put(idx++, EGL.EGL_NONE);
return attrs;
}
- public static int[] CreatePBufferSurfaceAttribList(int width, int height, int texFormat) {
- int[] attrs = new int[16];
+ public static IntBuffer CreatePBufferSurfaceAttribList(int width, int height, int texFormat) {
+ IntBuffer attrs = Buffers.newDirectIntBuffer(16);
int idx=0;
- attrs[idx++] = EGL.EGL_WIDTH;
- attrs[idx++] = width;
+ attrs.put(idx++, EGL.EGL_WIDTH);
+ attrs.put(idx++, width);
- attrs[idx++] = EGL.EGL_HEIGHT;
- attrs[idx++] = height;
+ attrs.put(idx++, EGL.EGL_HEIGHT);
+ attrs.put(idx++, height);
- attrs[idx++] = EGL.EGL_TEXTURE_FORMAT;
- attrs[idx++] = texFormat;
+ attrs.put(idx++, EGL.EGL_TEXTURE_FORMAT);
+ attrs.put(idx++, texFormat);
- attrs[idx++] = EGL.EGL_TEXTURE_TARGET;
- attrs[idx++] = EGL.EGL_NO_TEXTURE==texFormat ? EGL.EGL_NO_TEXTURE : EGL.EGL_TEXTURE_2D;
+ attrs.put(idx++, EGL.EGL_TEXTURE_TARGET);
+ attrs.put(idx++, EGL.EGL_NO_TEXTURE==texFormat ? EGL.EGL_NO_TEXTURE : EGL.EGL_TEXTURE_2D);
- attrs[idx++] = EGL.EGL_NONE;
+ attrs.put(idx++, EGL.EGL_NONE);
return attrs;
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java
index 0b21d20..f638ef8 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java
@@ -74,6 +74,7 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
static VisualIDHolder.VIDComparator EglCfgIDComparator = new VisualIDHolder.VIDComparator(VisualIDHolder.VIDType.EGL_CONFIG);
static GraphicsConfigurationFactory nativeGraphicsConfigurationFactory = null;
static GraphicsConfigurationFactory kdeglGraphicsConfigurationFactory = null;
+ static GraphicsConfigurationFactory fallbackGraphicsConfigurationFactory = null;
static void registerFactory() {
GraphicsConfigurationFactory eglFactory = new EGLGraphicsConfigurationFactory();
@@ -82,13 +83,18 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
final String nwType = NativeWindowFactory.getNativeWindowType(false);
if(NativeWindowFactory.TYPE_X11 == nwType) {
nativeGraphicsConfigurationFactory = GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.x11.X11GraphicsDevice.class, GLCapabilitiesImmutable.class, eglFactory);
+ if(null != nativeGraphicsConfigurationFactory) {
+ fallbackGraphicsConfigurationFactory = nativeGraphicsConfigurationFactory;
+ } else {
+ fallbackGraphicsConfigurationFactory = GraphicsConfigurationFactory.getFactory(com.jogamp.nativewindow.x11.X11GraphicsDevice.class, CapabilitiesImmutable.class);
+ }
} /* else if(NativeWindowFactory.TYPE_WINDOWS == NativeWindowFactory.getNativeWindowType(false)) {
nativeGraphicsConfigurationFactory = GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.windows.WindowsGraphicsDevice.class, eglFactory);
} else if(NativeWindowFactory.TYPE_MACOSX == NativeWindowFactory.getNativeWindowType(false)) {
} */
// become the selector for KD/EGL ..
- kdeglGraphicsConfigurationFactory = GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.egl.EGLGraphicsDevice.class, GLCapabilitiesImmutable.class, eglFactory);
+ kdeglGraphicsConfigurationFactory = GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.egl.EGLGraphicsDevice.class, GLCapabilitiesImmutable.class, eglFactory);
}
static void unregisterFactory() {
@@ -100,6 +106,7 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
} else if(NativeWindowFactory.TYPE_MACOSX == NativeWindowFactory.getNativeWindowType(false)) {
} */
nativeGraphicsConfigurationFactory = null;
+ fallbackGraphicsConfigurationFactory = null;
GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.egl.EGLGraphicsDevice.class, GLCapabilitiesImmutable.class, kdeglGraphicsConfigurationFactory);
kdeglGraphicsConfigurationFactory = null;
@@ -143,8 +150,8 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
absScreen, nativeVisualID, false);
} else {
// handle non native cases (X11, ..)
- if(null == nativeGraphicsConfigurationFactory) {
- throw new InternalError("Native GraphicsConfigurationFactory is null, but call issued for device: "+absDevice+" of type "+absDevice.getClass().getSimpleName());
+ if(null == fallbackGraphicsConfigurationFactory) {
+ throw new InternalError("Native fallback GraphicsConfigurationFactory is null, but call issued for device: "+absDevice+" of type "+absDevice.getClass().getSimpleName());
}
if(glCapsChosen.getGLProfile().usesNativeGLES()) {
@@ -165,9 +172,9 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
if(null == cfg) {
// fwd to native config factory (only X11 for now)
if(DEBUG) {
- System.err.println("EGLGraphicsConfigurationFactory.choose..: Delegate to "+nativeGraphicsConfigurationFactory.getClass().getSimpleName());
+ System.err.println("EGLGraphicsConfigurationFactory.choose..: Delegate to "+fallbackGraphicsConfigurationFactory.getClass().getSimpleName());
}
- cfg = nativeGraphicsConfigurationFactory.chooseGraphicsConfiguration(capsChosen, capsRequested, chooser, absScreen, nativeVisualID);
+ cfg = fallbackGraphicsConfigurationFactory.chooseGraphicsConfiguration(capsChosen, capsRequested, chooser, absScreen, nativeVisualID);
}
}
return cfg;
@@ -200,7 +207,7 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
throw new GLException("Graphics configuration get all configs (eglGetConfigs) call failed, error "+toHexString(EGL.eglGetError()));
}
if (numConfigs.get(0) > 0) {
- availableCaps = eglConfigs2GLCaps(null, eglDisplay, configs, numConfigs.get(0), GLGraphicsConfigurationUtil.ALL_BITS, false);
+ availableCaps = eglConfigs2GLCaps(eglDevice, null, configs, numConfigs.get(0), GLGraphicsConfigurationUtil.ALL_BITS, false);
if( null != availableCaps && availableCaps.size() > 1) {
Collections.sort(availableCaps, EglCfgIDComparator);
}
@@ -240,10 +247,8 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
}
final GLProfile glp = capsChosen.getGLProfile();
- final EGLDrawableFactory factory = (EGLDrawableFactory) GLDrawableFactory.getEGLFactory();
- capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( capsChosen, GLContext.isFBOAvailable(absDevice, glp), factory.canCreateGLPbuffer(absDevice) );
-
- EGLGraphicsConfiguration res = eglChooseConfig(eglDevice.getHandle(), capsChosen, capsReq, chooser, absScreen, nativeVisualID, forceTransparentFlag);
+ capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( capsChosen, GLDrawableFactory.getEGLFactory(), absDevice);
+ EGLGraphicsConfiguration res = eglChooseConfig(eglDevice, capsChosen, capsReq, chooser, absScreen, nativeVisualID, forceTransparentFlag);
if(null==res) {
if(DEBUG) {
System.err.println("eglChooseConfig failed with given capabilities "+capsChosen);
@@ -267,7 +272,7 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
if(DEBUG) {
System.err.println("trying fixed caps (1): "+fixedCaps);
}
- res = eglChooseConfig(eglDevice.getHandle(), fixedCaps, capsReq, chooser, absScreen, nativeVisualID, false);
+ res = eglChooseConfig(eglDevice, fixedCaps, capsReq, chooser, absScreen, nativeVisualID, false);
}
if(null==res) {
//
@@ -285,7 +290,7 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
if(DEBUG) {
System.err.println("trying fixed caps (2): "+fixedCaps);
}
- res = eglChooseConfig(eglDevice.getHandle(), fixedCaps, capsReq, chooser, absScreen, nativeVisualID, false);
+ res = eglChooseConfig(eglDevice, fixedCaps, capsReq, chooser, absScreen, nativeVisualID, false);
}
if(null==res) {
//
@@ -305,7 +310,7 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
if(DEBUG) {
System.err.println("trying fixed caps (3): "+fixedCaps);
}
- res = eglChooseConfig(eglDevice.getHandle(), fixedCaps, capsReq, chooser, absScreen, nativeVisualID, false);
+ res = eglChooseConfig(eglDevice, fixedCaps, capsReq, chooser, absScreen, nativeVisualID, false);
}
if(null==res) {
throw new GLException("Graphics configuration failed [direct caps, eglGetConfig/chooser and fixed-caps(1-3)]");
@@ -317,15 +322,15 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
return res;
}
- static EGLGraphicsConfiguration eglChooseConfig(long eglDisplay,
+
+ static EGLGraphicsConfiguration eglChooseConfig(EGLGraphicsDevice device,
GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested,
GLCapabilitiesChooser chooser,
AbstractGraphicsScreen absScreen,
int nativeVisualID, boolean forceTransparentFlag) {
+ final long eglDisplay = device.getHandle();
final GLProfile glp = capsChosen.getGLProfile();
- final boolean onscreen = capsChosen.isOnscreen();
- final boolean usePBuffer = capsChosen.isPBuffer();
- final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer, false);
+ final int winattrmask = GLGraphicsConfigurationUtil.getExclusiveWinAttributeBits(capsChosen);
List<GLCapabilitiesImmutable> availableCaps = null;
int recommendedIndex = -1;
long recommendedEGLConfig = -1;
@@ -338,10 +343,15 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
throw new GLException("EGLGraphicsConfiguration.eglChooseConfig: Get maxConfigs (eglGetConfigs) no configs");
}
if (DEBUG) {
- System.err.println("EGLGraphicsConfiguration.eglChooseConfig: eglChooseConfig eglDisplay "+toHexString(eglDisplay)+", nativeVisualID "+toHexString(nativeVisualID)+", onscreen "+onscreen+", usePBuffer "+usePBuffer+", "+capsChosen+", numConfigs "+numConfigs.get(0));
+ System.err.println("EGLGraphicsConfiguration.eglChooseConfig: eglChooseConfig eglDisplay "+toHexString(eglDisplay)+
+ ", nativeVisualID "+toHexString(nativeVisualID)+
+ ", capsChosen "+capsChosen+", winbits "+GLGraphicsConfigurationUtil.winAttributeBits2String(null, winattrmask).toString()+
+ ", fboAvail "+GLContext.isFBOAvailable(device, glp)+
+ ", device "+device+", "+device.getUniqueID()+
+ ", numConfigs "+numConfigs.get(0));
}
- final IntBuffer attrs = Buffers.newDirectIntBuffer(EGLGraphicsConfiguration.GLCapabilities2AttribList(capsChosen));
+ final IntBuffer attrs = EGLGraphicsConfiguration.GLCapabilities2AttribList(capsChosen);
PointerBuffer configs = PointerBuffer.allocateDirect(numConfigs.get(0));
// 1st choice: get GLCapabilities based on users GLCapabilities
@@ -352,7 +362,7 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
System.err.println("EGLGraphicsConfiguration.eglChooseConfig: #1 eglChooseConfig: false");
}
} else if (numConfigs.get(0) > 0) {
- availableCaps = eglConfigs2GLCaps(glp, eglDisplay, configs, numConfigs.get(0), winattrmask, forceTransparentFlag);
+ availableCaps = eglConfigs2GLCaps(device, glp, configs, numConfigs.get(0), winattrmask, forceTransparentFlag);
if(availableCaps.size() > 0) {
recommendedEGLConfig = configs.get(0);
recommendedIndex = 0;
@@ -377,7 +387,7 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
throw new GLException("EGLGraphicsConfiguration.eglChooseConfig: #2 Get all configs (eglGetConfigs) call failed, error "+toHexString(EGL.eglGetError()));
}
if (numConfigs.get(0) > 0) {
- availableCaps = eglConfigs2GLCaps(glp, eglDisplay, configs, numConfigs.get(0), winattrmask, forceTransparentFlag);
+ availableCaps = eglConfigs2GLCaps(device, glp, configs, numConfigs.get(0), winattrmask, forceTransparentFlag);
}
}
@@ -385,7 +395,7 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
if(DEBUG) {
// FIXME: this happens on a ATI PC Emulation ..
System.err.println("EGLGraphicsConfiguration.eglChooseConfig: #2 Graphics configuration 1st choice and 2nd choice failed - no configs");
- availableCaps = eglConfigs2GLCaps(glp, eglDisplay, configs, numConfigs.get(0), GLGraphicsConfigurationUtil.ALL_BITS, forceTransparentFlag);
+ availableCaps = eglConfigs2GLCaps(device, glp, configs, numConfigs.get(0), GLGraphicsConfigurationUtil.ALL_BITS, forceTransparentFlag);
printCaps("AllCaps", availableCaps, System.err);
}
return null;
@@ -426,18 +436,22 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
return null;
}
final EGLGLCapabilities chosenCaps = (EGLGLCapabilities) availableCaps.get(chosenIndex);
+ final EGLGraphicsConfiguration res = new EGLGraphicsConfiguration(absScreen, chosenCaps, capsRequested, chooser);
if (DEBUG) {
- System.err.println("EGLGraphicsConfiguration.eglChooseConfig: X chosen :"+chosenIndex+", eglConfig: "+toHexString(chosenCaps.getEGLConfig())+", "+chosenCaps);
+ System.err.println("EGLGraphicsConfiguration.eglChooseConfig: X chosen :"+chosenIndex+", eglConfig: "+toHexString(chosenCaps.getEGLConfig())+": "+res);
}
- return new EGLGraphicsConfiguration(absScreen, chosenCaps, capsRequested, chooser);
+ return res;
}
- static List<GLCapabilitiesImmutable> eglConfigs2GLCaps(GLProfile glp, long eglDisplay, PointerBuffer configs, int num, int winattrmask, boolean forceTransparentFlag) {
- List<GLCapabilitiesImmutable> caps = new ArrayList<GLCapabilitiesImmutable>(num);
+ static List<GLCapabilitiesImmutable> eglConfigs2GLCaps(EGLGraphicsDevice device, GLProfile glp, PointerBuffer configs, int num, int winattrmask, boolean forceTransparentFlag) {
+ List<GLCapabilitiesImmutable> bucket = new ArrayList<GLCapabilitiesImmutable>(num);
for(int i=0; i<num; i++) {
- EGLGraphicsConfiguration.EGLConfig2Capabilities(caps, glp, eglDisplay, configs.get(i), winattrmask, forceTransparentFlag);
+ final GLCapabilitiesImmutable caps = EGLGraphicsConfiguration.EGLConfig2Capabilities(device, glp, configs.get(i), winattrmask, forceTransparentFlag);
+ if(null != caps) {
+ bucket.add(caps);
+ }
}
- return caps;
+ return bucket;
}
static void printCaps(String prefix, List<GLCapabilitiesImmutable> caps, PrintStream out) {
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenContext.java
index eae47fa..325ad61 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenContext.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenContext.java
@@ -41,16 +41,5 @@ public class EGLOnscreenContext extends EGLContext {
public EGLOnscreenContext(EGLOnscreenDrawable drawable, GLContext shareWith) {
super(drawable, shareWith);
}
-
- @Override
- public void bindPbufferToTexture() {
- throw new GLException("Should not call this");
- }
-
- @Override
- public void releasePbufferFromTexture() {
- throw new GLException("Should not call this");
- }
-
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenDrawable.java b/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenDrawable.java
index d540577..6440cf1 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenDrawable.java
@@ -54,8 +54,8 @@ public class EGLOnscreenDrawable extends EGLDrawable {
}
@Override
- protected long createSurface(EGLGraphicsConfiguration config, long nativeSurfaceHandle) {
+ protected long createSurface(EGLGraphicsConfiguration config, int width, int height, long nativeSurfaceHandle) {
return EGL.eglCreateWindowSurface(config.getScreen().getDevice().getHandle(), config.getNativeConfig(), nativeSurfaceHandle, null);
- }
+ }
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLPbufferContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLPbufferContext.java
index 7175d51..bb9eeb8 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLPbufferContext.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLPbufferContext.java
@@ -46,15 +46,5 @@ public class EGLPbufferContext extends EGLContext {
public int getFloatingPointMode() {
return 0; // FIXME ??
}
-
- @Override
- public void bindPbufferToTexture() {
- throw new GLException("Not yet implemented");
- }
-
- @Override
- public void releasePbufferFromTexture() {
- throw new GLException("Not yet implemented");
- }
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java b/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java
index 4a36625..eb7e320 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java
@@ -52,12 +52,8 @@ public class EGLPbufferDrawable extends EGLDrawable {
}
@Override
- protected long createSurface(EGLGraphicsConfiguration config, long nativeSurfaceHandle) {
- final MutableSurface ms = (MutableSurface)getNativeSurface();
- if(config != ms.getGraphicsConfiguration()) {
- throw new InternalError("Not same: "+config.hashCode()+", "+ms.getGraphicsConfiguration()+": "+config+", "+ms.getGraphicsConfiguration());
- }
- return EGLDrawableFactory.createPBufferSurfaceImpl(ms, useTexture).getSurfaceHandle();
+ protected long createSurface(EGLGraphicsConfiguration config, int width, int height, long nativeSurfaceHandle) {
+ return EGLDrawableFactory.createPBufferSurfaceImpl(config, width, height, false);
}
@Override
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLUpstreamSurfaceHook.java b/src/jogl/classes/jogamp/opengl/egl/EGLUpstreamSurfaceHook.java
index 42c6e10..342c4c4 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLUpstreamSurfaceHook.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLUpstreamSurfaceHook.java
@@ -1,38 +1,163 @@
package jogamp.opengl.egl;
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.DefaultGraphicsScreen;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
+import javax.media.nativewindow.VisualIDHolder.VIDType;
+import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLException;
import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
-public class EGLUpstreamSurfaceHook implements ProxySurface.UpstreamSurfaceHook {
+public class EGLUpstreamSurfaceHook implements UpstreamSurfaceHook.MutableSize {
+ protected static final boolean DEBUG = EGLDrawableFactory.DEBUG;
private final NativeSurface upstreamSurface;
+ private final UpstreamSurfaceHook.MutableSize upstreamSurfaceHookMutableSize;
public EGLUpstreamSurfaceHook(NativeSurface upstream) {
upstreamSurface = upstream;
+ if(upstreamSurface instanceof ProxySurface) {
+ final UpstreamSurfaceHook ush = ((ProxySurface)upstreamSurface).getUpstreamSurfaceHook();
+ if(ush instanceof UpstreamSurfaceHook.MutableSize) {
+ // offscreen NativeSurface w/ MutableSize (default)
+ upstreamSurfaceHookMutableSize = (UpstreamSurfaceHook.MutableSize) ush;
+ } else {
+ upstreamSurfaceHookMutableSize = null;
+ }
+ } else {
+ upstreamSurfaceHookMutableSize = null;
+ }
}
public final NativeSurface getUpstreamSurface() { return upstreamSurface; }
+ static String getThreadName() { return Thread.currentThread().getName(); }
+
+ public final void setSize(int width, int height) {
+ if(null != upstreamSurfaceHookMutableSize) {
+ upstreamSurfaceHookMutableSize.setSize(width, height);
+ }
+ }
+
@Override
public final void create(ProxySurface surface) {
+ final String dbgPrefix;
+ if(DEBUG) {
+ dbgPrefix = getThreadName() + ": EGLUpstreamSurfaceHook.create("+surface.getClass().getSimpleName()+"): ";
+ System.err.println(dbgPrefix+this);
+ } else {
+ dbgPrefix = null;
+ }
+
if(upstreamSurface instanceof ProxySurface) {
+ // propagate createNotify(..) so upstreamSurface will be created
((ProxySurface)upstreamSurface).createNotify();
- if(NativeSurface.LOCK_SURFACE_NOT_READY >= upstreamSurface.lockSurface()) {
- throw new GLException("Could not lock: "+upstreamSurface);
+ }
+
+ // lock upstreamSurface, so it can be used in case EGLDisplay is derived from it!
+ if(NativeSurface.LOCK_SURFACE_NOT_READY >= upstreamSurface.lockSurface()) {
+ throw new GLException("Could not lock: "+upstreamSurface);
+ }
+ try {
+ evalUpstreamSurface(dbgPrefix, surface);
+ } finally {
+ upstreamSurface.unlockSurface();
+ }
+ }
+
+ private final void evalUpstreamSurface(String dbgPrefix, ProxySurface surface) {
+ //
+ // evaluate nature of upstreamSurface, may create EGL instances if required
+ //
+
+ boolean isEGLSurfaceValid = true; // assume yes
+
+ final AbstractGraphicsConfiguration aConfig = upstreamSurface.getGraphicsConfiguration();
+ final AbstractGraphicsDevice aDevice = aConfig.getScreen().getDevice();
+
+ final EGLGraphicsDevice eglDevice;
+ if( aDevice instanceof EGLGraphicsDevice ) {
+ eglDevice = (EGLGraphicsDevice) aDevice;
+ if(DEBUG) {
+ System.err.println(dbgPrefix+"Reusing eglDevice: "+eglDevice);
+ }
+ if(EGL.EGL_NO_DISPLAY == eglDevice.getHandle()) {
+ eglDevice.open();
+ isEGLSurfaceValid = false;
+ surface.addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_DEVICE );
+ }
+ } else {
+ eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(upstreamSurface);
+ isEGLSurfaceValid = false;
+ surface.addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_DEVICE );
+ }
+
+ final GLCapabilitiesImmutable capsRequested = (GLCapabilitiesImmutable) aConfig.getRequestedCapabilities();
+ final EGLGraphicsConfiguration eglConfig;
+ if( aConfig instanceof EGLGraphicsConfiguration ) {
+ // Config is already in EGL type - reuse ..
+ final EGLGLCapabilities capsChosen = (EGLGLCapabilities) aConfig.getChosenCapabilities();
+ if( !isEGLSurfaceValid || !EGLGraphicsConfiguration.isEGLConfigValid(eglDevice.getHandle(), capsChosen.getEGLConfig()) ) {
+ // 'refresh' the native EGLConfig handle
+ capsChosen.setEGLConfig(EGLGraphicsConfiguration.EGLConfigId2EGLConfig(eglDevice.getHandle(), capsChosen.getEGLConfigID()));
+ if( 0 == capsChosen.getEGLConfig() ) {
+ throw new GLException("Refreshing native EGLConfig handle failed with error "+EGLContext.toHexString(EGL.eglGetError())+": "+eglDevice+", "+capsChosen+" of "+aConfig);
+ }
+ final AbstractGraphicsScreen eglScreen = new DefaultGraphicsScreen(eglDevice, aConfig.getScreen().getIndex());
+ eglConfig = new EGLGraphicsConfiguration(eglScreen, capsChosen, capsRequested, null);
+ if(DEBUG) {
+ System.err.println(dbgPrefix+"Refreshing eglConfig: "+eglConfig);
+ }
+ isEGLSurfaceValid = false;
+ } else {
+ eglConfig = (EGLGraphicsConfiguration) aConfig;
+ if(DEBUG) {
+ System.err.println(dbgPrefix+"Reusing eglConfig: "+eglConfig);
+ }
+ }
+ } else {
+ final AbstractGraphicsScreen eglScreen = new DefaultGraphicsScreen(eglDevice, aConfig.getScreen().getIndex());
+ eglConfig = EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(
+ capsRequested, capsRequested, null, eglScreen, aConfig.getVisualID(VIDType.NATIVE), false);
+
+ if (null == eglConfig) {
+ throw new GLException("Couldn't create EGLGraphicsConfiguration from "+eglScreen);
+ } else if(DEBUG) {
+ System.err.println(dbgPrefix+"Chosen eglConfig: "+eglConfig);
}
+ isEGLSurfaceValid = false;
}
- final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) surface.getGraphicsConfiguration().getScreen().getDevice();
- eglDevice.open();
+ surface.setGraphicsConfiguration(eglConfig);
+
+ if(isEGLSurfaceValid) {
+ isEGLSurfaceValid = EGLDrawable.isValidEGLSurface(eglDevice.getHandle(), upstreamSurface.getSurfaceHandle());
+ }
+ if(isEGLSurfaceValid) {
+ surface.setSurfaceHandle(upstreamSurface.getSurfaceHandle());
+ surface.clearUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );
+ if(DEBUG) {
+ System.err.println(dbgPrefix+"Fin: Already valid EGL surface - use as-is: "+upstreamSurface);
+ }
+ } else {
+ surface.setSurfaceHandle(EGL.EGL_NO_SURFACE);
+ surface.addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE ); // create/destroy in EGLDrawable
+ if(DEBUG) {
+ System.err.println(dbgPrefix+"Fin: EGL surface n/a - TBD: "+upstreamSurface);
+ }
+ }
}
@Override
public final void destroy(ProxySurface surface) {
- final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) surface.getGraphicsConfiguration().getScreen().getDevice();
- eglDevice.close();
+ if(EGLDrawableFactory.DEBUG) {
+ System.err.println("EGLUpstreamSurfaceHook.destroy("+surface.getClass().getSimpleName()+"): "+this);
+ }
+ surface.clearUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );
if(upstreamSurface instanceof ProxySurface) {
- upstreamSurface.unlockSurface();
((ProxySurface)upstreamSurface).destroyNotify();
}
}
@@ -49,8 +174,8 @@ public class EGLUpstreamSurfaceHook implements ProxySurface.UpstreamSurfaceHook
@Override
public String toString() {
- final String us_s = null != upstreamSurface ? ( upstreamSurface.getClass().getName() + ": " + upstreamSurface ) : "nil";
- return "EGLUpstreamSurfaceHook[upstream: "+us_s+"]";
+ final String us_s = null != upstreamSurface ? ( upstreamSurface.getClass().getName() + ": 0x" + Long.toHexString(upstreamSurface.getSurfaceHandle()) ) : "nil";
+ return "EGLUpstreamSurfaceHook[ "+ upstreamSurface.getWidth() + "x" + upstreamSurface.getHeight() + ", " + us_s+ "]";
}
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLWrappedSurface.java b/src/jogl/classes/jogamp/opengl/egl/EGLWrappedSurface.java
new file mode 100644
index 0000000..b363033
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLWrappedSurface.java
@@ -0,0 +1,26 @@
+package jogamp.opengl.egl;
+
+import javax.media.nativewindow.NativeSurface;
+
+import jogamp.nativewindow.WrappedSurface;
+
+public class EGLWrappedSurface extends WrappedSurface {
+
+ public static EGLWrappedSurface get(NativeSurface surface) {
+ if(surface instanceof EGLWrappedSurface) {
+ return (EGLWrappedSurface)surface;
+ }
+ return new EGLWrappedSurface(surface);
+ }
+
+ public EGLWrappedSurface(NativeSurface surface) {
+ super(surface.getGraphicsConfiguration(), EGL.EGL_NO_SURFACE, new EGLUpstreamSurfaceHook(surface), false /* tbd in UpstreamSurfaceHook */);
+ if(EGLDrawableFactory.DEBUG) {
+ System.err.println("EGLWrappedSurface.ctor(): "+this);
+ }
+ }
+
+ public final NativeSurface getUpstreamSurface() {
+ return ((EGLUpstreamSurfaceHook)super.getUpstreamSurfaceHook()).getUpstreamSurface();
+ }
+}
diff --git a/src/jogl/classes/jogamp/opengl/glu/GLUquadricImpl.java b/src/jogl/classes/jogamp/opengl/glu/GLUquadricImpl.java
index 3f8a765..62ff3aa 100644
--- a/src/jogl/classes/jogamp/opengl/glu/GLUquadricImpl.java
+++ b/src/jogl/classes/jogamp/opengl/glu/GLUquadricImpl.java
@@ -115,10 +115,11 @@
package jogamp.opengl.glu;
-import javax.media.opengl.*;
-import javax.media.opengl.glu.*;
+import javax.media.opengl.GL;
+import javax.media.opengl.glu.GLU;
+import javax.media.opengl.glu.GLUquadric;
+
import com.jogamp.opengl.util.ImmModeSink;
-import java.nio.*;
/**
* GLUquadricImpl.java
@@ -190,17 +191,19 @@ public class GLUquadricImpl implements GLUquadric {
ImmModeSink res = immModeSink;
if(useGLSL) {
- immModeSink = ImmModeSink.createGLSL (gl, GL.GL_STATIC_DRAW, 32,
- 3, GL.GL_FLOAT, // vertex
- 0, GL.GL_FLOAT, // color
- USE_NORM?3:0, normalType,// normal
- USE_TEXT?2:0, GL.GL_FLOAT); // texture
+ immModeSink = ImmModeSink.createGLSL (32,
+ 3, GL.GL_FLOAT, // vertex
+ 0, GL.GL_FLOAT, // color
+ USE_NORM?3:0, normalType, // normal
+ USE_TEXT?2:0, GL.GL_FLOAT, // texCoords
+ GL.GL_STATIC_DRAW);
} else {
- immModeSink = ImmModeSink.createFixed(gl, GL.GL_STATIC_DRAW, 32,
- 3, GL.GL_FLOAT, // vertex
- 0, GL.GL_FLOAT, // color
- USE_NORM?3:0, normalType,// normal
- USE_TEXT?2:0, GL.GL_FLOAT); // texture
+ immModeSink = ImmModeSink.createFixed(32,
+ 3, GL.GL_FLOAT, // vertex
+ 0, GL.GL_FLOAT, // color
+ USE_NORM?3:0, normalType, // normal
+ USE_TEXT?2:0, GL.GL_FLOAT, // texCoords
+ GL.GL_STATIC_DRAW);
}
return res;
}
@@ -430,7 +433,7 @@ public class GLUquadricImpl implements GLUquadric {
r = baseRadius;
for (j = 0; j < stacks; j++) {
float s = 0.0f;
- glBegin(gl, immModeSink.GL_QUAD_STRIP);
+ glBegin(gl, ImmModeSink.GL_QUAD_STRIP);
for (i = 0; i <= slices; i++) {
if (i == slices) {
x = sin(0.0f);
@@ -514,7 +517,7 @@ public class GLUquadricImpl implements GLUquadric {
float r2 = r1 + dr;
if (orientation == GLU.GLU_OUTSIDE) {
int s;
- glBegin(gl, immModeSink.GL_QUAD_STRIP);
+ glBegin(gl, ImmModeSink.GL_QUAD_STRIP);
for (s = 0; s <= slices; s++) {
float a;
if (s == slices)
@@ -532,7 +535,7 @@ public class GLUquadricImpl implements GLUquadric {
}
else {
int s;
- glBegin(gl, immModeSink.GL_QUAD_STRIP);
+ glBegin(gl, ImmModeSink.GL_QUAD_STRIP);
for (s = slices; s >= 0; s--) {
float a;
if (s == slices)
@@ -655,11 +658,10 @@ public class GLUquadricImpl implements GLUquadric {
int loops,
float startAngle,
float sweepAngle) {
- int i, j, max;
+ int i, j;
float[] sinCache = new float[CACHE_SIZE];
float[] cosCache = new float[CACHE_SIZE];
float angle;
- float x, y;
float sintemp, costemp;
float deltaRadius;
float radiusLow, radiusHigh;
@@ -770,7 +772,7 @@ public class GLUquadricImpl implements GLUquadric {
texHigh = radiusHigh / outerRadius / 2;
}
- glBegin(gl, immModeSink.GL_QUAD_STRIP);
+ glBegin(gl, ImmModeSink.GL_QUAD_STRIP);
for (i = 0; i <= slices; i++) {
if (orientation == GLU.GLU_OUTSIDE) {
if (textureFlag) {
@@ -984,7 +986,7 @@ public class GLUquadricImpl implements GLUquadric {
// draw intermediate stacks as quad strips
for (i = imin; i < imax; i++) {
rho = i * drho;
- glBegin(gl, immModeSink.GL_QUAD_STRIP);
+ glBegin(gl, ImmModeSink.GL_QUAD_STRIP);
s = 0.0f;
for (j = 0; j <= slices; j++) {
theta = (j == slices) ? 0.0f : j * dtheta;
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
index 82525cf..360b745 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
@@ -41,6 +41,7 @@
package jogamp.opengl.macosx.cgl;
import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
import java.util.Map;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
@@ -49,23 +50,33 @@ import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.OffscreenLayerSurface;
import javax.media.nativewindow.ProxySurface;
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GL3;
+import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
+import javax.media.opengl.GLUniformData;
import jogamp.nativewindow.macosx.OSXUtil;
import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLDrawableImpl;
+import jogamp.opengl.GLFBODrawableImpl;
import jogamp.opengl.GLGraphicsConfigurationUtil;
import jogamp.opengl.macosx.cgl.MacOSXCGLDrawable.GLBackendType;
+import com.jogamp.common.nio.Buffers;
import com.jogamp.common.nio.PointerBuffer;
import com.jogamp.common.os.Platform;
import com.jogamp.common.util.VersionNumber;
import com.jogamp.gluegen.runtime.ProcAddressTable;
import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver;
import com.jogamp.opengl.GLExtensions;
+import com.jogamp.opengl.util.PMVMatrix;
+import com.jogamp.opengl.util.glsl.ShaderCode;
+import com.jogamp.opengl.util.glsl.ShaderProgram;
public abstract class MacOSXCGLContext extends GLContextImpl
{
@@ -75,9 +86,11 @@ public abstract class MacOSXCGLContext extends GLContextImpl
boolean isNSContext();
long create(long share, int ctp, int major, int minor);
boolean destroy(long ctx);
+ boolean contextRealized(boolean realized);
boolean copyImpl(long src, int mask);
boolean makeCurrent(long ctx);
boolean release(long ctx);
+ boolean detachPBuffer();
boolean setSwapInterval(int interval);
boolean swapBuffers();
}
@@ -125,6 +138,39 @@ public abstract class MacOSXCGLContext extends GLContextImpl
}
}
+ private static final String shaderBasename = "texture01_xxx";
+
+ private static ShaderProgram createCALayerShader(GL3 gl) {
+ // Create & Link the shader program
+ final ShaderProgram sp = new ShaderProgram();
+ final ShaderCode vp = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, MacOSXCGLContext.class,
+ "../../shader", "../../shader/bin", shaderBasename, true);
+ final ShaderCode fp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, MacOSXCGLContext.class,
+ "../../shader", "../../shader/bin", shaderBasename, true);
+ vp.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_vp);
+ fp.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_fp);
+ sp.add(vp);
+ sp.add(fp);
+ if(!sp.link(gl, System.err)) {
+ throw new GLException("Couldn't link program: "+sp);
+ }
+ sp.useProgram(gl, true);
+
+ // setup mgl_PMVMatrix
+ final PMVMatrix pmvMatrix = new PMVMatrix();
+ pmvMatrix.glMatrixMode(PMVMatrix.GL_PROJECTION);
+ pmvMatrix.glLoadIdentity();
+ pmvMatrix.glMatrixMode(PMVMatrix.GL_MODELVIEW);
+ pmvMatrix.glLoadIdentity();
+ final GLUniformData pmvMatrixUniform = new GLUniformData("mgl_PMVMatrix", 4, 4, pmvMatrix.glGetPMvMatrixf()); // P, Mv
+ pmvMatrixUniform.setLocation( gl.glGetUniformLocation( sp.program(), pmvMatrixUniform.getName() ) );
+ gl.glUniform(pmvMatrixUniform);
+
+ sp.useProgram(gl, false);
+ return sp;
+ }
+
+
private boolean haveSetOpenGLMode = false;
private GLBackendType openGLMode = GLBackendType.NSOPENGL;
@@ -278,7 +324,24 @@ public abstract class MacOSXCGLContext extends GLContextImpl
throw new GLException("Error destroying OpenGL Context: "+this);
}
}
+
+ @Override
+ protected void contextRealized(boolean realized) {
+ // context stuff depends on drawable stuff
+ if(realized) {
+ super.contextRealized(true); // 1) init drawable stuff
+ impl.contextRealized(true); // 2) init context stuff
+ } else {
+ impl.contextRealized(false); // 1) free context stuff
+ super.contextRealized(false); // 2) free drawable stuff
+ }
+ }
+ /* pp */ void detachPBuffer() {
+ impl.detachPBuffer();
+ }
+
+
@Override
protected void copyImpl(GLContext source, int mask) throws GLException {
if( isNSContext() != ((MacOSXCGLContext)source).isNSContext() ) {
@@ -364,16 +427,6 @@ public abstract class MacOSXCGLContext extends GLContextImpl
throw new GLException("Should not call this");
}
- @Override
- public void bindPbufferToTexture() {
- throw new GLException("Should not call this");
- }
-
- @Override
- public void releasePbufferFromTexture() {
- throw new GLException("Should not call this");
- }
-
// Support for "mode switching" as described in MacOSXCGLDrawable
public void setOpenGLMode(GLBackendType mode) {
if (mode == openGLMode) {
@@ -420,317 +473,495 @@ public abstract class MacOSXCGLContext extends GLContextImpl
// NSOpenGLContext-based implementation
class NSOpenGLImpl implements GLBackendImpl {
- long nsOpenGLLayer = 0;
- long nsOpenGLLayerPFmt = 0;
- float screenVSyncTimeout; // microSec
- int vsyncTimeout; // microSec - for nsOpenGLLayer mode
-
- @Override
- public boolean isNSContext() { return true; }
-
- @Override
- public long create(long share, int ctp, int major, int minor) {
- long ctx = 0;
- final long nsViewHandle;
- if(drawable instanceof MacOSXCGLDrawable) {
- // we allow null here! (special pbuffer case)
- nsViewHandle = ((MacOSXCGLDrawable)MacOSXCGLContext.this.drawable).getNSViewHandle();
- } else {
- // we only allow a valid NSView here
- final long aHandle = drawable.getHandle();
- if( OSXUtil.isNSView(aHandle) ) {
- nsViewHandle = aHandle;
- } else {
- throw new RuntimeException("Anonymous drawable instance's handle not of type NSView: "+drawable.getClass().getName()+", "+drawable);
- }
- }
- final NativeSurface surface = drawable.getNativeSurface();
- final MacOSXCGLGraphicsConfiguration config = (MacOSXCGLGraphicsConfiguration) surface.getGraphicsConfiguration();
- final OffscreenLayerSurface backingLayerHost = NativeWindowFactory.getOffscreenLayerSurface(surface, true);
-
- boolean allowIncompleteView = null != backingLayerHost;
- if( !allowIncompleteView && surface instanceof ProxySurface ) {
- allowIncompleteView = 0 != ( ProxySurface.INVISIBLE_WINDOW & ((ProxySurface)surface).getImplBitfield() ) ;
- }
- final GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
- long pixelFormat = MacOSXCGLGraphicsConfiguration.GLCapabilities2NSPixelFormat(chosenCaps, ctp, major, minor);
- if (pixelFormat == 0) {
- if(DEBUG) {
- System.err.println("Unable to allocate pixel format with requested GLCapabilities: "+chosenCaps);
- }
- return 0;
- }
- config.setChosenPixelFormat(pixelFormat);
- int sRefreshRate = CGL.getScreenRefreshRate(drawable.getNativeSurface().getGraphicsConfiguration().getScreen().getIndex());
- screenVSyncTimeout = 1000000f / sRefreshRate;
- if(DEBUG) {
- System.err.println("NS create OSX>=lion "+isLionOrLater);
- System.err.println("NS create allowIncompleteView: "+allowIncompleteView);
- System.err.println("NS create backingLayerHost: "+backingLayerHost);
- System.err.println("NS create share: "+share);
- System.err.println("NS create chosenCaps: "+chosenCaps);
- System.err.println("NS create pixelFormat: "+toHexString(pixelFormat));
- System.err.println("NS create drawable native-handle: "+toHexString(drawable.getHandle()));
- System.err.println("NS create drawable NSView-handle: "+toHexString(nsViewHandle));
- System.err.println("NS create screen refresh-rate: "+sRefreshRate+" hz, "+screenVSyncTimeout+" micros");
- // Thread.dumpStack();
- }
- try {
- int[] viewNotReady = new int[1];
- // Try to allocate a context with this
- ctx = CGL.createContext(share,
- nsViewHandle, allowIncompleteView,
- pixelFormat,
- chosenCaps.isBackgroundOpaque(),
- viewNotReady, 0);
- if (0 == ctx) {
- if(DEBUG) {
- System.err.println("NS create failed: viewNotReady: "+ (1 == viewNotReady[0]));
- }
- return 0;
- }
+ private OffscreenLayerSurface backingLayerHost = null;
+ private long nsOpenGLLayer = 0;
+ private long nsOpenGLLayerPFmt = 0;
+ private float screenVSyncTimeout; // microSec
+ private int vsyncTimeout; // microSec - for nsOpenGLLayer mode
+ private int lastWidth=0, lastHeight=0; // allowing to detect size change
+ private boolean needsSetContextPBuffer = false;
+ private ShaderProgram gl3ShaderProgram = null;
+
+ @Override
+ public boolean isNSContext() { return true; }
+
+ @Override
+ public long create(long share, int ctp, int major, int minor) {
+ long ctx = 0;
+ final NativeSurface surface = drawable.getNativeSurface();
+ final MacOSXCGLGraphicsConfiguration config = (MacOSXCGLGraphicsConfiguration) surface.getGraphicsConfiguration();
+ final GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
+ final long nsViewHandle;
+ final boolean isPBuffer;
+ final boolean isFBO;
+ if(drawable instanceof GLFBODrawableImpl) {
+ nsViewHandle = 0;
+ isPBuffer = false;
+ isFBO = true;
+ if(DEBUG) {
+ System.err.println("NS create GLFBODrawableImpl drawable: isFBO "+isFBO+", isPBuffer "+isPBuffer+", "+drawable.getClass().getName()+",\n\t"+drawable);
+ }
+ } else if(drawable instanceof MacOSXCGLDrawable) {
+ // we allow null here! (special pbuffer case)
+ nsViewHandle = ((MacOSXCGLDrawable)MacOSXCGLContext.this.drawable).getNSViewHandle();
+ isPBuffer = CGL.isNSOpenGLPixelBuffer(drawable.getHandle());
+ isFBO = false;
+ if(DEBUG) {
+ System.err.println("NS create MacOSXCGLDrawable drawable handle isFBO "+isFBO+", isPBuffer "+isPBuffer+", "+drawable.getClass().getName()+",\n\t"+drawable);
+ }
+ } else {
+ // we only allow a valid NSView here
+ final long drawableHandle = drawable.getHandle();
+ final boolean isNSView = OSXUtil.isNSView(drawableHandle);
+ final boolean isNSWindow = OSXUtil.isNSWindow(drawableHandle);
+ isPBuffer = CGL.isNSOpenGLPixelBuffer(drawableHandle);
+ isFBO = false;
- if (!chosenCaps.isPBuffer() && !chosenCaps.isBackgroundOpaque()) {
- // Set the context opacity
- CGL.setContextOpacity(ctx, 0);
+ if(DEBUG) {
+ System.err.println("NS create Anonymous drawable handle "+toHexString(drawableHandle)+": isNSView "+isNSView+", isNSWindow "+isNSWindow+", isFBO "+isFBO+", isPBuffer "+isPBuffer+", "+drawable.getClass().getName()+",\n\t"+drawable);
+ }
+ if( isNSView ) {
+ nsViewHandle = drawableHandle;
+ } else if( isNSWindow ) {
+ nsViewHandle = OSXUtil.GetNSView(drawableHandle);
+ } else if( isPBuffer ) {
+ nsViewHandle = 0;
+ } else {
+ throw new RuntimeException("Anonymous drawable instance's handle neither NSView, NSWindow nor PBuffer: "+toHexString(drawableHandle)+", "+drawable.getClass().getName()+",\n\t"+drawable);
+ }
}
+ needsSetContextPBuffer = isPBuffer;
+ backingLayerHost = NativeWindowFactory.getOffscreenLayerSurface(surface, true);
- GLCapabilitiesImmutable fixedCaps = MacOSXCGLGraphicsConfiguration.NSPixelFormat2GLCapabilities(chosenCaps.getGLProfile(), pixelFormat);
+ boolean incompleteView = null != backingLayerHost;
+ if( !incompleteView && surface instanceof ProxySurface ) {
+ incompleteView = ((ProxySurface)surface).containsUpstreamOptionBits( ProxySurface.OPT_UPSTREAM_WINDOW_INVISIBLE );
+ }
+ long pixelFormat = MacOSXCGLGraphicsConfiguration.GLCapabilities2NSPixelFormat(chosenCaps, ctp, major, minor);
+ if (pixelFormat == 0) {
+ if(DEBUG) {
+ System.err.println("Unable to allocate pixel format with requested GLCapabilities: "+chosenCaps);
+ }
+ return 0;
+ }
+ GLCapabilities fixedCaps = MacOSXCGLGraphicsConfiguration.NSPixelFormat2GLCapabilities(chosenCaps.getGLProfile(), pixelFormat);
+ if( !fixedCaps.isPBuffer() && isPBuffer ) {
+ throw new InternalError("handle is PBuffer, fixedCaps not: "+drawable);
+ }
+ { // determine on-/offscreen caps, since pformat is ambiguous
+ fixedCaps.setFBO( isFBO ); // exclusive
+ fixedCaps.setPBuffer( isPBuffer ); // exclusive
+ fixedCaps.setBitmap( false ); // n/a in our OSX impl.
+ fixedCaps.setOnscreen( !isFBO && !isPBuffer );
+ }
fixedCaps = GLGraphicsConfigurationUtil.fixOpaqueGLCapabilities(fixedCaps, chosenCaps.isBackgroundOpaque());
- config.setChosenCapabilities(fixedCaps);
+ int sRefreshRate = OSXUtil.GetScreenRefreshRate(drawable.getNativeSurface().getGraphicsConfiguration().getScreen().getIndex());
+ screenVSyncTimeout = 1000000f / sRefreshRate;
if(DEBUG) {
+ System.err.println("NS create OSX>=lion "+isLionOrLater);
+ System.err.println("NS create incompleteView: "+incompleteView);
+ System.err.println("NS create backingLayerHost: "+backingLayerHost);
+ System.err.println("NS create share: "+share);
+ System.err.println("NS create drawable type: "+drawable.getClass().getName());
+ System.err.println("NS create drawable handle: isPBuffer "+isPBuffer+", isFBO "+isFBO);
+ System.err.println("NS create pixelFormat: "+toHexString(pixelFormat));
+ System.err.println("NS create chosenCaps: "+chosenCaps);
System.err.println("NS create fixedCaps: "+fixedCaps);
+ System.err.println("NS create drawable native-handle: "+toHexString(drawable.getHandle()));
+ System.err.println("NS create drawable NSView-handle: "+toHexString(nsViewHandle));
+ System.err.println("NS create screen refresh-rate: "+sRefreshRate+" hz, "+screenVSyncTimeout+" micros");
+ // Thread.dumpStack();
}
- if(fixedCaps.isPBuffer()) {
- // Must now associate the pbuffer with our newly-created context
- CGL.setContextPBuffer(ctx, drawable.getHandle());
- }
- //
- // handled layered surface
- //
+ config.setChosenCapabilities(fixedCaps);
+ /**
if(null != backingLayerHost) {
- nsOpenGLLayerPFmt = pixelFormat;
- pixelFormat = 0;
- final int texWidth, texHeight;
- if(drawable instanceof MacOSXPbufferCGLDrawable) {
- final MacOSXPbufferCGLDrawable osxPDrawable = (MacOSXPbufferCGLDrawable)drawable;
- texWidth = osxPDrawable.getTextureWidth();
- texHeight = osxPDrawable.getTextureHeight();
- } else {
- texWidth = drawable.getWidth();
- texHeight = drawable.getHeight();
+ backingLayerHost.setChosenCapabilities(fixedCaps);
+ } */
+
+ try {
+ final IntBuffer viewNotReady = Buffers.newDirectIntBuffer(1);
+ // Try to allocate a context with this
+ ctx = CGL.createContext(share,
+ nsViewHandle, incompleteView,
+ pixelFormat,
+ chosenCaps.isBackgroundOpaque(),
+ viewNotReady);
+ if (0 == ctx) {
+ if(DEBUG) {
+ System.err.println("NS create failed: viewNotReady: "+ (1 == viewNotReady.get(0)));
+ }
+ return 0;
}
- if(0>=texWidth || 0>=texHeight || !drawable.isRealized()) {
- throw new GLException("Drawable not realized yet or invalid texture size, texSize "+texWidth+"x"+texHeight+", "+drawable);
+
+ if(null != backingLayerHost) {
+ nsOpenGLLayerPFmt = pixelFormat;
+ pixelFormat = 0;
}
- nsOpenGLLayer = CGL.createNSOpenGLLayer(ctx, nsOpenGLLayerPFmt, drawable.getHandle(), fixedCaps.isBackgroundOpaque(), texWidth, texHeight);
- if (DEBUG) {
- System.err.println("NS create nsOpenGLLayer "+toHexString(nsOpenGLLayer)+", texSize "+texWidth+"x"+texHeight+", "+drawable);
+
+ if (chosenCaps.isOnscreen() && !chosenCaps.isBackgroundOpaque()) {
+ // Set the context opacity
+ CGL.setContextOpacity(ctx, 0);
+ }
+ } finally {
+ if(0!=pixelFormat) {
+ CGL.deletePixelFormat(pixelFormat);
+ pixelFormat = 0;
}
- backingLayerHost.attachSurfaceLayer(nsOpenGLLayer);
- setSwapInterval(1); // enabled per default in layered surface
- }
- } finally {
- if(0!=pixelFormat) {
- CGL.deletePixelFormat(pixelFormat);
- }
- }
- return ctx;
- }
-
- @Override
- public boolean destroy(long ctx) {
- if(0 != nsOpenGLLayer) {
- final NativeSurface surface = drawable.getNativeSurface();
- if (DEBUG) {
- System.err.println("NS destroy nsOpenGLLayer "+toHexString(nsOpenGLLayer));
- }
- final OffscreenLayerSurface ols = NativeWindowFactory.getOffscreenLayerSurface(surface, true);
- if(null != ols && ols.isSurfaceLayerAttached()) {
- // still having a valid OLS attached to surface (parent OLS could have been removed)
- ols.detachSurfaceLayer();
}
- CGL.releaseNSOpenGLLayer(nsOpenGLLayer);
- CGL.deletePixelFormat(nsOpenGLLayerPFmt);
- nsOpenGLLayerPFmt = 0;
- nsOpenGLLayer = 0;
+ return ctx;
}
- return CGL.deleteContext(ctx, true);
- }
-
- @Override
- public boolean copyImpl(long src, int mask) {
- CGL.copyContext(contextHandle, src, mask);
- return true;
- }
- @Override
- public boolean makeCurrent(long ctx) {
- final long cglCtx = CGL.getCGLContext(ctx);
- if(0 == cglCtx) {
- throw new InternalError("Null CGLContext for: "+this);
+ @Override
+ public boolean destroy(long ctx) {
+ return CGL.deleteContext(ctx, true);
}
- int err = CGL.CGLLockContext(cglCtx);
- if(CGL.kCGLNoError == err) {
- return CGL.makeCurrentContext(ctx);
- } else if(DEBUG) {
- System.err.println("NSGL: Could not lock context: err 0x"+Integer.toHexString(err)+": "+this);
+
+ @Override
+ public boolean contextRealized(boolean realized) {
+ if( realized ) {
+ if( null != backingLayerHost ) {
+ //
+ // handled layered surface
+ //
+ final GLCapabilitiesImmutable chosenCaps = drawable.getChosenGLCapabilities();
+ final long ctx = MacOSXCGLContext.this.getHandle();
+ final int texID;
+ final long drawableHandle = drawable.getHandle();
+ final long pbufferHandle;
+ if(drawable instanceof GLFBODrawableImpl) {
+ final GLFBODrawableImpl fbod = (GLFBODrawableImpl)drawable;
+ texID = fbod.getTextureBuffer(GL.GL_FRONT).getName();
+ pbufferHandle = 0;
+ fbod.setSwapBufferContext(new GLFBODrawableImpl.SwapBufferContext() {
+ public void swapBuffers(boolean doubleBuffered) {
+ MacOSXCGLContext.NSOpenGLImpl.this.swapBuffers();
+ } } ) ;
+ } else if( CGL.isNSOpenGLPixelBuffer(drawableHandle) ) {
+ texID = 0;
+ pbufferHandle = drawableHandle;
+ if(0 != drawableHandle) { // complete 'validatePBufferConfig(..)' procedure
+ CGL.setContextPBuffer(ctx, pbufferHandle);
+ needsSetContextPBuffer = false;
+ }
+ } else {
+ throw new GLException("BackingLayerHost w/ unknown handle (!FBO, !PBuffer): "+drawable);
+ }
+ lastWidth = drawable.getWidth();
+ lastHeight = drawable.getHeight();
+ if(0>=lastWidth || 0>=lastHeight || !drawable.isRealized()) {
+ throw new GLException("Drawable not realized yet or invalid texture size, texSize "+lastWidth+"x"+lastHeight+", "+drawable);
+ }
+ final int gl3ShaderProgramName;
+ if( MacOSXCGLContext.this.isGL3core() ) {
+ if( null == gl3ShaderProgram) {
+ gl3ShaderProgram = createCALayerShader(MacOSXCGLContext.this.gl.getGL3());
+ }
+ gl3ShaderProgramName = gl3ShaderProgram.program();
+ } else {
+ gl3ShaderProgramName = 0;
+ }
+ nsOpenGLLayer = CGL.createNSOpenGLLayer(ctx, gl3ShaderProgramName, nsOpenGLLayerPFmt, pbufferHandle, texID, chosenCaps.isBackgroundOpaque(), lastWidth, lastHeight);
+ if (DEBUG) {
+ System.err.println("NS create nsOpenGLLayer "+toHexString(nsOpenGLLayer)+" w/ pbuffer "+toHexString(pbufferHandle)+", texID "+texID+", texSize "+lastWidth+"x"+lastHeight+", "+drawable);
+ }
+ backingLayerHost.attachSurfaceLayer(nsOpenGLLayer);
+ setSwapInterval(1); // enabled per default in layered surface
+ } else {
+ lastWidth = drawable.getWidth();
+ lastHeight = drawable.getHeight();
+ }
+ } else {
+ if( 0 != nsOpenGLLayer ) {
+ final NativeSurface surface = drawable.getNativeSurface();
+ if (DEBUG) {
+ System.err.println("NS destroy nsOpenGLLayer "+toHexString(nsOpenGLLayer)+", "+drawable);
+ }
+ final OffscreenLayerSurface ols = NativeWindowFactory.getOffscreenLayerSurface(surface, true);
+ if(null != ols && ols.isSurfaceLayerAttached()) {
+ // still having a valid OLS attached to surface (parent OLS could have been removed)
+ ols.detachSurfaceLayer();
+ }
+ CGL.releaseNSOpenGLLayer(nsOpenGLLayer);
+ if( null != gl3ShaderProgram ) {
+ gl3ShaderProgram.destroy(MacOSXCGLContext.this.gl.getGL3());
+ gl3ShaderProgram = null;
+ }
+ nsOpenGLLayer = 0;
+ }
+ if(0 != nsOpenGLLayerPFmt) {
+ CGL.deletePixelFormat(nsOpenGLLayerPFmt);
+ nsOpenGLLayerPFmt = 0;
+ }
+ }
+ backingLayerHost = null;
+ return true;
}
- return false;
- }
- @Override
- public boolean release(long ctx) {
- try {
- gl.glFlush(); // w/o glFlush()/glFinish() OSX < 10.7 (NVidia driver) may freeze
- } catch (GLException gle) {
- if(DEBUG) {
- System.err.println("MacOSXCGLContext.NSOpenGLImpl.release: INFO: glFlush() catched exception:");
- gle.printStackTrace();
+ private final void validatePBufferConfig(long ctx) {
+ final long drawableHandle = drawable.getHandle();
+ if( needsSetContextPBuffer && 0 != drawableHandle && CGL.isNSOpenGLPixelBuffer(drawableHandle) ) {
+ // Must associate the pbuffer with our newly-created context
+ needsSetContextPBuffer = false;
+ CGL.setContextPBuffer(ctx, drawableHandle);
+ if(DEBUG) {
+ System.err.println("NS.validateDrawableConfig bind pbuffer "+toHexString(drawableHandle)+" -> ctx "+toHexString(ctx));
+ }
}
}
- final boolean res = CGL.clearCurrentContext(ctx);
- final long cglCtx = CGL.getCGLContext(ctx);
- if(0 == cglCtx) {
- throw new InternalError("Null CGLContext for: "+this);
+
+ /** Returns true if size has been updated, otherwise false (same size). */
+ private final boolean validateDrawableSizeConfig(long ctx) {
+ final int width = drawable.getWidth();
+ final int height = drawable.getHeight();
+ if( lastWidth != width || lastHeight != height ) {
+ lastWidth = drawable.getWidth();
+ lastHeight = drawable.getHeight();
+ if(DEBUG) {
+ System.err.println("NS.validateDrawableConfig size changed");
+ }
+ return true;
+ }
+ return false;
}
- final int err = CGL.CGLUnlockContext(cglCtx);
- if(DEBUG && CGL.kCGLNoError != err) {
- System.err.println("CGL: Could not unlock context: err 0x"+Integer.toHexString(err)+": "+this);
+
+ @Override
+ public boolean copyImpl(long src, int mask) {
+ CGL.copyContext(contextHandle, src, mask);
+ return true;
}
- return res && CGL.kCGLNoError == err;
- }
- @Override
- public boolean setSwapInterval(int interval) {
- if(0 != nsOpenGLLayer) {
- CGL.setNSOpenGLLayerSwapInterval(nsOpenGLLayer, interval);
- vsyncTimeout = interval * (int)screenVSyncTimeout;
- if(DEBUG) { System.err.println("NS setSwapInterval: "+vsyncTimeout+" micros"); }
+ @Override
+ public boolean makeCurrent(long ctx) {
+ final long cglCtx = CGL.getCGLContext(ctx);
+ if(0 == cglCtx) {
+ throw new InternalError("Null CGLContext for: "+this);
+ }
+ int err = CGL.CGLLockContext(cglCtx);
+ if(CGL.kCGLNoError == err) {
+ validatePBufferConfig(ctx); // required to handle pbuffer change ASAP
+ return CGL.makeCurrentContext(ctx);
+ } else if(DEBUG) {
+ System.err.println("NSGL: Could not lock context: err 0x"+Integer.toHexString(err)+": "+this);
+ }
+ return false;
}
- CGL.setSwapInterval(contextHandle, interval);
- return true;
- }
- @Override
- public boolean swapBuffers() {
- if( 0 != nsOpenGLLayer ) {
- // If v-sync is disabled, frames will be drawn as quickly as possible
- // w/o delay but in sync w/ CALayer. Otherwise wait until next swap interval (v-sync).
- CGL.waitUntilNSOpenGLLayerIsReady(nsOpenGLLayer, vsyncTimeout);
+ @Override
+ public boolean release(long ctx) {
+ try {
+ gl.glFlush(); // w/o glFlush()/glFinish() OSX < 10.7 (NVidia driver) may freeze
+ } catch (GLException gle) {
+ if(DEBUG) {
+ System.err.println("MacOSXCGLContext.NSOpenGLImpl.release: INFO: glFlush() catched exception:");
+ gle.printStackTrace();
+ }
+ }
+ final boolean res = CGL.clearCurrentContext(ctx);
+ final long cglCtx = CGL.getCGLContext(ctx);
+ if(0 == cglCtx) {
+ throw new InternalError("Null CGLContext for: "+this);
+ }
+ final int err = CGL.CGLUnlockContext(cglCtx);
+ if(DEBUG && CGL.kCGLNoError != err) {
+ System.err.println("CGL: Could not unlock context: err 0x"+Integer.toHexString(err)+": "+this);
+ }
+ return res && CGL.kCGLNoError == err;
+ }
+
+ @Override
+ public boolean detachPBuffer() {
+ needsSetContextPBuffer = true;
+ // CGL.setContextPBuffer(contextHandle, 0); // doesn't work, i.e. not taking nil
+ return true;
}
- if(CGL.flushBuffer(contextHandle)) {
+
+ @Override
+ public boolean setSwapInterval(int interval) {
if(0 != nsOpenGLLayer) {
- // trigger CALayer to update
- CGL.setNSOpenGLLayerNeedsDisplay(nsOpenGLLayer);
+ CGL.setNSOpenGLLayerSwapInterval(nsOpenGLLayer, interval);
+ vsyncTimeout = interval * (int)screenVSyncTimeout + 1000; // +1ms
+ if(DEBUG) { System.err.println("NS setSwapInterval: "+vsyncTimeout+" micros"); }
}
+ CGL.setSwapInterval(contextHandle, interval);
return true;
}
- return false;
- }
+
+ private int skipSync=0;
+
+ @Override
+ public boolean swapBuffers() {
+ final boolean res;
+ if( 0 != nsOpenGLLayer ) {
+ if( validateDrawableSizeConfig(contextHandle) ) {
+ // skip wait-for-vsync for a few frames if size has changed,
+ // allowing to update the texture IDs ASAP.
+ skipSync = 10;
+ }
+
+ final int texID;
+ final boolean valid;
+ final boolean isFBO = drawable instanceof GLFBODrawableImpl;
+ if( isFBO ){
+ texID = ((GLFBODrawableImpl)drawable).getTextureBuffer(GL.GL_FRONT).getName();
+ valid = 0 != texID;
+ } else {
+ texID = 0;
+ valid = 0 != drawable.getHandle();
+ }
+ if(valid) {
+ if(0 == skipSync) {
+ // If v-sync is disabled, frames will be drawn as quickly as possible
+ // w/o delay but in sync w/ CALayer. Otherwise wait until next swap interval (v-sync).
+ CGL.waitUntilNSOpenGLLayerIsReady(nsOpenGLLayer, vsyncTimeout);
+ } else {
+ skipSync--;
+ }
+ res = CGL.flushBuffer(contextHandle);
+ if(res) {
+ if(isFBO) {
+ // trigger CALayer to update incl. possible surface change (texture)
+ CGL.setNSOpenGLLayerNeedsDisplayFBO(nsOpenGLLayer, texID);
+ } else {
+ // trigger CALayer to update incl. possible surface change (new pbuffer handle)
+ CGL.setNSOpenGLLayerNeedsDisplayPBuffer(nsOpenGLLayer, drawable.getHandle());
+ }
+ }
+ } else {
+ res = true;
+ }
+ } else {
+ res = CGL.flushBuffer(contextHandle);
+ }
+ return res;
+ }
+
}
class CGLImpl implements GLBackendImpl {
- @Override
- public boolean isNSContext() { return false; }
-
- @Override
- public long create(long share, int ctp, int major, int minor) {
- long ctx = 0;
- MacOSXCGLGraphicsConfiguration config = (MacOSXCGLGraphicsConfiguration) drawable.getNativeSurface().getGraphicsConfiguration();
- GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable)config.getChosenCapabilities();
- long pixelFormat = MacOSXCGLGraphicsConfiguration.GLCapabilities2CGLPixelFormat(chosenCaps, ctp, major, minor);
- if (pixelFormat == 0) {
- throw new GLException("Unable to allocate pixel format with requested GLCapabilities");
- }
- config.setChosenPixelFormat(pixelFormat);
- try {
- // Create new context
- PointerBuffer ctxPB = PointerBuffer.allocateDirect(1);
- if (DEBUG) {
- System.err.println("Share context for CGL-based pbuffer context is " + toHexString(share));
- }
- int res = CGL.CGLCreateContext(pixelFormat, share, ctxPB);
- if (res != CGL.kCGLNoError) {
- throw new GLException("Error code " + res + " while creating context");
+ @Override
+ public boolean isNSContext() { return false; }
+
+ @Override
+ public long create(long share, int ctp, int major, int minor) {
+ long ctx = 0;
+ MacOSXCGLGraphicsConfiguration config = (MacOSXCGLGraphicsConfiguration) drawable.getNativeSurface().getGraphicsConfiguration();
+ GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable)config.getChosenCapabilities();
+ long pixelFormat = MacOSXCGLGraphicsConfiguration.GLCapabilities2CGLPixelFormat(chosenCaps, ctp, major, minor);
+ if (pixelFormat == 0) {
+ throw new GLException("Unable to allocate pixel format with requested GLCapabilities");
}
- if(chosenCaps.isPBuffer()) {
- // Attach newly-created context to the pbuffer
- res = CGL.CGLSetPBuffer(ctxPB.get(0), drawable.getHandle(), 0, 0, 0);
+ try {
+ // Create new context
+ PointerBuffer ctxPB = PointerBuffer.allocateDirect(1);
+ if (DEBUG) {
+ System.err.println("Share context for CGL-based pbuffer context is " + toHexString(share));
+ }
+ int res = CGL.CGLCreateContext(pixelFormat, share, ctxPB);
if (res != CGL.kCGLNoError) {
- throw new GLException("Error code " + res + " while attaching context to pbuffer");
+ throw new GLException("Error code " + res + " while creating context");
}
- }
- ctx = ctxPB.get(0);
- if(0!=ctx) {
- if(DEBUG) {
- GLCapabilitiesImmutable caps0 = MacOSXCGLGraphicsConfiguration.CGLPixelFormat2GLCapabilities(pixelFormat);
- System.err.println("NS created: "+caps0);
+ ctx = ctxPB.get(0);
+
+ if (0 != ctx) {
+ GLCapabilities fixedCaps = MacOSXCGLGraphicsConfiguration.CGLPixelFormat2GLCapabilities(pixelFormat);
+ fixedCaps = GLGraphicsConfigurationUtil.fixOpaqueGLCapabilities(fixedCaps, chosenCaps.isBackgroundOpaque());
+ { // determine on-/offscreen caps, since pformat is ambiguous
+ fixedCaps.setFBO( false ); // n/a for CGLImpl
+ fixedCaps.setPBuffer( fixedCaps.isPBuffer() && !chosenCaps.isOnscreen() );
+ fixedCaps.setBitmap( false ); // n/a in our OSX impl.
+ fixedCaps.setOnscreen( !fixedCaps.isPBuffer() );
+ }
+ config.setChosenCapabilities(fixedCaps);
+ if(DEBUG) {
+ System.err.println("CGL create fixedCaps: "+fixedCaps);
+ }
+ if(fixedCaps.isPBuffer()) {
+ // Must now associate the pbuffer with our newly-created context
+ res = CGL.CGLSetPBuffer(ctx, drawable.getHandle(), 0, 0, 0);
+ if (res != CGL.kCGLNoError) {
+ throw new GLException("Error code " + res + " while attaching context to pbuffer");
+ }
+ }
}
+ } finally {
+ CGL.CGLDestroyPixelFormat(pixelFormat);
}
- } finally {
- CGL.CGLDestroyPixelFormat(pixelFormat);
+ return ctx;
}
- return ctx;
- }
- @Override
- public boolean destroy(long ctx) {
- return CGL.CGLDestroyContext(ctx) == CGL.kCGLNoError;
- }
+ @Override
+ public boolean destroy(long ctx) {
+ return CGL.CGLDestroyContext(ctx) == CGL.kCGLNoError;
+ }
- @Override
- public boolean copyImpl(long src, int mask) {
- CGL.CGLCopyContext(src, contextHandle, mask);
- return true;
- }
+ @Override
+ public boolean contextRealized(boolean realized) {
+ return true;
+ }
+
+ @Override
+ public boolean copyImpl(long src, int mask) {
+ CGL.CGLCopyContext(src, contextHandle, mask);
+ return true;
+ }
- @Override
- public boolean makeCurrent(long ctx) {
- int err = CGL.CGLLockContext(ctx);
- if(CGL.kCGLNoError == err) {
- err = CGL.CGLSetCurrentContext(ctx);
+ @Override
+ public boolean makeCurrent(long ctx) {
+ int err = CGL.CGLLockContext(ctx);
if(CGL.kCGLNoError == err) {
- return true;
+ err = CGL.CGLSetCurrentContext(ctx);
+ if(CGL.kCGLNoError == err) {
+ return true;
+ } else if(DEBUG) {
+ System.err.println("CGL: Could not make context current: err 0x"+Integer.toHexString(err)+": "+this);
+ }
} else if(DEBUG) {
- System.err.println("CGL: Could not make context current: err 0x"+Integer.toHexString(err)+": "+this);
+ System.err.println("CGL: Could not lock context: err 0x"+Integer.toHexString(err)+": "+this);
}
- } else if(DEBUG) {
- System.err.println("CGL: Could not lock context: err 0x"+Integer.toHexString(err)+": "+this);
+ return false;
}
- return false;
- }
- @Override
- public boolean release(long ctx) {
- try {
- gl.glFlush(); // w/o glFlush()/glFinish() OSX < 10.7 (NVidia driver) may freeze
- } catch (GLException gle) {
- if(DEBUG) {
- System.err.println("MacOSXCGLContext.CGLImpl.release: INFO: glFlush() catched exception:");
- gle.printStackTrace();
+ @Override
+ public boolean release(long ctx) {
+ try {
+ gl.glFlush(); // w/o glFlush()/glFinish() OSX < 10.7 (NVidia driver) may freeze
+ } catch (GLException gle) {
+ if(DEBUG) {
+ System.err.println("MacOSXCGLContext.CGLImpl.release: INFO: glFlush() catched exception:");
+ gle.printStackTrace();
+ }
}
+ int err = CGL.CGLSetCurrentContext(0);
+ if(DEBUG && CGL.kCGLNoError != err) {
+ System.err.println("CGL: Could not release current context: err 0x"+Integer.toHexString(err)+": "+this);
+ }
+ int err2 = CGL.CGLUnlockContext(ctx);
+ if(DEBUG && CGL.kCGLNoError != err2) {
+ System.err.println("CGL: Could not unlock context: err 0x"+Integer.toHexString(err2)+": "+this);
+ }
+ return CGL.kCGLNoError == err && CGL.kCGLNoError == err2;
+ }
+
+ @Override
+ public boolean detachPBuffer() {
+ /* Doesn't work, i.e. not taking NULL
+ final int res = CGL.CGLSetPBuffer(contextHandle, 0, 0, 0, 0);
+ if (res != CGL.kCGLNoError) {
+ throw new GLException("Error code " + res + " while detaching context from pbuffer");
+ } */
+ return true;
}
- int err = CGL.CGLSetCurrentContext(0);
- if(DEBUG && CGL.kCGLNoError != err) {
- System.err.println("CGL: Could not release current context: err 0x"+Integer.toHexString(err)+": "+this);
+
+ @Override
+ public boolean setSwapInterval(int interval) {
+ final IntBuffer lval = Buffers.newDirectIntBuffer(1);
+ lval.put(0, interval);
+ CGL.CGLSetParameter(contextHandle, CGL.kCGLCPSwapInterval, lval);
+ return true;
}
- int err2 = CGL.CGLUnlockContext(ctx);
- if(DEBUG && CGL.kCGLNoError != err2) {
- System.err.println("CGL: Could not unlock context: err 0x"+Integer.toHexString(err2)+": "+this);
+ @Override
+ public boolean swapBuffers() {
+ return CGL.kCGLNoError == CGL.CGLFlushDrawable(contextHandle);
}
- return CGL.kCGLNoError == err && CGL.kCGLNoError == err2;
- }
-
- @Override
- public boolean setSwapInterval(int interval) {
- int[] lval = new int[] { interval } ;
- CGL.CGLSetParameter(contextHandle, CGL.kCGLCPSwapInterval, lval, 0);
- return true;
- }
- @Override
- public boolean swapBuffers() {
- return CGL.kCGLNoError == CGL.CGLFlushDrawable(contextHandle);
- }
}
}
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java
index af767f0..cc727c8 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java
@@ -42,10 +42,10 @@ package jogamp.opengl.macosx.cgl;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
-import java.util.Iterator;
import java.util.List;
import javax.media.nativewindow.NativeSurface;
+import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
@@ -92,7 +92,7 @@ public abstract class MacOSXCGLDrawable extends GLDrawableImpl {
this.id = id;
}
}
- private List<WeakReference<MacOSXCGLContext>> createdContexts = new ArrayList<WeakReference<MacOSXCGLContext>>();
+ /* pp */ List<WeakReference<MacOSXCGLContext>> createdContexts = new ArrayList<WeakReference<MacOSXCGLContext>>();
private boolean haveSetOpenGLMode = false;
private GLBackendType openGLMode = GLBackendType.NSOPENGL;
@@ -110,26 +110,42 @@ public abstract class MacOSXCGLDrawable extends GLDrawableImpl {
return GLBackendType.NSOPENGL == openGLMode ? getHandle() : 0;
}
- protected void registerContext(MacOSXCGLContext ctx) {
+ @Override
+ protected void associateContext(GLContext ctx, boolean bound) {
// NOTE: we need to keep track of the created contexts in order to
// implement swapBuffers() because of how Mac OS X implements its
// OpenGL window interface
synchronized (createdContexts) {
- createdContexts.add(new WeakReference<MacOSXCGLContext>(ctx));
- }
+ if(bound) {
+ createdContexts.add(new WeakReference<MacOSXCGLContext>((MacOSXCGLContext)ctx));
+ } else {
+ for(int i=0; i<createdContexts.size(); ) {
+ final WeakReference<MacOSXCGLContext> ref = createdContexts.get(i);
+ final MacOSXCGLContext _ctx = ref.get();
+ if( _ctx == null || _ctx == ctx) {
+ createdContexts.remove(i);
+ } else {
+ i++;
+ }
+ }
+ }
+ }
}
+
@Override
- protected final void swapBuffersImpl() {
- // single-buffer is already filtered out @ GLDrawableImpl#swapBuffers()
- synchronized (createdContexts) {
- for (Iterator<WeakReference<MacOSXCGLContext>> iter = createdContexts.iterator(); iter.hasNext(); ) {
- WeakReference<MacOSXCGLContext> ref = iter.next();
- MacOSXCGLContext ctx = ref.get();
- if (ctx != null) {
- ctx.swapBuffers();
- } else {
- iter.remove();
- }
+ protected final void swapBuffersImpl(boolean doubleBuffered) {
+ if(doubleBuffered) {
+ synchronized (createdContexts) {
+ for(int i=0; i<createdContexts.size(); ) {
+ final WeakReference<MacOSXCGLContext> ref = createdContexts.get(i);
+ final MacOSXCGLContext ctx = ref.get();
+ if (ctx != null) {
+ ctx.swapBuffers();
+ i++;
+ } else {
+ createdContexts.remove(i);
+ }
+ }
}
}
}
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java
index 9689d9f..ae2082d 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java
@@ -41,17 +41,17 @@
package jogamp.opengl.macosx.cgl;
import java.nio.Buffer;
+import java.nio.FloatBuffer;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
-import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.AbstractGraphicsScreen;
import javax.media.nativewindow.DefaultGraphicsScreen;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.ProxySurface;
-import javax.media.nativewindow.ProxySurface.UpstreamSurfaceHook;
+import javax.media.nativewindow.UpstreamSurfaceHook;
import javax.media.opengl.GL;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesChooser;
@@ -60,21 +60,22 @@ import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawable;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
-import javax.media.opengl.GLProfile.ShutdownType;
-import jogamp.nativewindow.macosx.OSXUtil;
+import jogamp.nativewindow.WrappedSurface;
+import jogamp.nativewindow.macosx.OSXDummyUpstreamSurfaceHook;
import jogamp.opengl.DesktopGLDynamicLookupHelper;
-import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLDrawableFactoryImpl;
import jogamp.opengl.GLDrawableImpl;
import jogamp.opengl.GLDynamicLookupHelper;
import jogamp.opengl.GLGraphicsConfigurationUtil;
import com.jogamp.common.JogampRuntimeException;
+import com.jogamp.common.nio.Buffers;
import com.jogamp.common.util.ReflectionUtil;
-import com.jogamp.nativewindow.WrappedSurface;
+import com.jogamp.nativewindow.MutableGraphicsConfiguration;
import com.jogamp.nativewindow.macosx.MacOSXGraphicsDevice;
import com.jogamp.opengl.GLExtensions;
+import com.jogamp.opengl.GLRendererQuirks;
public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
private static DesktopGLDynamicLookupHelper macOSXCGLDynamicLookupHelper = null;
@@ -119,7 +120,12 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
}
@Override
- protected final void destroy(ShutdownType shutdownType) {
+ protected final boolean isComplete() {
+ return null != macOSXCGLDynamicLookupHelper;
+ }
+
+ @Override
+ protected final void destroy() {
if(null != sharedMap) {
sharedMap.clear();
sharedMap = null;
@@ -128,10 +134,9 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
/**
* Pulling away the native library may cause havoc ..
*
- if(ShutdownType.COMPLETE == shutdownType && null != macOSXCGLDynamicLookupHelper) {
- macOSXCGLDynamicLookupHelper.destroy();
- macOSXCGLDynamicLookupHelper = null;
- } */
+ macOSXCGLDynamicLookupHelper.destroy();
+ */
+ macOSXCGLDynamicLookupHelper = null;
}
@Override
@@ -145,6 +150,7 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
static class SharedResource {
// private MacOSXCGLDrawable drawable;
// private MacOSXCGLContext context;
+ private GLRendererQuirks glRendererQuirks;
MacOSXGraphicsDevice device;
boolean wasContextCreated;
boolean hasNPOTTextures;
@@ -153,9 +159,10 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
SharedResource(MacOSXGraphicsDevice device, boolean wasContextCreated,
boolean hasNPOTTextures, boolean hasRECTTextures, boolean hasAppletFloatPixels
- /* MacOSXCGLDrawable draw, MacOSXCGLContext ctx */) {
+ /* MacOSXCGLDrawable draw, MacOSXCGLContext ctx */, GLRendererQuirks glRendererQuirks) {
// drawable = draw;
- // context = ctx;
+ // this.context = ctx;
+ this.glRendererQuirks = glRendererQuirks;
this.device = device;
this.wasContextCreated = wasContextCreated;
this.hasNPOTTextures = hasNPOTTextures;
@@ -163,6 +170,8 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
this.hasAppleFloatPixels = hasAppletFloatPixels;
}
final MacOSXGraphicsDevice getDevice() { return device; }
+ // final MacOSXCGLContext getContext() { return context; }
+ final GLRendererQuirks getGLRendererQuirks() { return glRendererQuirks; }
final boolean wasContextAvailable() { return wasContextCreated; }
final boolean isNPOTTextureAvailable() { return hasNPOTTextures; }
final boolean isRECTTextureAvailable() { return hasRECTTextures; }
@@ -209,6 +218,7 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
if(null==sr && !getDeviceTried(connection)) {
addDeviceTried(connection);
final MacOSXGraphicsDevice sharedDevice = new MacOSXGraphicsDevice(adevice.getUnitID());
+ GLRendererQuirks glRendererQuirks = null;
boolean madeCurrent = false;
boolean hasNPOTTextures = false;
boolean hasRECTTextures = false;
@@ -218,10 +228,11 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
if (null == glp) {
throw new GLException("Couldn't get default GLProfile for device: "+sharedDevice);
}
- final GLDrawableImpl sharedDrawable = createOnscreenDrawableImpl(createDummySurfaceImpl(sharedDevice, false, new GLCapabilities(glp), null, 64, 64));
+ final GLCapabilitiesImmutable caps = new GLCapabilities(glp);
+ final GLDrawableImpl sharedDrawable = createOnscreenDrawableImpl(createDummySurfaceImpl(sharedDevice, false, caps, caps, null, 64, 64));
sharedDrawable.setRealized(true);
- final GLContextImpl sharedContext = (GLContextImpl) sharedDrawable.createContext(null);
+ final MacOSXCGLContext sharedContext = (MacOSXCGLContext) sharedDrawable.createContext(null);
if (null == sharedContext) {
throw new GLException("Couldn't create shared context for drawable: "+sharedDrawable);
}
@@ -234,6 +245,7 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
hasNPOTTextures = gl.isNPOTTextureAvailable();
hasRECTTextures = gl.isExtensionAvailable(GLExtensions.EXT_texture_rectangle);
hasAppleFloatPixels = gl.isExtensionAvailable(GLExtensions.APPLE_float_pixels);
+ glRendererQuirks = sharedContext.getRendererQuirks();
}
} catch (GLException gle) {
if (DEBUG) {
@@ -252,7 +264,7 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
}
sharedDrawable.setRealized(false);
}
- sr = new SharedResource(sharedDevice, madeCurrent, hasNPOTTextures, hasRECTTextures, hasAppleFloatPixels);
+ sr = new SharedResource(sharedDevice, madeCurrent, hasNPOTTextures, hasRECTTextures, hasAppleFloatPixels, glRendererQuirks);
synchronized(sharedMap) {
sharedMap.put(connection, sr);
}
@@ -260,7 +272,7 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
if (DEBUG) {
System.err.println("MacOSXCGLDrawableFactory.createShared: device: " + sharedDevice);
System.err.println("MacOSXCGLDrawableFactory.createShared: context: madeCurrent " + madeCurrent + ", NPOT "+hasNPOTTextures+
- ", RECT "+hasRECTTextures+", FloatPixels "+hasAppleFloatPixels);
+ ", RECT "+hasRECTTextures+", FloatPixels "+hasAppleFloatPixels+", "+glRendererQuirks);
}
}
return sr;
@@ -289,11 +301,20 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
@Override
protected final GLContext getOrCreateSharedContextImpl(AbstractGraphicsDevice device) {
- // FIXME: not implemented .. needs a dummy OSX surface
+ // FIXME: no more available
return null;
}
@Override
+ public GLRendererQuirks getRendererQuirks(AbstractGraphicsDevice device) {
+ SharedResource sr = getOrCreateOSXSharedResource(device);
+ if(null!=sr) {
+ return sr.getGLRendererQuirks();
+ }
+ return null;
+ }
+
+ @Override
protected AbstractGraphicsDevice getOrCreateSharedDeviceImpl(AbstractGraphicsDevice device) {
SharedResource sr = getOrCreateOSXSharedResource(device);
if(null!=sr) {
@@ -317,9 +338,14 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
@Override
protected GLDrawableImpl createOffscreenDrawableImpl(NativeSurface target) {
- AbstractGraphicsConfiguration config = target.getGraphicsConfiguration();
- GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
+ final MutableGraphicsConfiguration config = (MutableGraphicsConfiguration) target.getGraphicsConfiguration();
+ final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
if(!caps.isPBuffer()) {
+ // Actual implementation is using PBuffer ...
+ final GLCapabilities modCaps = (GLCapabilities) caps.cloneMutable();
+ modCaps.setPBuffer(true);
+ modCaps.setBitmap(false);
+ config.setChosenCapabilities(modCaps);
return new MacOSXOffscreenCGLDrawable(this, target);
}
return new MacOSXPbufferCGLDrawable(this, target);
@@ -333,9 +359,9 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
@Override
protected ProxySurface createMutableSurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice,
GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested,
- GLCapabilitiesChooser chooser, int width, int height, UpstreamSurfaceHook lifecycleHook) {
+ GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstreamHook) {
final MacOSXGraphicsDevice device;
- if(createNewDevice) {
+ if( createNewDevice || !(deviceReq instanceof MacOSXGraphicsDevice) ) {
device = new MacOSXGraphicsDevice(deviceReq.getUnitID());
} else {
device = (MacOSXGraphicsDevice)deviceReq;
@@ -345,68 +371,23 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
if(null == config) {
throw new GLException("Choosing GraphicsConfiguration failed w/ "+capsChosen+" on "+screen);
}
- return new WrappedSurface(config, 0, width, height, lifecycleHook);
+ return new WrappedSurface(config, 0, upstreamHook, createNewDevice);
}
@Override
public final ProxySurface createDummySurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice,
- GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height) {
- final GLCapabilitiesImmutable chosenCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(requestedCaps);
- return createMutableSurfaceImpl(deviceReq, createNewDevice, chosenCaps, requestedCaps, chooser, width, height, dummySurfaceLifecycleHook);
+ GLCapabilitiesImmutable chosenCaps, GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height) {
+ chosenCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(chosenCaps);
+ return createMutableSurfaceImpl(deviceReq, createNewDevice, chosenCaps, requestedCaps, chooser,
+ new OSXDummyUpstreamSurfaceHook(width, height));
}
- private static final ProxySurface.UpstreamSurfaceHook dummySurfaceLifecycleHook = new ProxySurface.UpstreamSurfaceHook() {
- long nsWindow = 0;
- @Override
- public final void create(ProxySurface s) {
- if(0 == nsWindow && 0 == s.getSurfaceHandle()) {
- nsWindow = OSXUtil.CreateNSWindow(0, 0, s.getWidth(), s.getHeight());
- if(0 == nsWindow) {
- throw new GLException("Error NS window 0");
- }
- long nsView = OSXUtil.GetNSView(nsWindow);
- if(0 == nsView) {
- throw new GLException("Error NS view 0");
- }
- s.setSurfaceHandle(nsView);
- s.setImplBitfield(ProxySurface.INVISIBLE_WINDOW);
- if(DEBUG) {
- System.err.println("MacOSXCGLDrawableFactory.dummySurfaceLifecycleHook.create: "+s);
- }
- }
- }
- @Override
- public final void destroy(ProxySurface s) {
- if(0 != nsWindow && 0 != s.getSurfaceHandle()) {
- OSXUtil.DestroyNSWindow(nsWindow);
- nsWindow = 0;
- s.setSurfaceHandle(0);
- if(DEBUG) {
- System.err.println("MacOSXCGLDrawableFactory.dummySurfaceLifecycleHook.destroy: "+s);
- }
- }
- }
- @Override
- public final int getWidth(ProxySurface s) {
- return s.initialWidth;
- }
- @Override
- public final int getHeight(ProxySurface s) {
- return s.initialHeight;
- }
-
- @Override
- public String toString() {
- return "MacOSXLSurfaceLifecycleHook[]";
- }
-
- };
@Override
protected ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice deviceReq, int screenIdx, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstream) {
final MacOSXGraphicsDevice device = new MacOSXGraphicsDevice(deviceReq.getUnitID());
final AbstractGraphicsScreen screen = new DefaultGraphicsScreen(device, screenIdx);
final MacOSXCGLGraphicsConfiguration config = MacOSXCGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsRequested, capsRequested, chooser, screen, true);
- return new WrappedSurface(config, windowHandle, 0, 0, upstream);
+ return new WrappedSurface(config, windowHandle, upstream, true);
}
@Override
@@ -451,10 +432,9 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
@Override
protected boolean setGammaRamp(float[] ramp) {
- return CGL.setGammaRamp(ramp.length,
- ramp, 0,
- ramp, 0,
- ramp, 0);
+ final FloatBuffer rampNIO = Buffers.newDirectFloatBuffer(ramp);
+
+ return CGL.setGammaRamp(ramp.length, rampNIO, rampNIO, rampNIO);
}
@Override
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java
index 202644b..fa8e8d4 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java
@@ -36,6 +36,7 @@
package jogamp.opengl.macosx.cgl;
+import java.nio.IntBuffer;
import java.util.ArrayList;
import java.util.List;
@@ -47,27 +48,21 @@ import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
+import com.jogamp.common.nio.Buffers;
import com.jogamp.common.nio.PointerBuffer;
import com.jogamp.nativewindow.MutableGraphicsConfiguration;
public class MacOSXCGLGraphicsConfiguration extends MutableGraphicsConfiguration implements Cloneable {
- long pixelformat;
MacOSXCGLGraphicsConfiguration(AbstractGraphicsScreen screen,
- GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested,
- long pixelformat) {
+ GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested) {
super(screen, capsChosen, capsRequested);
- this.pixelformat=pixelformat;
}
public Object clone() {
return super.clone();
}
- void setChosenPixelFormat(long pixelformat) {
- this.pixelformat=pixelformat;
- }
-
protected static List<GLCapabilitiesImmutable> getAvailableCapabilities(MacOSXCGLDrawableFactory factory, AbstractGraphicsDevice device) {
MacOSXCGLDrawableFactory.SharedResource sharedResource = factory.getOrCreateOSXSharedResource(device);
if(null == sharedResource) {
@@ -77,7 +72,7 @@ public class MacOSXCGLGraphicsConfiguration extends MutableGraphicsConfiguration
return new ArrayList<GLCapabilitiesImmutable>(0);
}
- static final int[] cglInternalAttributeToken = new int[] {
+ static final IntBuffer cglInternalAttributeToken = Buffers.newDirectIntBuffer(new int[] {
CGL.kCGLPFAOpenGLProfile, // >= lion
CGL.NSOpenGLPFAAccelerated, // query only (prefer accelerated, but allow non accelerated), ignored for createPixelformat
CGL.NSOpenGLPFANoRecovery,
@@ -91,70 +86,65 @@ public class MacOSXCGLGraphicsConfiguration extends MutableGraphicsConfiguration
CGL.NSOpenGLPFAAccumSize,
CGL.NSOpenGLPFAStencilSize,
CGL.NSOpenGLPFASampleBuffers,
- CGL.NSOpenGLPFASamples };
+ CGL.NSOpenGLPFASamples });
- static int[] GLCapabilities2NSAttribList(GLCapabilitiesImmutable caps, int ctp, int major, int minor) {
- int len = cglInternalAttributeToken.length;
- int off = 0;
- if ( !MacOSXCGLContext.isLionOrLater ) {
- // no OpenGLProfile
- off++;
- len--;
- }
- int[] ivalues = new int[len];
+ static IntBuffer GLCapabilities2NSAttribList(IntBuffer attrToken, GLCapabilitiesImmutable caps, int ctp, int major, int minor) {
+ final int len = attrToken.remaining();
+ final int off = attrToken.position();
+ final IntBuffer ivalues = Buffers.newDirectIntBuffer(len);
for (int idx = 0; idx < len; idx++) {
- final int attr = cglInternalAttributeToken[idx+off];
+ final int attr = attrToken.get(idx+off);
switch (attr) {
case CGL.kCGLPFAOpenGLProfile:
- ivalues[idx] = MacOSXCGLContext.GLProfile2CGLOGLProfileValue(ctp, major, minor);
+ ivalues.put(idx, MacOSXCGLContext.GLProfile2CGLOGLProfileValue(ctp, major, minor));
break;
case CGL.NSOpenGLPFANoRecovery:
- ivalues[idx] = caps.getHardwareAccelerated() ? 1 : 0;
+ ivalues.put(idx, caps.getHardwareAccelerated() ? 1 : 0);
break;
case CGL.kCGLPFAColorFloat:
- ivalues[idx] = caps.getPbufferFloatingPointBuffers() ? 1 : 0;
+ ivalues.put(idx, ( !caps.isOnscreen() && caps.isPBuffer() && caps.getPbufferFloatingPointBuffers() ) ? 1 : 0);
break;
case CGL.NSOpenGLPFAPixelBuffer:
- ivalues[idx] = caps.isPBuffer() ? 1 : 0;
+ ivalues.put(idx, ( !caps.isOnscreen() && caps.isPBuffer() ) ? 1 : 0);
break;
case CGL.NSOpenGLPFADoubleBuffer:
- ivalues[idx] = (caps.getDoubleBuffered() ? 1 : 0);
+ ivalues.put(idx, (caps.getDoubleBuffered() ? 1 : 0));
break;
case CGL.NSOpenGLPFAStereo:
- ivalues[idx] = (caps.getStereo() ? 1 : 0);
+ ivalues.put(idx, (caps.getStereo() ? 1 : 0));
break;
case CGL.NSOpenGLPFAColorSize:
- ivalues[idx] = (caps.getRedBits() + caps.getGreenBits() + caps.getBlueBits());
+ ivalues.put(idx, (caps.getRedBits() + caps.getGreenBits() + caps.getBlueBits()));
break;
case CGL.NSOpenGLPFAAlphaSize:
- ivalues[idx] = caps.getAlphaBits();
+ ivalues.put(idx, caps.getAlphaBits());
break;
case CGL.NSOpenGLPFADepthSize:
- ivalues[idx] = caps.getDepthBits();
+ ivalues.put(idx, caps.getDepthBits());
break;
case CGL.NSOpenGLPFAAccumSize:
- ivalues[idx] = (caps.getAccumRedBits() + caps.getAccumGreenBits() + caps.getAccumBlueBits() + caps.getAccumAlphaBits());
+ ivalues.put(idx, (caps.getAccumRedBits() + caps.getAccumGreenBits() + caps.getAccumBlueBits() + caps.getAccumAlphaBits()));
break;
case CGL.NSOpenGLPFAStencilSize:
- ivalues[idx] = caps.getStencilBits();
+ ivalues.put(idx, caps.getStencilBits());
break;
case CGL.NSOpenGLPFASampleBuffers:
- ivalues[idx] = caps.getSampleBuffers() ? 1 : 0;
+ ivalues.put(idx, caps.getSampleBuffers() ? 1 : 0);
break;
case CGL.NSOpenGLPFASamples:
- ivalues[idx] = caps.getNumSamples() ;
+ ivalues.put(idx, caps.getNumSamples());
break;
default:
@@ -165,87 +155,88 @@ public class MacOSXCGLGraphicsConfiguration extends MutableGraphicsConfiguration
}
static long GLCapabilities2NSPixelFormat(GLCapabilitiesImmutable caps, int ctp, int major, int minor) {
- int len = cglInternalAttributeToken.length;
- int off = 0;
+ final IntBuffer attrToken = cglInternalAttributeToken.duplicate();
if ( !MacOSXCGLContext.isLionOrLater ) {
// no OpenGLProfile
- off++;
- len--;
+ attrToken.position(1);
}
- int[] ivalues = GLCapabilities2NSAttribList(caps, ctp, major, minor);
- return CGL.createPixelFormat(cglInternalAttributeToken, off, len, ivalues, 0);
+ final IntBuffer ivalues = GLCapabilities2NSAttribList(attrToken, caps, ctp, major, minor);
+ return CGL.createPixelFormat(attrToken, attrToken.remaining(), ivalues);
}
- static GLCapabilitiesImmutable NSPixelFormat2GLCapabilities(GLProfile glp, long pixelFormat) {
+ static GLCapabilities NSPixelFormat2GLCapabilities(GLProfile glp, long pixelFormat) {
return PixelFormat2GLCapabilities(glp, pixelFormat, true);
}
static long GLCapabilities2CGLPixelFormat(GLCapabilitiesImmutable caps, int ctp, int major, int minor) {
// Set up pixel format attributes
- int[] attrs = new int[256];
+ final IntBuffer attrs = Buffers.newDirectIntBuffer(256);
int i = 0;
if(MacOSXCGLContext.isLionOrLater) {
- attrs[i++] = CGL.kCGLPFAOpenGLProfile;
- attrs[i++] = MacOSXCGLContext.GLProfile2CGLOGLProfileValue(ctp, major, minor);
+ attrs.put(i++, CGL.kCGLPFAOpenGLProfile);
+ attrs.put(i++, MacOSXCGLContext.GLProfile2CGLOGLProfileValue(ctp, major, minor));
}
- if(caps.isPBuffer()) {
- attrs[i++] = CGL.kCGLPFAPBuffer;
- }
- if (caps.getPbufferFloatingPointBuffers()) {
- attrs[i++] = CGL.kCGLPFAColorFloat;
+ if(!caps.isOnscreen() && caps.isPBuffer()) {
+ attrs.put(i++, CGL.kCGLPFAPBuffer);
+ if (caps.getPbufferFloatingPointBuffers()) {
+ attrs.put(i++, CGL.kCGLPFAColorFloat);
+ }
}
if (caps.getDoubleBuffered()) {
- attrs[i++] = CGL.kCGLPFADoubleBuffer;
+ attrs.put(i++, CGL.kCGLPFADoubleBuffer);
}
if (caps.getStereo()) {
- attrs[i++] = CGL.kCGLPFAStereo;
+ attrs.put(i++, CGL.kCGLPFAStereo);
}
- attrs[i++] = CGL.kCGLPFAColorSize;
- attrs[i++] = (caps.getRedBits() +
- caps.getGreenBits() +
- caps.getBlueBits());
- attrs[i++] = CGL.kCGLPFAAlphaSize;
- attrs[i++] = caps.getAlphaBits();
- attrs[i++] = CGL.kCGLPFADepthSize;
- attrs[i++] = caps.getDepthBits();
+ attrs.put(i++, CGL.kCGLPFAColorSize);
+ attrs.put(i++, ( caps.getRedBits() +
+ caps.getGreenBits() +
+ caps.getBlueBits() ) );
+ attrs.put(i++, CGL.kCGLPFAAlphaSize);
+ attrs.put(i++, caps.getAlphaBits());
+ attrs.put(i++, CGL.kCGLPFADepthSize);
+ attrs.put(i++, caps.getDepthBits());
// FIXME: should validate stencil size as is done in MacOSXWindowSystemInterface.m
- attrs[i++] = CGL.kCGLPFAStencilSize;
- attrs[i++] = caps.getStencilBits();
- attrs[i++] = CGL.kCGLPFAAccumSize;
- attrs[i++] = (caps.getAccumRedBits() +
- caps.getAccumGreenBits() +
- caps.getAccumBlueBits() +
- caps.getAccumAlphaBits());
+ attrs.put(i++, CGL.kCGLPFAStencilSize);
+ attrs.put(i++, caps.getStencilBits());
+ attrs.put(i++, CGL.kCGLPFAAccumSize);
+ attrs.put(i++, ( caps.getAccumRedBits() +
+ caps.getAccumGreenBits() +
+ caps.getAccumBlueBits() +
+ caps.getAccumAlphaBits() ) );
if (caps.getSampleBuffers()) {
- attrs[i++] = CGL.kCGLPFASampleBuffers;
- attrs[i++] = 1;
- attrs[i++] = CGL.kCGLPFASamples;
- attrs[i++] = caps.getNumSamples();
+ attrs.put(i++, CGL.kCGLPFASampleBuffers);
+ attrs.put(i++, 1);
+ attrs.put(i++, CGL.kCGLPFASamples);
+ attrs.put(i++, caps.getNumSamples());
}
// Use attribute array to select pixel format
PointerBuffer fmt = PointerBuffer.allocateDirect(1);
- int[] numScreens = new int[1];
- int res = CGL.CGLChoosePixelFormat(attrs, 0, fmt, numScreens, 0);
+ IntBuffer numScreens = Buffers.newDirectIntBuffer(1);
+ int res = CGL.CGLChoosePixelFormat(attrs, fmt, numScreens);
if (res != CGL.kCGLNoError) {
throw new GLException("Error code " + res + " while choosing pixel format");
}
return fmt.get(0);
}
- static GLCapabilitiesImmutable CGLPixelFormat2GLCapabilities(long pixelFormat) {
+ static GLCapabilities CGLPixelFormat2GLCapabilities(long pixelFormat) {
return PixelFormat2GLCapabilities(null, pixelFormat, false);
}
- private static GLCapabilitiesImmutable PixelFormat2GLCapabilities(GLProfile glp, long pixelFormat, boolean nsUsage) {
- int len = cglInternalAttributeToken.length;
- int off = 0;
+ private static GLCapabilities PixelFormat2GLCapabilities(GLProfile glp, long pixelFormat, boolean nsUsage) {
+ final IntBuffer attrToken = cglInternalAttributeToken.duplicate();
+ final int off;
if ( !MacOSXCGLContext.isLionOrLater ) {
// no OpenGLProfile
- off++;
- len--;
+ off = 1;
+ } else {
+ off = 0;
}
- int[] ivalues = new int[len];
+ attrToken.position(off);
+ final int len = attrToken.remaining();
+ final IntBuffer ivalues = Buffers.newDirectIntBuffer(len);
// On this platform the pixel format is associated with the
// context and not the drawable. However it's a reasonable
@@ -256,15 +247,17 @@ public class MacOSXCGLGraphicsConfiguration extends MutableGraphicsConfiguration
// Figure out what attributes we really got
if(nsUsage) {
- CGL.queryPixelFormat(pixelFormat, cglInternalAttributeToken, off, len, ivalues, 0);
+ CGL.queryPixelFormat(pixelFormat, attrToken, len, ivalues);
} else {
- CGL.CGLQueryPixelFormat(pixelFormat, cglInternalAttributeToken, off, len, ivalues, 0);
+ CGL.CGLQueryPixelFormat(pixelFormat, attrToken, len, ivalues);
}
+
if(null == glp && MacOSXCGLContext.isLionOrLater) {
// pre-scan for OpenGL Profile
for (int i = 0; i < len; i++) {
- if(CGL.kCGLPFAOpenGLProfile == cglInternalAttributeToken[i+off]) {
- switch(ivalues[i]) {
+ final int ivalue = ivalues.get(i);
+ if(CGL.kCGLPFAOpenGLProfile == attrToken.get(i+off)) {
+ switch(ivalue) {
case CGL.kCGLOGLPVersion_3_2_Core:
glp = GLProfile.get(GLProfile.GL3);
break;
@@ -272,7 +265,7 @@ public class MacOSXCGLGraphicsConfiguration extends MutableGraphicsConfiguration
glp = GLProfile.get(GLProfile.GL2);
break;
default:
- throw new RuntimeException("Unhandled OSX OpenGL Profile: 0x"+Integer.toHexString(ivalues[i]));
+ throw new RuntimeException("Unhandled OSX OpenGL Profile: 0x"+Integer.toHexString(ivalue));
}
}
}
@@ -280,37 +273,35 @@ public class MacOSXCGLGraphicsConfiguration extends MutableGraphicsConfiguration
if(null == glp) {
glp = GLProfile.get(GLProfile.GL2);
}
- GLCapabilities caps = new GLCapabilities(glp);
+ final GLCapabilities caps = new GLCapabilities(glp);
int alphaBits = 0;
for (int i = 0; i < len; i++) {
- int attr = cglInternalAttributeToken[i+off];
+ final int attr = attrToken.get(i+off);
+ final int ivalue = ivalues.get(i);
switch (attr) {
case CGL.NSOpenGLPFAAccelerated:
- caps.setHardwareAccelerated(ivalues[i] != 0);
+ caps.setHardwareAccelerated(ivalue != 0);
break;
case CGL.kCGLPFAColorFloat:
- caps.setPbufferFloatingPointBuffers(ivalues[i] != 0);
+ caps.setPbufferFloatingPointBuffers(ivalue != 0);
break;
case CGL.NSOpenGLPFAPixelBuffer:
- caps.setPBuffer(ivalues[i] != 0);
+ caps.setPBuffer(ivalue != 0);
break;
case CGL.NSOpenGLPFADoubleBuffer:
- caps.setDoubleBuffered(ivalues[i] != 0);
+ caps.setDoubleBuffered(ivalue != 0);
break;
case CGL.NSOpenGLPFAStereo:
- caps.setStereo(ivalues[i] != 0);
+ caps.setStereo(ivalue != 0);
break;
case CGL.NSOpenGLPFAColorSize:
{
- int bitSize = ivalues[i];
- if (bitSize == 32)
- bitSize = 24;
- bitSize /= 3;
+ final int bitSize = ( 32 == ivalue ? 24 : ivalue ) / 3;
caps.setRedBits(bitSize);
caps.setGreenBits(bitSize);
caps.setBlueBits(bitSize);
@@ -319,16 +310,16 @@ public class MacOSXCGLGraphicsConfiguration extends MutableGraphicsConfiguration
case CGL.NSOpenGLPFAAlphaSize:
// ALPHA shall be set at last - due to it's auto setting by !opaque / samples
- alphaBits = ivalues[i];
+ alphaBits = ivalue;
break;
case CGL.NSOpenGLPFADepthSize:
- caps.setDepthBits(ivalues[i]);
+ caps.setDepthBits(ivalue);
break;
case CGL.NSOpenGLPFAAccumSize:
{
- int bitSize = ivalues[i] / 4;
+ final int bitSize = ivalue / 4;
caps.setAccumRedBits(bitSize);
caps.setAccumGreenBits(bitSize);
caps.setAccumBlueBits(bitSize);
@@ -337,15 +328,15 @@ public class MacOSXCGLGraphicsConfiguration extends MutableGraphicsConfiguration
break;
case CGL.NSOpenGLPFAStencilSize:
- caps.setStencilBits(ivalues[i]);
+ caps.setStencilBits(ivalue);
break;
case CGL.NSOpenGLPFASampleBuffers:
- caps.setSampleBuffers(ivalues[i] != 0);
+ caps.setSampleBuffers(ivalue != 0);
break;
case CGL.NSOpenGLPFASamples:
- caps.setNumSamples(ivalues[i]);
+ caps.setNumSamples(ivalue);
break;
default:
@@ -353,7 +344,7 @@ public class MacOSXCGLGraphicsConfiguration extends MutableGraphicsConfiguration
}
}
caps.setAlphaBits(alphaBits);
-
+
return caps;
}
}
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java
index f138e75..3bbba2c 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java
@@ -34,13 +34,17 @@
package jogamp.opengl.macosx.cgl;
import jogamp.opengl.GLGraphicsConfigurationFactory;
+import jogamp.opengl.GLGraphicsConfigurationUtil;
+
import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.AbstractGraphicsScreen;
import javax.media.nativewindow.CapabilitiesChooser;
import javax.media.nativewindow.CapabilitiesImmutable;
import javax.media.nativewindow.GraphicsConfigurationFactory;
import javax.media.opengl.GLCapabilitiesChooser;
import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLDrawableFactory;
/** Subclass of GraphicsConfigurationFactory used when non-AWT tookits
@@ -58,13 +62,7 @@ public class MacOSXCGLGraphicsConfigurationFactory extends GLGraphicsConfigurati
protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl(
CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested,
CapabilitiesChooser chooser, AbstractGraphicsScreen absScreen, int nativeVisualID) {
- return chooseGraphicsConfigurationStatic(capsChosen, capsRequested, chooser, absScreen, false);
- }
-
- static MacOSXCGLGraphicsConfiguration chooseGraphicsConfigurationStatic(CapabilitiesImmutable capsChosen,
- CapabilitiesImmutable capsRequested,
- CapabilitiesChooser chooser,
- AbstractGraphicsScreen absScreen, boolean usePBuffer) {
+
if (absScreen == null) {
throw new IllegalArgumentException("AbstractGraphicsScreen is null");
}
@@ -77,11 +75,23 @@ public class MacOSXCGLGraphicsConfigurationFactory extends GLGraphicsConfigurati
throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilities objects - requested");
}
- if (chooser != null &&
- !(chooser instanceof GLCapabilitiesChooser)) {
+ if (chooser != null && !(chooser instanceof GLCapabilitiesChooser)) {
throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilitiesChooser objects");
}
+
+ return chooseGraphicsConfigurationStatic((GLCapabilitiesImmutable)capsChosen, (GLCapabilitiesImmutable)capsRequested, (GLCapabilitiesChooser)chooser, absScreen, false);
+ }
- return new MacOSXCGLGraphicsConfiguration(absScreen, (GLCapabilitiesImmutable)capsChosen, (GLCapabilitiesImmutable)capsRequested, 0);
+ static MacOSXCGLGraphicsConfiguration chooseGraphicsConfigurationStatic(GLCapabilitiesImmutable capsChosen,
+ GLCapabilitiesImmutable capsRequested,
+ GLCapabilitiesChooser chooser,
+ AbstractGraphicsScreen absScreen, boolean usePBuffer) {
+ if (absScreen == null) {
+ throw new IllegalArgumentException("AbstractGraphicsScreen is null");
+ }
+ final AbstractGraphicsDevice device = absScreen.getDevice();
+ capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( capsChosen, GLDrawableFactory.getDesktopFactory(), device);
+
+ return new MacOSXCGLGraphicsConfiguration(absScreen, (GLCapabilitiesImmutable)capsChosen, (GLCapabilitiesImmutable)capsRequested);
}
}
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java
index 6be9e38..65ed5fc 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java
@@ -49,8 +49,8 @@ import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
-import com.jogamp.nativewindow.WrappedSurface;
+import jogamp.nativewindow.WrappedSurface;
import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLContextShareSet;
import jogamp.opengl.macosx.cgl.MacOSXCGLDrawable.GLBackendType;
@@ -62,7 +62,6 @@ public class MacOSXExternalCGLContext extends MacOSXCGLContext {
private MacOSXExternalCGLContext(Drawable drawable, boolean isNSContext, long handle) {
super(drawable, null);
setOpenGLMode(isNSContext ? GLBackendType.NSOPENGL : GLBackendType.CGL );
- drawable.registerContext(this);
this.contextHandle = handle;
GLContextShareSet.contextCreated(this);
setGLFunctionAvailability(false, 0, 0, CTX_PROFILE_COMPAT);
@@ -108,13 +107,13 @@ public class MacOSXExternalCGLContext extends MacOSXCGLContext {
}
AbstractGraphicsScreen aScreen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_MACOSX);
- MacOSXCGLGraphicsConfiguration cfg = new MacOSXCGLGraphicsConfiguration(aScreen, caps, caps, pixelFormat);
+ MacOSXCGLGraphicsConfiguration cfg = new MacOSXCGLGraphicsConfiguration(aScreen, caps, caps);
if(0 == currentDrawable) {
// set a fake marker stating a valid drawable
currentDrawable = 1;
}
- WrappedSurface ns = new WrappedSurface(cfg, currentDrawable, 64, 64, null);
+ WrappedSurface ns = new WrappedSurface(cfg, currentDrawable, 64, 64, true);
return new MacOSXExternalCGLContext(new Drawable(factory, ns), isNSContext, contextHandle);
}
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLContext.java
index e344fd4..447d18f 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLContext.java
@@ -39,6 +39,8 @@
package jogamp.opengl.macosx.cgl;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.ProxySurface;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLException;
@@ -60,7 +62,7 @@ public class MacOSXOnscreenCGLContext extends MacOSXCGLContext {
@Override
protected void drawableUpdatedNotify() throws GLException {
final int w = drawable.getWidth();
- final int h = drawable.getHeight();
+ final int h = drawable.getHeight();
final boolean updateContext = ( 0!=updateHandle && CGL.updateContextNeedsUpdate(updateHandle) ) ||
w != lastWidth || h != lastHeight;
if(updateContext) {
@@ -82,9 +84,18 @@ public class MacOSXOnscreenCGLContext extends MacOSXCGLContext {
if(0 != updateHandle) {
throw new InternalError("XXX1");
}
- updateHandle = CGL.updateContextRegister(contextHandle, drawable.getHandle());
- if(0 == updateHandle) {
- throw new InternalError("XXX2");
+ final boolean incompleteView;
+ final NativeSurface surface = drawable.getNativeSurface();
+ if( surface instanceof ProxySurface ) {
+ incompleteView = ((ProxySurface)surface).containsUpstreamOptionBits( ProxySurface.OPT_UPSTREAM_WINDOW_INVISIBLE );
+ } else {
+ incompleteView = false;
+ }
+ if(!incompleteView) {
+ updateHandle = CGL.updateContextRegister(contextHandle, drawable.getHandle());
+ if(0 == updateHandle) {
+ throw new InternalError("XXX2");
+ }
}
}
return res;
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLDrawable.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLDrawable.java
index b1e283e..ec96280 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLDrawable.java
@@ -52,9 +52,7 @@ public class MacOSXOnscreenCGLDrawable extends MacOSXCGLDrawable {
@Override
public GLContext createContext(GLContext shareWith) {
- final MacOSXOnscreenCGLContext ctx= new MacOSXOnscreenCGLContext(this, shareWith);
- registerContext(ctx);
- return ctx;
+ return new MacOSXOnscreenCGLContext(this, shareWith);
}
}
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLContext.java
index 88886dd..7e2d8cf 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLContext.java
@@ -39,6 +39,7 @@ import javax.media.opengl.GLPbuffer;
import jogamp.opengl.GLContextImpl;
+ at SuppressWarnings("deprecation")
public class MacOSXPbufferCGLContext extends MacOSXCGLContext {
// State for render-to-texture and render-to-texture-rectangle support
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java
index 8f2f386..668e463 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java
@@ -40,6 +40,8 @@
package jogamp.opengl.macosx.cgl;
+import java.lang.ref.WeakReference;
+
import javax.media.nativewindow.DefaultGraphicsConfiguration;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.MutableSurface;
@@ -70,9 +72,6 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable {
// private int textureTarget; // e.g. GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE_NV
// private int texture; // actual texture object
- // Note that we can not store this in the NativeSurface because the
- // semantic is that contains an NSView
- protected long pBuffer;
protected int pBufferTexTarget, pBufferTexWidth, pBufferTexHeight;
public MacOSXPbufferCGLDrawable(GLDrawableFactory factory, NativeSurface target) {
@@ -90,9 +89,7 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable {
@Override
public GLContext createContext(GLContext shareWith) {
- final MacOSXPbufferCGLContext ctx = new MacOSXPbufferCGLContext(this, shareWith);
- registerContext(ctx);
- return ctx;
+ return new MacOSXPbufferCGLContext(this, shareWith);
}
@Override
@@ -101,27 +98,34 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable {
return 0;
}
- @Override
- public long getHandle() {
- return pBuffer;
- }
-
protected int getTextureTarget() { return pBufferTexTarget; }
protected int getTextureWidth() { return pBufferTexWidth; }
protected int getTextureHeight() { return pBufferTexHeight; }
protected void destroyPbuffer() {
- if (this.pBuffer != 0) {
- NativeSurface ns = getNativeSurface();
+ final MutableSurface ms = (MutableSurface) getNativeSurface();
+ final long pBuffer = ms.getSurfaceHandle();
+ if (0 != pBuffer) {
+ synchronized (createdContexts) {
+ for(int i=0; i<createdContexts.size(); ) {
+ final WeakReference<MacOSXCGLContext> ref = createdContexts.get(i);
+ final MacOSXCGLContext ctx = ref.get();
+ if (ctx != null) {
+ ctx.detachPBuffer();
+ i++;
+ } else {
+ createdContexts.remove(i);
+ }
+ }
+ }
impl.destroy(pBuffer);
- this.pBuffer = 0;
- ((MutableSurface)ns).setSurfaceHandle(0);
+ ms.setSurfaceHandle(0);
}
}
private void createPbuffer() {
- final NativeSurface ns = getNativeSurface();
- final DefaultGraphicsConfiguration config = (DefaultGraphicsConfiguration) ns.getGraphicsConfiguration();
+ final MutableSurface ms = (MutableSurface) getNativeSurface();
+ final DefaultGraphicsConfiguration config = (DefaultGraphicsConfiguration) ms.getGraphicsConfiguration();
final GLCapabilitiesImmutable capabilities = (GLCapabilitiesImmutable)config.getChosenCapabilities();
final GLProfile glProfile = capabilities.getGLProfile();
MacOSXCGLDrawableFactory.SharedResource sr = ((MacOSXCGLDrawableFactory)factory).getOrCreateOSXSharedResource(config.getScreen().getDevice());
@@ -161,7 +165,7 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable {
}
}
- pBuffer = impl.create(pBufferTexTarget, internalFormat, getWidth(), getHeight());
+ final long pBuffer = impl.create(pBufferTexTarget, internalFormat, getWidth(), getHeight());
if(DEBUG) {
System.err.println("MacOSXPbufferCGLDrawable tex: target "+toHexString(pBufferTexTarget)+
", pbufferSize "+getWidth()+"x"+getHeight()+
@@ -174,7 +178,7 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable {
throw new GLException("pbuffer creation error: CGL.createPBuffer() failed");
}
- ((MutableSurface)ns).setSurfaceHandle(pBuffer);
+ ms.setSurfaceHandle(pBuffer);
}
@Override
diff --git a/src/jogl/classes/jogamp/opengl/shader/texture01_xxx.fp b/src/jogl/classes/jogamp/opengl/shader/texture01_xxx.fp
new file mode 100644
index 0000000..8b30b65
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/shader/texture01_xxx.fp
@@ -0,0 +1,19 @@
+// Copyright 2012 JogAmp Community. All rights reserved.
+
+#if __VERSION__ >= 130
+ #define varying in
+ out vec4 mgl_FragColor;
+ #define texture2D texture
+#else
+ #define mgl_FragColor gl_FragColor
+#endif
+
+varying vec2 mgl_texCoord;
+
+uniform sampler2D mgl_Texture0;
+
+void main (void)
+{
+ mgl_FragColor = texture2D(mgl_Texture0, mgl_texCoord);
+}
+
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texture01_xxx.vp b/src/jogl/classes/jogamp/opengl/shader/texture01_xxx.vp
similarity index 64%
copy from src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texture01_xxx.vp
copy to src/jogl/classes/jogamp/opengl/shader/texture01_xxx.vp
index c521e37..d9ef6b4 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texture01_xxx.vp
+++ b/src/jogl/classes/jogamp/opengl/shader/texture01_xxx.vp
@@ -1,17 +1,19 @@
// Copyright 2012 JogAmp Community. All rights reserved.
+#if __VERSION__ >= 130
+ #define attribute in
+ #define varying out
+#endif
+
uniform mat4 mgl_PMVMatrix[2];
-// uniform mat4 mgl_STMatrix;
+
attribute vec4 mgl_Vertex;
-attribute vec4 mgl_Color;
attribute vec4 mgl_MultiTexCoord;
-varying vec4 frontColor;
+
varying vec2 mgl_texCoord;
void main(void)
{
- frontColor=mgl_Color;
- // mgl_texCoord = (mgl_STMatrix * mgl_MultiTexCoord).st;
mgl_texCoord = mgl_MultiTexCoord.st;
gl_Position = mgl_PMVMatrix[0] * mgl_PMVMatrix[1] * mgl_Vertex;
}
diff --git a/src/jogl/classes/jogamp/opengl/util/GLArrayHandler.java b/src/jogl/classes/jogamp/opengl/util/GLArrayHandler.java
index 22690b0..a6314a2 100644
--- a/src/jogl/classes/jogamp/opengl/util/GLArrayHandler.java
+++ b/src/jogl/classes/jogamp/opengl/util/GLArrayHandler.java
@@ -37,18 +37,29 @@ import javax.media.opengl.*;
*/
public interface GLArrayHandler {
+
/**
- * Implementation shall associate the data with the array
- * and synchronize the data with the GPU.
+ * if <code>bind</code> is true and the data uses VBO,
+ * the latter will be bound and data written to the GPU if required.
+ * <p>
+ * If <code>bind</code> is false and the data uses VBO,
+ * the latter will be unbound.
+ * </p>
*
* @param gl current GL object
- * @param enable true if array data shall be valid, otherwise false.
- * @param ext extension object allowing passing of an implementation detail
+ * @param bind true if VBO shall be bound and data written,
+ * otherwise clear VBO binding.
+ * @return true if data uses VBO and action was performed, otherwise false
*/
- public void syncData(GL gl, boolean enable, Object ext);
+ public boolean bindBuffer(GL gl, boolean bind);
/**
* Implementation shall enable or disable the array state.
+ * <p>
+ * Before enabling the array state,
+ * implementation shall synchronize the data with the GPU
+ * and associate the data with the array.
+ * </p>
*
* @param gl current GL object
* @param enable true if array shall be enabled, otherwise false.
diff --git a/src/jogl/classes/jogamp/opengl/util/GLArrayHandlerFlat.java b/src/jogl/classes/jogamp/opengl/util/GLArrayHandlerFlat.java
index dca9129..4a8f406 100644
--- a/src/jogl/classes/jogamp/opengl/util/GLArrayHandlerFlat.java
+++ b/src/jogl/classes/jogamp/opengl/util/GLArrayHandlerFlat.java
@@ -41,11 +41,9 @@ public interface GLArrayHandlerFlat {
* Implementation shall associate the data with the array
*
* @param gl current GL object
- * @param enable true if array data shall be valid, otherwise false.
- * @param force true force data association, bypassing optimization
* @param ext extension object allowing passing of an implementation detail
*/
- public void syncData(GL gl, boolean enable, boolean force, Object ext);
+ public void syncData(GL gl, Object ext);
/**
* Implementation shall enable or disable the array state.
diff --git a/src/jogl/classes/jogamp/opengl/util/GLArrayHandlerInterleaved.java b/src/jogl/classes/jogamp/opengl/util/GLArrayHandlerInterleaved.java
index d31b415..98f711b 100644
--- a/src/jogl/classes/jogamp/opengl/util/GLArrayHandlerInterleaved.java
+++ b/src/jogl/classes/jogamp/opengl/util/GLArrayHandlerInterleaved.java
@@ -28,8 +28,6 @@
package jogamp.opengl.util;
-
-import java.nio.Buffer;
import java.util.ArrayList;
import java.util.List;
@@ -41,12 +39,11 @@ import com.jogamp.opengl.util.GLArrayDataEditable;
* Interleaved fixed function arrays, i.e. where this buffer data
* represents many arrays.
*/
-public class GLArrayHandlerInterleaved implements GLArrayHandler {
- private GLArrayDataEditable ad;
+public class GLArrayHandlerInterleaved extends GLVBOArrayHandler implements GLArrayHandler {
private List<GLArrayHandlerFlat> subArrays = new ArrayList<GLArrayHandlerFlat>();
public GLArrayHandlerInterleaved(GLArrayDataEditable ad) {
- this.ad = ad;
+ super(ad);
}
public final void setSubArrayVBOName(int vboName) {
@@ -59,37 +56,20 @@ public class GLArrayHandlerInterleaved implements GLArrayHandler {
subArrays.add(handler);
}
- private final void syncSubData(GL gl, boolean enable, boolean force, Object ext) {
+ private final void syncSubData(GL gl, Object ext) {
for(int i=0; i<subArrays.size(); i++) {
- subArrays.get(i).syncData(gl, enable, force, ext);
+ subArrays.get(i).syncData(gl, ext);
}
}
- public final void syncData(GL gl, boolean enable, Object ext) {
+ public final void enableState(GL gl, boolean enable, Object ext) {
if(enable) {
- final Buffer buffer = ad.getBuffer();
-
- if(ad.isVBO()) {
- // always bind and refresh the VBO mgr,
- // in case more than one gl*Pointer objects are in use
- gl.glBindBuffer(ad.getVBOTarget(), ad.getVBOName());
- if(!ad.isVBOWritten()) {
- if(null!=buffer) {
- gl.glBufferData(ad.getVBOTarget(), buffer.limit() * ad.getComponentSizeInBytes(), buffer, ad.getVBOUsage());
- }
- ad.setVBOWritten(true);
- }
- }
- syncSubData(gl, true, true, ext);
- } else {
- syncSubData(gl, false, true, ext);
- if(ad.isVBO()) {
- gl.glBindBuffer(ad.getVBOTarget(), 0);
- }
+ final boolean vboBound = bindBuffer(gl, true);
+ syncSubData(gl, ext);
+ if(vboBound) {
+ bindBuffer(gl, false);
+ }
}
- }
-
- public final void enableState(GL gl, boolean enable, Object ext) {
for(int i=0; i<subArrays.size(); i++) {
subArrays.get(i).enableState(gl, enable, ext);
}
diff --git a/src/jogl/classes/jogamp/opengl/util/GLDataArrayHandler.java b/src/jogl/classes/jogamp/opengl/util/GLDataArrayHandler.java
index 6c8e2e7..862d49d 100644
--- a/src/jogl/classes/jogamp/opengl/util/GLDataArrayHandler.java
+++ b/src/jogl/classes/jogamp/opengl/util/GLDataArrayHandler.java
@@ -28,21 +28,20 @@
package jogamp.opengl.util;
-import javax.media.opengl.*;
+import javax.media.opengl.GL;
+import javax.media.opengl.GLException;
-import com.jogamp.opengl.util.*;
+import com.jogamp.opengl.util.GLArrayDataEditable;
-import java.nio.*;
/**
* Used for pure VBO data arrays, i.e. where the buffer data
* does not represents a specific array name.
*/
-public class GLDataArrayHandler implements GLArrayHandler {
- private GLArrayDataEditable ad;
+public class GLDataArrayHandler extends GLVBOArrayHandler implements GLArrayHandler {
public GLDataArrayHandler(GLArrayDataEditable ad) {
- this.ad = ad;
+ super(ad);
}
public final void setSubArrayVBOName(int vboName) {
@@ -53,30 +52,16 @@ public class GLDataArrayHandler implements GLArrayHandler {
throw new UnsupportedOperationException();
}
- public final void syncData(GL gl, boolean enable, Object ext) {
- if(!ad.isVBO()) {
- // makes no sense otherwise
- throw new GLException("GLDataArrayHandler can only handle VBOs.");
- }
+ public final void enableState(GL gl, boolean enable, Object ext) {
if(enable) {
- Buffer buffer = ad.getBuffer();
-
- // always bind and refresh the VBO mgr,
- // in case more than one gl*Pointer objects are in use
- gl.glBindBuffer(ad.getVBOTarget(), ad.getVBOName());
- if(!ad.isVBOWritten()) {
- if(null!=buffer) {
- gl.glBufferData(ad.getVBOTarget(), buffer.limit() * ad.getComponentSizeInBytes(), buffer, ad.getVBOUsage());
- }
- ad.setVBOWritten(true);
+ if(!ad.isVBO()) {
+ // makes no sense otherwise
+ throw new GLException("GLDataArrayHandler can only handle VBOs.");
}
- } else {
- gl.glBindBuffer(ad.getVBOTarget(), 0);
- }
- }
-
- public final void enableState(GL gl, boolean enable, Object ext) {
- // no array association
+ bindBuffer(gl, true);
+ bindBuffer(gl, false);
+ }
+ // no array association
}
}
diff --git a/src/jogl/classes/jogamp/opengl/util/GLFixedArrayHandler.java b/src/jogl/classes/jogamp/opengl/util/GLFixedArrayHandler.java
index d8939dc..32bba89 100644
--- a/src/jogl/classes/jogamp/opengl/util/GLFixedArrayHandler.java
+++ b/src/jogl/classes/jogamp/opengl/util/GLFixedArrayHandler.java
@@ -28,22 +28,19 @@
package jogamp.opengl.util;
-import javax.media.opengl.*;
-import javax.media.opengl.fixedfunc.*;
+import javax.media.opengl.GL;
+import javax.media.opengl.GLException;
+import javax.media.opengl.fixedfunc.GLPointerFunc;
import com.jogamp.opengl.util.GLArrayDataEditable;
-import java.nio.*;
-
/**
* Used for 1:1 fixed function arrays, i.e. where the buffer data
* represents this array only.
*/
-public class GLFixedArrayHandler implements GLArrayHandler {
- private GLArrayDataEditable ad;
-
+public class GLFixedArrayHandler extends GLVBOArrayHandler implements GLArrayHandler {
public GLFixedArrayHandler(GLArrayDataEditable ad) {
- this.ad = ad;
+ super(ad);
}
public final void setSubArrayVBOName(int vboName) {
@@ -54,21 +51,10 @@ public class GLFixedArrayHandler implements GLArrayHandler {
throw new UnsupportedOperationException();
}
- public final void syncData(GL gl, boolean enable, Object ext) {
+ public final void enableState(GL gl, boolean enable, Object ext) {
+ final GLPointerFunc glp = gl.getGL2ES1();
if(enable) {
- final Buffer buffer = ad.getBuffer();
- if(ad.isVBO()) {
- // always bind and refresh the VBO mgr,
- // in case more than one gl*Pointer objects are in use
- gl.glBindBuffer(ad.getVBOTarget(), ad.getVBOName());
- if(!ad.isVBOWritten()) {
- if(null!=buffer) {
- gl.glBufferData(ad.getVBOTarget(), buffer.limit() * ad.getComponentSizeInBytes(), buffer, ad.getVBOUsage());
- }
- ad.setVBOWritten(true);
- }
- }
- final GLPointerFunc glp = gl.getGL2ES1();
+ final boolean vboBound = bindBuffer(gl, true);
switch(ad.getIndex()) {
case GLPointerFunc.GL_VERTEX_ARRAY:
glp.glVertexPointer(ad);
@@ -85,14 +71,9 @@ public class GLFixedArrayHandler implements GLArrayHandler {
default:
throw new GLException("invalid glArrayIndex: "+ad.getIndex()+":\n\t"+ad);
}
- } else if(ad.isVBO()) {
- gl.glBindBuffer(ad.getVBOTarget(), 0);
- }
- }
-
- public final void enableState(GL gl, boolean enable, Object ext) {
- final GLPointerFunc glp = gl.getGL2ES1();
- if(enable) {
+ if(vboBound) {
+ bindBuffer(gl, false);
+ }
glp.glEnableClientState(ad.getIndex());
} else {
glp.glDisableClientState(ad.getIndex());
diff --git a/src/jogl/classes/jogamp/opengl/util/GLFixedArrayHandlerFlat.java b/src/jogl/classes/jogamp/opengl/util/GLFixedArrayHandlerFlat.java
index 2937cc7..ff1813b 100644
--- a/src/jogl/classes/jogamp/opengl/util/GLFixedArrayHandlerFlat.java
+++ b/src/jogl/classes/jogamp/opengl/util/GLFixedArrayHandlerFlat.java
@@ -49,25 +49,23 @@ public class GLFixedArrayHandlerFlat implements GLArrayHandlerFlat {
return ad;
}
- public final void syncData(GL gl, boolean enable, boolean force, Object ext) {
- if(enable) {
- final GLPointerFunc glp = gl.getGL2ES1();
- switch(ad.getIndex()) {
- case GLPointerFunc.GL_VERTEX_ARRAY:
- glp.glVertexPointer(ad);
- break;
- case GLPointerFunc.GL_NORMAL_ARRAY:
- glp.glNormalPointer(ad);
- break;
- case GLPointerFunc.GL_COLOR_ARRAY:
- glp.glColorPointer(ad);
- break;
- case GLPointerFunc.GL_TEXTURE_COORD_ARRAY:
- glp.glTexCoordPointer(ad);
- break;
- default:
- throw new GLException("invalid glArrayIndex: "+ad.getIndex()+":\n\t"+ad);
- }
+ public final void syncData(GL gl, Object ext) {
+ final GLPointerFunc glp = gl.getGL2ES1();
+ switch(ad.getIndex()) {
+ case GLPointerFunc.GL_VERTEX_ARRAY:
+ glp.glVertexPointer(ad);
+ break;
+ case GLPointerFunc.GL_NORMAL_ARRAY:
+ glp.glNormalPointer(ad);
+ break;
+ case GLPointerFunc.GL_COLOR_ARRAY:
+ glp.glColorPointer(ad);
+ break;
+ case GLPointerFunc.GL_TEXTURE_COORD_ARRAY:
+ glp.glTexCoordPointer(ad);
+ break;
+ default:
+ throw new GLException("invalid glArrayIndex: "+ad.getIndex()+":\n\t"+ad);
}
}
diff --git a/src/jogl/classes/jogamp/opengl/util/GLDataArrayHandler.java b/src/jogl/classes/jogamp/opengl/util/GLVBOArrayHandler.java
similarity index 69%
copy from src/jogl/classes/jogamp/opengl/util/GLDataArrayHandler.java
copy to src/jogl/classes/jogamp/opengl/util/GLVBOArrayHandler.java
index 6c8e2e7..ad88a70 100644
--- a/src/jogl/classes/jogamp/opengl/util/GLDataArrayHandler.java
+++ b/src/jogl/classes/jogamp/opengl/util/GLVBOArrayHandler.java
@@ -28,43 +28,36 @@
package jogamp.opengl.util;
-import javax.media.opengl.*;
-import com.jogamp.opengl.util.*;
+import java.nio.Buffer;
+import java.util.ArrayList;
+import java.util.List;
-import java.nio.*;
+import javax.media.opengl.GL;
+
+import com.jogamp.opengl.util.GLArrayDataEditable;
/**
- * Used for pure VBO data arrays, i.e. where the buffer data
- * does not represents a specific array name.
+ * Interleaved fixed function arrays, i.e. where this buffer data
+ * represents many arrays.
*/
-public class GLDataArrayHandler implements GLArrayHandler {
- private GLArrayDataEditable ad;
+public abstract class GLVBOArrayHandler implements GLArrayHandler {
+ protected GLArrayDataEditable ad;
- public GLDataArrayHandler(GLArrayDataEditable ad) {
+ public GLVBOArrayHandler(GLArrayDataEditable ad) {
this.ad = ad;
}
-
- public final void setSubArrayVBOName(int vboName) {
- throw new UnsupportedOperationException();
- }
-
- public final void addSubHandler(GLArrayHandlerFlat handler) {
- throw new UnsupportedOperationException();
- }
- public final void syncData(GL gl, boolean enable, Object ext) {
- if(!ad.isVBO()) {
- // makes no sense otherwise
- throw new GLException("GLDataArrayHandler can only handle VBOs.");
+ public final boolean bindBuffer(GL gl, boolean bind) {
+ if( !ad.isVBO() ) {
+ return false;
}
- if(enable) {
- Buffer buffer = ad.getBuffer();
-
+ if(bind) {
// always bind and refresh the VBO mgr,
// in case more than one gl*Pointer objects are in use
gl.glBindBuffer(ad.getVBOTarget(), ad.getVBOName());
if(!ad.isVBOWritten()) {
+ final Buffer buffer = ad.getBuffer();
if(null!=buffer) {
gl.glBufferData(ad.getVBOTarget(), buffer.limit() * ad.getComponentSizeInBytes(), buffer, ad.getVBOUsage());
}
@@ -72,11 +65,9 @@ public class GLDataArrayHandler implements GLArrayHandler {
}
} else {
gl.glBindBuffer(ad.getVBOTarget(), 0);
- }
+ }
+ return true;
}
- public final void enableState(GL gl, boolean enable, Object ext) {
- // no array association
- }
}
diff --git a/src/jogl/classes/jogamp/opengl/util/av/EGLMediaPlayerImpl.java b/src/jogl/classes/jogamp/opengl/util/av/EGLMediaPlayerImpl.java
index 6bf8839..274ccff 100644
--- a/src/jogl/classes/jogamp/opengl/util/av/EGLMediaPlayerImpl.java
+++ b/src/jogl/classes/jogamp/opengl/util/av/EGLMediaPlayerImpl.java
@@ -125,12 +125,12 @@ public abstract class EGLMediaPlayerImpl extends GLMediaPlayerImpl {
}
if(useKHRSync) {
- int[] tmp = new int[1];
+ IntBuffer tmp = Buffers.newDirectIntBuffer(1);
// Create sync object so that we can be sure that gl has finished
// rendering the EGLImage texture before we tell OpenMAX to fill
// it with a new frame.
- tmp[0] = EGL.EGL_NONE;
- sync = eglExt.eglCreateSyncKHR(eglDrawable.getNativeSurface().getDisplayHandle(), EGLExt.EGL_SYNC_FENCE_KHR, tmp, 0);
+ tmp.put(0, EGL.EGL_NONE);
+ sync = eglExt.eglCreateSyncKHR(eglDrawable.getNativeSurface().getDisplayHandle(), EGLExt.EGL_SYNC_FENCE_KHR, tmp);
if (0==sync) {
throw new RuntimeException("EGLSync creation failed: "+EGL.eglGetError()+", ctx "+eglCtx+", err "+toHexString(EGL.eglGetError()));
}
diff --git a/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java b/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java
index d3d45e6..27c9267 100644
--- a/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java
+++ b/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java
@@ -62,6 +62,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
protected int textureCount;
protected int textureTarget;
protected int textureFormat;
+ protected int textureInternalFormat;
protected int textureType;
protected int texUnit;
@@ -104,6 +105,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
this.textureCount=3;
this.textureTarget=GL.GL_TEXTURE_2D;
this.textureFormat = GL.GL_RGBA;
+ this.textureInternalFormat = GL.GL_RGBA;
this.textureType = GL.GL_UNSIGNED_BYTE;
this.texUnit = 0;
this.state = State.Uninitialized;
@@ -122,7 +124,10 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
public final int getTextureCount() { return textureCount; }
protected final void setTextureTarget(int target) { textureTarget=target; }
- protected final void setTextureFormat(int f) { textureFormat=f; }
+ protected final void setTextureFormat(int internalFormat, int format) {
+ textureInternalFormat=internalFormat;
+ textureFormat=format;
+ }
protected final void setTextureType(int t) { textureType=t; }
public final void setTextureMinMagFilter(int[] minMagFilter) { texMinMagFilter[0] = minMagFilter[0]; texMinMagFilter[1] = minMagFilter[1];}
@@ -361,9 +366,9 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
gl.glTexImage2D(
textureTarget, // target
0, // level
- GL.GL_RGBA, // internal format
- tWidth, // width
- tHeight, // height
+ textureInternalFormat, // internal format
+ tWidth, // width
+ tHeight, // height
0, // border
textureFormat,
textureType,
diff --git a/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGDynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGDynamicLibraryBundleInfo.java
index ce9df21..32c8635 100644
--- a/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGDynamicLibraryBundleInfo.java
+++ b/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGDynamicLibraryBundleInfo.java
@@ -222,6 +222,11 @@ class FFMPEGDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo {
final List<String> avutil = new ArrayList<String>();
avutil.add("avutil"); // default
+
+ avutil.add("libavutil.so.52"); // dummy future proof
+ avutil.add("libavutil.so.51"); // 0.8
+ avutil.add("libavutil.so.50"); // 0.7
+
avutil.add("avutil-52"); // dummy future proof
avutil.add("avutil-51"); // 0.8
avutil.add("avutil-50"); // 0.7
@@ -229,6 +234,12 @@ class FFMPEGDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo {
final List<String> avformat = new ArrayList<String>();
avformat.add("avformat"); // default
+
+ avformat.add("libavformat.so.55"); // dummy future proof
+ avformat.add("libavformat.so.54"); // 0.?
+ avformat.add("libavformat.so.53"); // 0.8
+ avformat.add("libavformat.so.52"); // 0.7
+
avformat.add("avformat-55"); // dummy future proof
avformat.add("avformat-54"); // 0.?
avformat.add("avformat-53"); // 0.8
@@ -237,6 +248,12 @@ class FFMPEGDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo {
final List<String> avcodec = new ArrayList<String>();
avcodec.add("avcodec"); // default
+
+ avcodec.add("libavcodec.so.55"); // dummy future proof
+ avcodec.add("libavcodec.so.54"); // 0.?
+ avcodec.add("libavcodec.so.53"); // 0.8
+ avcodec.add("libavcodec.so.52"); // 0.7
+
avcodec.add("avcodec-55"); // dummy future proof
avcodec.add("avcodec-54"); // 0.?
avcodec.add("avcodec-53"); // 0.8
diff --git a/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGMediaPlayer.java b/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGMediaPlayer.java
index 7d10cff..4be2bcb 100644
--- a/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGMediaPlayer.java
+++ b/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGMediaPlayer.java
@@ -192,14 +192,14 @@ public class FFMPEGMediaPlayer extends EGLMediaPlayerImpl {
System.out.println("setURL: p1 "+this);
setStream0(moviePtr, urlS, -1, -1);
System.out.println("setURL: p2 "+this);
- int tf;
+ int tf, tif=GL.GL_RGBA; // texture format and internal format
switch(vBytesPerPixelPerPlane) {
- case 1: tf = GL2ES2.GL_RED; break;
- case 3: tf = GL2ES2.GL_RGB; break;
- case 4: tf = GL2ES2.GL_RGBA; break;
+ case 1: tf = GL2ES2.GL_ALPHA; tif=GL.GL_ALPHA; break;
+ case 3: tf = GL2ES2.GL_RGB; tif=GL.GL_RGB; break;
+ case 4: tf = GL2ES2.GL_RGBA; tif=GL.GL_RGBA; break;
default: throw new RuntimeException("Unsupported bytes-per-pixel / plane "+vBytesPerPixelPerPlane);
}
- setTextureFormat(tf);
+ setTextureFormat(tif, tf);
setTextureType(GL.GL_UNSIGNED_BYTE);
GLContextImpl ctx = (GLContextImpl)gl.getContext();
ProcAddressTable pt = ctx.getGLProcAddressTable();
@@ -296,9 +296,9 @@ public class FFMPEGMediaPlayer extends EGLMediaPlayerImpl {
" vec2 v_off = vec2("+tc_w_1+", 0.5);\n"+
" vec2 tc_half = texCoord*0.5;\n"+
" float y,u,v,r,g,b;\n"+
- " y = texture2D(image, texCoord).r;\n"+
- " u = texture2D(image, u_off+tc_half).r;\n"+
- " v = texture2D(image, v_off+tc_half).r;\n"+
+ " y = texture2D(image, texCoord).a;\n"+
+ " u = texture2D(image, u_off+tc_half).a;\n"+
+ " v = texture2D(image, v_off+tc_half).a;\n"+
" y = 1.1643*(y-0.0625);\n"+
" u = u-0.5;\n"+
" v = v-0.5;\n"+
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandler.java b/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandler.java
index 602d283..79bed90 100644
--- a/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandler.java
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandler.java
@@ -35,6 +35,7 @@ import javax.media.opengl.GL2ES2;
import jogamp.opengl.util.GLArrayHandler;
import jogamp.opengl.util.GLArrayHandlerFlat;
+import jogamp.opengl.util.GLVBOArrayHandler;
import com.jogamp.opengl.util.GLArrayDataEditable;
import com.jogamp.opengl.util.glsl.ShaderState;
@@ -43,11 +44,10 @@ import com.jogamp.opengl.util.glsl.ShaderState;
* Used for 1:1 GLSL arrays, i.e. where the buffer data
* represents this array only.
*/
-public class GLSLArrayHandler implements GLArrayHandler {
- private GLArrayDataEditable ad;
-
+public class GLSLArrayHandler extends GLVBOArrayHandler implements GLArrayHandler {
+
public GLSLArrayHandler(GLArrayDataEditable ad) {
- this.ad = ad;
+ super(ad);
}
public final void setSubArrayVBOName(int vboName) {
@@ -58,12 +58,11 @@ public class GLSLArrayHandler implements GLArrayHandler {
throw new UnsupportedOperationException();
}
- public final void syncData(GL gl, boolean enable, Object ext) {
+ public final void enableState(GL gl, boolean enable, Object ext) {
final GL2ES2 glsl = gl.getGL2ES2();
- final ShaderState st = (ShaderState) ext;
+ final ShaderState st = (ShaderState) ext;
if(enable) {
- final Buffer buffer = ad.getBuffer();
/*
* This would be the non optimized code path:
*
@@ -78,6 +77,7 @@ public class GLSLArrayHandler implements GLArrayHandler {
}
st.vertexAttribPointer(glsl, ad);
*/
+ final Buffer buffer = ad.getBuffer();
if(ad.isVBO()) {
// bind and refresh the VBO / vertex-attr only if necessary
if(!ad.isVBOWritten()) {
@@ -87,6 +87,7 @@ public class GLSLArrayHandler implements GLArrayHandler {
}
ad.setVBOWritten(true);
st.vertexAttribPointer(glsl, ad);
+ glsl.glBindBuffer(ad.getVBOTarget(), 0);
} else if(st.getAttribLocation(glsl, ad) >= 0) {
// didn't experience a performance hit on this query ..
// (using ShaderState's location query above to validate the location)
@@ -95,26 +96,17 @@ public class GLSLArrayHandler implements GLArrayHandler {
if(ad.getVBOName() != qi[0]) {
glsl.glBindBuffer(ad.getVBOTarget(), ad.getVBOName());
st.vertexAttribPointer(glsl, ad);
+ glsl.glBindBuffer(ad.getVBOTarget(), 0);
}
}
} else if(null!=buffer) {
st.vertexAttribPointer(glsl, ad);
}
- } else if(ad.isVBO()) {
- glsl.glBindBuffer(ad.getVBOTarget(), 0);
- }
- }
-
- public final void enableState(GL gl, boolean enable, Object ext) {
- final GL2ES2 glsl = gl.getGL2ES2();
- final ShaderState st = (ShaderState) ext;
-
- if(enable) {
+
st.enableVertexAttribArray(glsl, ad);
} else {
st.disableVertexAttribArray(glsl, ad);
}
}
-
}
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandlerFlat.java b/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandlerFlat.java
index c4b761b..c5beb7d 100644
--- a/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandlerFlat.java
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandlerFlat.java
@@ -51,28 +51,26 @@ public class GLSLArrayHandlerFlat implements GLArrayHandlerFlat {
return ad;
}
- public final void syncData(GL gl, boolean enable, boolean force, Object ext) {
- if(enable) {
- final GL2ES2 glsl = gl.getGL2ES2();
- final ShaderState st = (ShaderState) ext;
+ public final void syncData(GL gl, Object ext) {
+ final GL2ES2 glsl = gl.getGL2ES2();
+ final ShaderState st = (ShaderState) ext;
+ st.vertexAttribPointer(glsl, ad);
+ /**
+ * Due to probable application VBO switching, this might not make any sense ..
+ *
+ if(!written) {
st.vertexAttribPointer(glsl, ad);
- /**
- * Due to probable application VBO switching, this might not make any sense ..
- *
- if(force) {
+ } else if(st.getAttribLocation(glsl, ad) >= 0) {
+ final int[] qi = new int[1];
+ glsl.glGetVertexAttribiv(ad.getLocation(), GL2ES2.GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, qi, 0);
+ if(ad.getVBOName() != qi[0]) {
+ System.err.println("XXX1: "+ad.getName()+", vbo ad "+ad.getVBOName()+", gl "+qi[0]+", "+ad);
st.vertexAttribPointer(glsl, ad);
- } else if(st.getAttribLocation(glsl, ad) >= 0) {
- final int[] qi = new int[1];
- glsl.glGetVertexAttribiv(ad.getLocation(), GL2ES2.GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, qi, 0);
- if(ad.getVBOName() != qi[0]) {
- System.err.println("XXX1: "+ad.getName()+", vbo ad "+ad.getVBOName()+", gl "+qi[0]+", "+ad);
- st.vertexAttribPointer(glsl, ad);
- } else {
- System.err.println("XXX0: "+ad.getName()+", vbo ad "+ad.getVBOName()+", gl "+qi[0]+", "+ad);
- }
- }*/
- }
+ } else {
+ System.err.println("XXX0: "+ad.getName()+", vbo ad "+ad.getVBOName()+", gl "+qi[0]+", "+ad);
+ }
+ }*/
}
public final void enableState(GL gl, boolean enable, Object ext) {
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandlerInterleaved.java b/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandlerInterleaved.java
index f504296..f36693e 100644
--- a/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandlerInterleaved.java
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandlerInterleaved.java
@@ -28,7 +28,6 @@
package jogamp.opengl.util.glsl;
-import java.nio.Buffer;
import java.util.ArrayList;
import java.util.List;
@@ -36,6 +35,7 @@ import javax.media.opengl.GL;
import jogamp.opengl.util.GLArrayHandler;
import jogamp.opengl.util.GLArrayHandlerFlat;
+import jogamp.opengl.util.GLVBOArrayHandler;
import com.jogamp.opengl.util.GLArrayDataEditable;
@@ -43,12 +43,11 @@ import com.jogamp.opengl.util.GLArrayDataEditable;
* Interleaved fixed function arrays, i.e. where this buffer data
* represents many arrays.
*/
-public class GLSLArrayHandlerInterleaved implements GLArrayHandler {
- private GLArrayDataEditable ad;
+public class GLSLArrayHandlerInterleaved extends GLVBOArrayHandler implements GLArrayHandler {
private List<GLArrayHandlerFlat> subArrays = new ArrayList<GLArrayHandlerFlat>();
public GLSLArrayHandlerInterleaved(GLArrayDataEditable ad) {
- this.ad = ad;
+ super(ad);
}
public final void setSubArrayVBOName(int vboName) {
@@ -61,39 +60,22 @@ public class GLSLArrayHandlerInterleaved implements GLArrayHandler {
subArrays.add(handler);
}
- private final void syncSubData(GL gl, boolean enable, boolean force, Object ext) {
+ private final void syncSubData(GL gl, Object ext) {
for(int i=0; i<subArrays.size(); i++) {
- subArrays.get(i).syncData(gl, enable, force, ext);
+ subArrays.get(i).syncData(gl, ext);
}
}
- public final void syncData(GL gl, boolean enable, Object ext) {
- if(!ad.isVBO()) {
- throw new InternalError("Interleaved handle is not VBO: "+ad);
- }
-
+ public final void enableState(GL gl, boolean enable, Object ext) {
if(enable) {
- final Buffer buffer = ad.getBuffer();
- final boolean vboWritten = ad.isVBOWritten();
-
- // always bind and refresh the VBO mgr,
- // in case more than one gl*Pointer objects are in use
- gl.glBindBuffer(ad.getVBOTarget(), ad.getVBOName());
- if(!vboWritten) {
- if(null!=buffer) {
- gl.glBufferData(ad.getVBOTarget(), buffer.limit() * ad.getComponentSizeInBytes(), buffer, ad.getVBOUsage());
- }
- ad.setVBOWritten(true);
+ if(!ad.isVBO()) {
+ throw new InternalError("Interleaved handle is not VBO: "+ad);
}
+ bindBuffer(gl, true);
// sub data will decide weather to update the vertex attrib pointer
- syncSubData(gl, true, !vboWritten, ext);
- } else {
- // NOP on GLSL: syncSubData(gl, false, ext);
- gl.glBindBuffer(ad.getVBOTarget(), 0);
+ syncSubData(gl, ext);
+ bindBuffer(gl, false);
}
- }
-
- public final void enableState(GL gl, boolean enable, Object ext) {
for(int i=0; i<subArrays.size(); i++) {
subArrays.get(i).enableState(gl, enable, ext);
}
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/FixedFuncHook.java b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/FixedFuncHook.java
index 897967f..351d7a1 100644
--- a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/FixedFuncHook.java
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/FixedFuncHook.java
@@ -29,48 +29,83 @@
package jogamp.opengl.util.glsl.fixedfunc;
-import javax.media.opengl.*;
-import javax.media.opengl.fixedfunc.*;
-import com.jogamp.common.nio.Buffers;
-import com.jogamp.opengl.util.*;
+import java.nio.Buffer;
+import java.nio.IntBuffer;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GLArrayData;
+import javax.media.opengl.GLException;
+import javax.media.opengl.fixedfunc.GLLightingFunc;
+import javax.media.opengl.fixedfunc.GLMatrixFunc;
+import javax.media.opengl.fixedfunc.GLPointerFunc;
-import java.nio.*;
+import com.jogamp.common.nio.Buffers;
+import com.jogamp.common.util.ValueConv;
+import com.jogamp.opengl.util.GLArrayDataWrapper;
+import com.jogamp.opengl.util.GLBuffers;
+import com.jogamp.opengl.util.PMVMatrix;
+import com.jogamp.opengl.util.glsl.fixedfunc.ShaderSelectionMode;
public class FixedFuncHook implements GLLightingFunc, GLMatrixFunc, GLPointerFunc {
public static final int MAX_TEXTURE_UNITS = 8;
- protected FixedFuncPipeline fixedFunction=null;
- protected PMVMatrix pmvMatrix=null;
- protected GL2ES2 gl=null;
-
- public FixedFuncHook (GL2ES2 gl) {
- this(gl, null);
- }
+ protected FixedFuncPipeline fixedFunction;
+ protected PMVMatrix pmvMatrix;
+ protected boolean ownsPMVMatrix;
+ protected GL2ES2 gl;
- public FixedFuncHook (GL2ES2 gl, PMVMatrix matrix) {
+ /**
+ * @param gl
+ * @param mode TODO
+ * @param pmvMatrix optional pass through PMVMatrix for the {@link FixedFuncHook} and {@link FixedFuncPipeline}
+ */
+ public FixedFuncHook (GL2ES2 gl, ShaderSelectionMode mode, PMVMatrix pmvMatrix) {
this.gl = gl;
- pmvMatrix = (null!=matrix)?matrix:new PMVMatrix();
-
- fixedFunction = new FixedFuncPipeline(gl, pmvMatrix);
+ if(null != pmvMatrix) {
+ this.ownsPMVMatrix = false;
+ this.pmvMatrix = pmvMatrix;
+ } else {
+ this.ownsPMVMatrix = true;
+ this.pmvMatrix = new PMVMatrix();
+ }
+ fixedFunction = new FixedFuncPipeline(this.gl, mode, this.pmvMatrix);
}
- public FixedFuncHook(GL2ES2 gl, PMVMatrix matrix,
- Class<?> shaderRootClass, String shaderSrcRoot, String shaderBinRoot,
- String vertexColorFile,
- String vertexColorLightFile,
- String fragmentColorFile,
- String fragmentColorTextureFile) {
+ /**
+ * @param gl
+ * @param mode TODO
+ * @param pmvMatrix optional pass through PMVMatrix for the {@link FixedFuncHook} and {@link FixedFuncPipeline}
+ */
+ public FixedFuncHook(GL2ES2 gl, ShaderSelectionMode mode, PMVMatrix pmvMatrix,
+ Class<?> shaderRootClass, String shaderSrcRoot, String shaderBinRoot,
+ String vertexColorFile, String vertexColorLightFile,
+ String fragmentColorFile, String fragmentColorTextureFile) {
this.gl = gl;
- pmvMatrix = matrix;
+ if(null != pmvMatrix) {
+ this.ownsPMVMatrix = false;
+ this.pmvMatrix = pmvMatrix;
+ } else {
+ this.ownsPMVMatrix = true;
+ this.pmvMatrix = new PMVMatrix();
+ }
- fixedFunction = new FixedFuncPipeline(gl, pmvMatrix,
- shaderRootClass, shaderSrcRoot, shaderBinRoot,
- vertexColorFile, vertexColorLightFile, fragmentColorFile, fragmentColorTextureFile);
+ fixedFunction = new FixedFuncPipeline(this.gl, mode, this.pmvMatrix, shaderRootClass, shaderSrcRoot,
+ shaderBinRoot, vertexColorFile, vertexColorLightFile, fragmentColorFile, fragmentColorTextureFile);
}
+ public boolean verbose() { return fixedFunction.verbose(); }
+
+ public void setVerbose(boolean v) { fixedFunction.setVerbose(v); }
+
public void destroy() {
fixedFunction.destroy(gl);
fixedFunction = null;
+ if(ownsPMVMatrix) {
+ pmvMatrix.destroy();
+ }
+ pmvMatrix=null;
+ gl=null;
}
public PMVMatrix getMatrix() { return pmvMatrix; }
@@ -79,37 +114,29 @@ public class FixedFuncHook implements GLLightingFunc, GLMatrixFunc, GLPointerFun
// FixedFuncHookIf - hooks
//
public void glDrawArrays(int mode, int first, int count) {
- fixedFunction.validate(gl);
- gl.glDrawArrays(mode, first, count);
+ fixedFunction.glDrawArrays(gl, mode, first, count);
}
public void glDrawElements(int mode, int count, int type, java.nio.Buffer indices) {
- fixedFunction.validate(gl);
- gl.glDrawElements(mode, count, type, indices);
+ fixedFunction.glDrawElements(gl, mode, count, type, indices);
}
public void glDrawElements(int mode, int count, int type, long indices_buffer_offset) {
- fixedFunction.validate(gl);
- gl.glDrawElements(mode, count, type, indices_buffer_offset);
+ fixedFunction.glDrawElements(gl, mode, count, type, indices_buffer_offset);
}
public void glActiveTexture(int texture) {
- fixedFunction.glActiveTexture(gl, texture);
+ fixedFunction.glActiveTexture(texture);
gl.glActiveTexture(texture);
}
public void glEnable(int cap) {
- if(fixedFunction.glEnable(gl, cap, true)) {
+ if(fixedFunction.glEnable(cap, true)) {
gl.glEnable(cap);
}
}
public void glDisable(int cap) {
- if(fixedFunction.glEnable(gl, cap, false)) {
+ if(fixedFunction.glEnable(cap, false)) {
gl.glDisable(cap);
}
- }
- public void glCullFace(int faceName) {
- fixedFunction.glCullFace(gl, faceName);
- gl.glCullFace(faceName);
- }
-
+ }
public void glGetFloatv(int pname, java.nio.FloatBuffer params) {
if(PMVMatrix.isMatrixGetName(pname)) {
pmvMatrix.glGetFloatv(pname, params);
@@ -138,7 +165,54 @@ public class FixedFuncHook implements GLLightingFunc, GLMatrixFunc, GLPointerFun
}
gl.glGetIntegerv(pname, params, params_offset);
}
+
+ public void glTexEnvi(int target, int pname, int value) {
+ fixedFunction.glTexEnvi(target, pname, value);
+ }
+ public void glGetTexEnviv(int target, int pname, IntBuffer params) {
+ fixedFunction.glGetTexEnviv(target, pname, params);
+ }
+ public void glGetTexEnviv(int target, int pname, int[] params, int params_offset) {
+ fixedFunction.glGetTexEnviv(target, pname, params, params_offset);
+ }
+ public void glBindTexture(int target, int texture) {
+ fixedFunction.glBindTexture(target, texture);
+ gl.glBindTexture(target, texture);
+ }
+ public void glTexImage2D(int target, int level, int internalformat, int width, int height, int border,
+ int format, int type, Buffer pixels) {
+ // align internalformat w/ format, an ES2 requirement
+ switch(internalformat) {
+ case 3: internalformat= ( GL.GL_RGBA == format ) ? GL.GL_RGBA : GL.GL_RGB; break;
+ case 4: internalformat= ( GL.GL_RGB == format ) ? GL.GL_RGB : GL.GL_RGBA; break;
+ }
+ fixedFunction.glTexImage2D(target, /* level, */ internalformat, /*width, height, border, */ format /*, type, pixels*/);
+ gl.glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
+ }
+ public void glTexImage2D(int target, int level, int internalformat, int width, int height, int border,
+ int format, int type, long pixels_buffer_offset) {
+ // align internalformat w/ format, an ES2 requirement
+ switch(internalformat) {
+ case 3: internalformat= ( GL.GL_RGBA == format ) ? GL.GL_RGBA : GL.GL_RGB; break;
+ case 4: internalformat= ( GL.GL_RGB == format ) ? GL.GL_RGB : GL.GL_RGBA; break;
+ }
+ fixedFunction.glTexImage2D(target, /* level, */ internalformat, /*width, height, border, */ format /*, type, pixels*/);
+ gl.glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels_buffer_offset);
+ }
+ public void glPointSize(float size) {
+ fixedFunction.glPointSize(size);
+ }
+ public void glPointParameterf(int pname, float param) {
+ fixedFunction.glPointParameterf(pname, param);
+ }
+ public void glPointParameterfv(int pname, float[] params, int params_offset) {
+ fixedFunction.glPointParameterfv(pname, params, params_offset);
+ }
+ public void glPointParameterfv(int pname, java.nio.FloatBuffer params) {
+ fixedFunction.glPointParameterfv(pname, params);
+ }
+
//
// MatrixIf
//
@@ -178,9 +252,15 @@ public class FixedFuncHook implements GLLightingFunc, GLMatrixFunc, GLPointerFun
public void glScalef(float x, float y, float z) {
pmvMatrix.glScalef(x, y, z);
}
+ public void glOrtho(double left, double right, double bottom, double top, double near_val, double far_val) {
+ glOrthof((float) left, (float) right, (float) bottom, (float) top, (float) near_val, (float) far_val);
+ }
public void glOrthof(float left, float right, float bottom, float top, float zNear, float zFar) {
pmvMatrix.glOrthof(left, right, bottom, top, zNear, zFar);
}
+ public void glFrustum(double left, double right, double bottom, double top, double zNear, double zFar) {
+ glFrustumf((float) left, (float) right, (float) bottom, (float) top, (float) zNear, (float) zFar);
+ }
public void glFrustumf(float left, float right, float bottom, float top, float zNear, float zFar) {
pmvMatrix.glFrustumf(left, right, bottom, top, zNear, zFar);
}
@@ -189,9 +269,15 @@ public class FixedFuncHook implements GLLightingFunc, GLMatrixFunc, GLPointerFun
// LightingIf
//
public void glColor4f(float red, float green, float blue, float alpha) {
- fixedFunction.glColor4fv(gl, GLBuffers.newDirectFloatBuffer(new float[] { red, green, blue, alpha }));
+ fixedFunction.glColor4f(gl, red, green, blue, alpha);
+ }
+
+ public void glColor4ub(byte red, byte green, byte blue, byte alpha) {
+ glColor4f(ValueConv.byte_to_float(red, false),
+ ValueConv.byte_to_float(green, false),
+ ValueConv.byte_to_float(blue, false),
+ ValueConv.byte_to_float(alpha, false) );
}
-
public void glLightfv(int light, int pname, java.nio.FloatBuffer params) {
fixedFunction.glLightfv(gl, light, pname, params);
}
@@ -207,13 +293,29 @@ public class FixedFuncHook implements GLLightingFunc, GLMatrixFunc, GLPointerFun
public void glMaterialf(int face, int pname, float param) {
glMaterialfv(face, pname, GLBuffers.newDirectFloatBuffer(new float[] { param }));
}
+
+ //
+ // Misc Simple States
+ //
public void glShadeModel(int mode) {
fixedFunction.glShadeModel(gl, mode);
+ }
+ public void glAlphaFunc(int func, float ref) {
+ fixedFunction.glAlphaFunc(func, ref);
}
-
+
+ /** ES2 supports CullFace implicit
+ public void glCullFace(int faceName) {
+ fixedFunction.glCullFace(faceName);
+ gl.glCullFace(faceName);
+ } */
+
//
// PointerIf
//
+ public void glClientActiveTexture(int textureUnit) {
+ fixedFunction.glClientActiveTexture(textureUnit);
+ }
public void glEnableClientState(int glArrayIndex) {
fixedFunction.glEnableClientState(gl, glArrayIndex);
}
@@ -238,14 +340,15 @@ public class FixedFuncHook implements GLLightingFunc, GLMatrixFunc, GLPointerFun
}
public void glVertexPointer(int size, int type, int stride, java.nio.Buffer pointer) {
- glVertexPointer(GLArrayDataWrapper.createFixed(GL_VERTEX_ARRAY, size, type, false, stride, pointer, 0, 0, 0, GL.GL_ARRAY_BUFFER));
+ glVertexPointer(GLArrayDataWrapper.createFixed(GL_VERTEX_ARRAY, size, type, GLBuffers.isGLTypeFixedPoint(type), stride,
+ pointer, 0, 0, 0, GL.GL_ARRAY_BUFFER));
}
public void glVertexPointer(int size, int type, int stride, long pointer_buffer_offset) {
int vboName = gl.glGetBoundBuffer(GL.GL_ARRAY_BUFFER);
if(vboName==0) {
throw new GLException("no GL_ARRAY_BUFFER VBO bound");
}
- glVertexPointer(GLArrayDataWrapper.createFixed(GL_VERTEX_ARRAY, size, type, false, stride,
+ glVertexPointer(GLArrayDataWrapper.createFixed(GL_VERTEX_ARRAY, size, type, GLBuffers.isGLTypeFixedPoint(type), stride,
null, vboName, pointer_buffer_offset, GL.GL_STATIC_DRAW, GL.GL_ARRAY_BUFFER));
}
@@ -265,7 +368,7 @@ public class FixedFuncHook implements GLLightingFunc, GLMatrixFunc, GLPointerFun
fixedFunction.glColorPointer(gl, array);
}
public void glColorPointer(int size, int type, int stride, java.nio.Buffer pointer) {
- glColorPointer(GLArrayDataWrapper.createFixed(GL_COLOR_ARRAY, size, type, false, stride,
+ glColorPointer(GLArrayDataWrapper.createFixed(GL_COLOR_ARRAY, size, type, GLBuffers.isGLTypeFixedPoint(type), stride,
pointer, 0, 0, 0, GL.GL_ARRAY_BUFFER));
}
public void glColorPointer(int size, int type, int stride, long pointer_buffer_offset) {
@@ -273,7 +376,7 @@ public class FixedFuncHook implements GLLightingFunc, GLMatrixFunc, GLPointerFun
if(vboName==0) {
throw new GLException("no GL_ARRAY_BUFFER VBO bound");
}
- glColorPointer(GLArrayDataWrapper.createFixed(GL_COLOR_ARRAY, size, type, false, stride,
+ glColorPointer(GLArrayDataWrapper.createFixed(GL_COLOR_ARRAY, size, type, GLBuffers.isGLTypeFixedPoint(type), stride,
null, vboName, pointer_buffer_offset, GL.GL_STATIC_DRAW, GL.GL_ARRAY_BUFFER));
}
@@ -296,7 +399,7 @@ public class FixedFuncHook implements GLLightingFunc, GLMatrixFunc, GLPointerFun
fixedFunction.glNormalPointer(gl, array);
}
public void glNormalPointer(int type, int stride, java.nio.Buffer pointer) {
- glNormalPointer(GLArrayDataWrapper.createFixed(GL_NORMAL_ARRAY, 3, type, false, stride,
+ glNormalPointer(GLArrayDataWrapper.createFixed(GL_NORMAL_ARRAY, 3, type, GLBuffers.isGLTypeFixedPoint(type), stride,
pointer, 0, 0, 0, GL.GL_ARRAY_BUFFER));
}
public void glNormalPointer(int type, int stride, long pointer_buffer_offset) {
@@ -304,7 +407,7 @@ public class FixedFuncHook implements GLLightingFunc, GLMatrixFunc, GLPointerFun
if(vboName==0) {
throw new GLException("no GL_ARRAY_BUFFER VBO bound");
}
- glNormalPointer(GLArrayDataWrapper.createFixed(GL_NORMAL_ARRAY, 3, type, false, stride,
+ glNormalPointer(GLArrayDataWrapper.createFixed(GL_NORMAL_ARRAY, 3, type, GLBuffers.isGLTypeFixedPoint(type), stride,
null, vboName, pointer_buffer_offset, GL.GL_STATIC_DRAW, GL.GL_ARRAY_BUFFER));
}
@@ -325,7 +428,8 @@ public class FixedFuncHook implements GLLightingFunc, GLMatrixFunc, GLPointerFun
}
public void glTexCoordPointer(int size, int type, int stride, java.nio.Buffer pointer) {
glTexCoordPointer(
- GLArrayDataWrapper.createFixed(GL_TEXTURE_COORD_ARRAY, size, type, false, stride, pointer, 0, 0, 0, GL.GL_ARRAY_BUFFER));
+ GLArrayDataWrapper.createFixed(GL_TEXTURE_COORD_ARRAY, size, type, GLBuffers.isGLTypeFixedPoint(type), stride,
+ pointer, 0, 0, 0, GL.GL_ARRAY_BUFFER));
}
public void glTexCoordPointer(int size, int type, int stride, long pointer_buffer_offset) {
int vboName = gl.glGetBoundBuffer(GL.GL_ARRAY_BUFFER);
@@ -333,7 +437,7 @@ public class FixedFuncHook implements GLLightingFunc, GLMatrixFunc, GLPointerFun
throw new GLException("no GL_ARRAY_BUFFER VBO bound");
}
glTexCoordPointer(
- GLArrayDataWrapper.createFixed(GL_TEXTURE_COORD_ARRAY, size, type, false, stride,
+ GLArrayDataWrapper.createFixed(GL_TEXTURE_COORD_ARRAY, size, type, GLBuffers.isGLTypeFixedPoint(type), stride,
null, vboName, pointer_buffer_offset, GL.GL_STATIC_DRAW, GL.GL_ARRAY_BUFFER) );
}
@@ -341,7 +445,7 @@ public class FixedFuncHook implements GLLightingFunc, GLMatrixFunc, GLPointerFun
StringBuilder buf = new StringBuilder();
buf.append(getClass().getName()+" (");
if(null!=pmvMatrix) {
- buf.append(", matrixDirty: "+pmvMatrix.isDirty());
+ buf.append(", matrixDirty: "+ (0 != pmvMatrix.getModifiedBits(false)));
}
buf.append("\n\t, FixedFunction: "+fixedFunction);
buf.append(gl);
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/FixedFuncPipeline.java b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/FixedFuncPipeline.java
index bfe2e13..cc58f23 100644
--- a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/FixedFuncPipeline.java
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/FixedFuncPipeline.java
@@ -29,33 +29,80 @@
package jogamp.opengl.util.glsl.fixedfunc;
+import java.nio.ByteBuffer;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+import java.nio.ShortBuffer;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2;
+import javax.media.opengl.GL2ES1;
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GL2GL3;
+import javax.media.opengl.GLArrayData;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLRunnable2;
+import javax.media.opengl.GLUniformData;
+import javax.media.opengl.fixedfunc.GLLightingFunc;
+import javax.media.opengl.fixedfunc.GLPointerFunc;
+import javax.media.opengl.fixedfunc.GLPointerFuncUtil;
+
+import jogamp.opengl.Debug;
+
import com.jogamp.common.nio.Buffers;
-import javax.media.opengl.*;
-import javax.media.opengl.fixedfunc.*;
-import com.jogamp.opengl.util.*;
-import com.jogamp.opengl.util.glsl.*;
-import java.nio.*;
+import com.jogamp.common.util.IntIntHashMap;
+import com.jogamp.opengl.util.PMVMatrix;
+import com.jogamp.opengl.util.glsl.ShaderCode;
+import com.jogamp.opengl.util.glsl.ShaderProgram;
+import com.jogamp.opengl.util.glsl.ShaderState;
+import com.jogamp.opengl.util.glsl.fixedfunc.ShaderSelectionMode;
+/**
+ *
+ * <p>
+ * Note: Certain GL FFP state values (e.g.: alphaTestFunc and cullFace)
+ * are mapped to a lower number range so they can be stored in low precision storage,
+ * i.e. in a 'lowp int' (GL ES2).
+ * </p>
+ */
public class FixedFuncPipeline {
+ protected static final boolean DEBUG = Debug.isPropertyDefined("jogl.debug.FixedFuncPipeline", true);
+ /** The maximum texture units which could be used, depending on {@link ShaderSelectionMode}. */
public static final int MAX_TEXTURE_UNITS = 8;
public static final int MAX_LIGHTS = 8;
-
- public FixedFuncPipeline(GL2ES2 gl, PMVMatrix pmvMatrix) {
- init(gl, pmvMatrix, FixedFuncPipeline.class, shaderSrcRootDef, shaderBinRootDef,
- vertexColorFileDef, vertexColorLightFileDef, fragmentColorFileDef, fragmentColorTextureFileDef);
+
+ public FixedFuncPipeline(GL2ES2 gl, ShaderSelectionMode mode, PMVMatrix pmvMatrix) {
+ shaderRootClass = FixedFuncPipeline.class;
+ shaderSrcRoot = shaderSrcRootDef;
+ shaderBinRoot = shaderBinRootDef;
+ vertexColorFile = vertexColorFileDef;
+ vertexColorLightFile = vertexColorLightFileDef;
+ fragmentColorFile = fragmentColorFileDef;
+ fragmentColorTextureFile = fragmentColorTextureFileDef;
+ init(gl, mode, pmvMatrix);
}
- public FixedFuncPipeline(GL2ES2 gl, PMVMatrix pmvMatrix, Class shaderRootClass, String shaderSrcRoot, String shaderBinRoot,
- String vertexColorFile,
- String vertexColorLightFile,
- String fragmentColorFile,
- String fragmentColorTextureFile) {
- init(gl, pmvMatrix, shaderRootClass, shaderSrcRoot, shaderBinRoot,
- vertexColorFile, vertexColorLightFile, fragmentColorFile, fragmentColorTextureFile);
+ public FixedFuncPipeline(GL2ES2 gl, ShaderSelectionMode mode, PMVMatrix pmvMatrix,
+ Class<?> shaderRootClass, String shaderSrcRoot,
+ String shaderBinRoot,
+ String vertexColorFile, String vertexColorLightFile,
+ String fragmentColorFile, String fragmentColorTextureFile) {
+ this.shaderRootClass = shaderRootClass;
+ this.shaderSrcRoot = shaderSrcRoot;
+ this.shaderBinRoot = shaderBinRoot;
+ this.vertexColorFile = vertexColorFile;
+ this.vertexColorLightFile = vertexColorLightFile;
+ this.fragmentColorFile = fragmentColorFile;
+ this.fragmentColorTextureFile = fragmentColorTextureFile;
+ init(gl, mode, pmvMatrix);
}
+
+ public ShaderSelectionMode getShaderSelectionMode() { return requestedShaderSelectionMode; }
+ public void setShaderSelectionMode(ShaderSelectionMode mode) { requestedShaderSelectionMode=mode; }
+ public ShaderSelectionMode getCurrentShaderSelectionMode() { return currentShaderSelectionMode; }
public boolean verbose() { return verbose; }
- public void setVerbose(boolean v) { verbose=v; }
+ public void setVerbose(boolean v) { verbose = DEBUG || v; }
public boolean isValid() {
return shaderState.linked();
@@ -69,49 +116,86 @@ public class FixedFuncPipeline {
return activeTextureUnit;
}
- public String getArrayIndexName(int glArrayIndex) {
- String name = GLPointerFuncUtil.getPredefinedArrayIndexName(glArrayIndex);
- switch(glArrayIndex) {
- case GLPointerFunc.GL_VERTEX_ARRAY:
- case GLPointerFunc.GL_NORMAL_ARRAY:
- case GLPointerFunc.GL_COLOR_ARRAY:
- break;
- case GLPointerFunc.GL_TEXTURE_COORD_ARRAY:
- name = name + activeTextureUnit;
- }
- return name;
- }
-
public void destroy(GL2ES2 gl) {
- shaderProgramColor.release(gl, true);
- shaderProgramColorLight.release(gl, true);
- shaderProgramColorTexture.release(gl, true);
- shaderProgramColorTextureLight.release(gl, true);
+ if(null != shaderProgramColor) {
+ shaderProgramColor.release(gl, true);
+ }
+ if(null != shaderProgramColorLight) {
+ shaderProgramColorLight.release(gl, true);
+ }
+ if(null != shaderProgramColorTexture2) {
+ shaderProgramColorTexture2.release(gl, true);
+ }
+ if(null != shaderProgramColorTexture4) {
+ shaderProgramColorTexture4.release(gl, true);
+ }
+ if(null != shaderProgramColorTexture4) {
+ shaderProgramColorTexture4.release(gl, true);
+ }
+ if(null != shaderProgramColorTexture8Light) {
+ shaderProgramColorTexture8Light.release(gl, true);
+ }
shaderState.destroy(gl);
}
- public void glEnableClientState(GL2ES2 gl, int glArrayIndex) {
+ //
+ // Simple Globals
+ //
+ public void glColor4f(GL2ES2 gl, float red, float green, float blue, float alpha) {
+ colorStatic.put(0, red);
+ colorStatic.put(1, green);
+ colorStatic.put(2, blue);
+ colorStatic.put(3, alpha);
+
shaderState.useProgram(gl, true);
-
- shaderState.enableVertexAttribArray(gl, getArrayIndexName(glArrayIndex));
- // textureCoordsEnabled |= (1 << activeTextureUnit);
- if ( textureCoordsEnabled.get(activeTextureUnit) != 1 ) {
- textureCoordsEnabled.put(activeTextureUnit, 1);
- textureCoordsEnabledDirty = true;
- }
+ final GLUniformData ud = shaderState.getUniform(mgl_ColorStatic);
+ if(null!=ud) {
+ // same data object ..
+ shaderState.uniform(gl, ud);
+ } else {
+ throw new GLException("Failed to update: mgl_ColorStatic");
+ }
+ }
+
+ //
+ // Arrays / States
+ //
+
+ public void glEnableClientState(GL2ES2 gl, int glArrayIndex) {
+ glToggleClientState(gl, glArrayIndex, true);
}
public void glDisableClientState(GL2ES2 gl, int glArrayIndex) {
- shaderState.useProgram(gl, true);
+ glToggleClientState(gl, glArrayIndex, false);
+ }
- shaderState.disableVertexAttribArray(gl, getArrayIndexName(glArrayIndex));
- // textureCoordsEnabled &= ~(1 << activeTextureUnit);
- if ( textureCoordsEnabled.get(activeTextureUnit) != 0 ) {
- textureCoordsEnabled.put(activeTextureUnit, 0);
- textureCoordsEnabledDirty = true;
+ private void glToggleClientState(GL2ES2 gl, int glArrayIndex, boolean enable) {
+ final String arrayName = GLPointerFuncUtil.getPredefinedArrayIndexName(glArrayIndex, clientActiveTextureUnit);
+ if(null == arrayName) {
+ throw new GLException("arrayIndex "+toHexString(glArrayIndex)+" unknown");
+ }
+ shaderState.useProgram(gl, true);
+ if(enable) {
+ shaderState.enableVertexAttribArray(gl, arrayName );
+ } else {
+ shaderState.disableVertexAttribArray(gl, arrayName );
+ }
+ switch( glArrayIndex ) {
+ case GLPointerFunc.GL_TEXTURE_COORD_ARRAY:
+ final int enableV = enable ? 1 : 0;
+ // enable-bitwise: textureCoordsEnabled |= (1 << clientActiveTextureUnit);
+ // disable-bitwise: textureCoordsEnabled &= ~(1 << clientActiveTextureUnit);
+ if ( textureCoordEnabled.get(clientActiveTextureUnit) != enableV) {
+ textureCoordEnabled.put(clientActiveTextureUnit, enableV);
+ textureCoordEnabledDirty = true;
+ }
+ break;
+ case GLPointerFunc.GL_COLOR_ARRAY:
+ colorVAEnabledDirty = true;
+ break;
}
}
-
+
public void glVertexPointer(GL2ES2 gl, GLArrayData data) {
shaderState.useProgram(gl, true);
shaderState.vertexAttribPointer(gl, data);
@@ -122,27 +206,236 @@ public class FixedFuncPipeline {
shaderState.vertexAttribPointer(gl, data);
}
- public void glColor4fv(GL2ES2 gl, FloatBuffer data ) {
- shaderState.useProgram(gl, true);
- GLUniformData ud = shaderState.getUniform(mgl_ColorStatic);
- if(null!=ud) {
- ud.setData(data);
- shaderState.uniform(gl, ud);
- }
- }
-
public void glNormalPointer(GL2ES2 gl, GLArrayData data) {
shaderState.useProgram(gl, true);
shaderState.vertexAttribPointer(gl, data);
}
+
+ //
+ // MULTI-TEXTURE
+ //
+
+ /** Enables/Disables the named texture unit (if changed), returns previous state */
+ private boolean glEnableTexture(boolean enable, int unit) {
+ final boolean isEnabled = 0 != ( textureEnabledBits & ( 1 << activeTextureUnit ) );
+ if( isEnabled != enable ) {
+ if(enable) {
+ textureEnabledBits |= ( 1 << unit );
+ textureEnabled.put(unit, 1);
+ } else {
+ textureEnabledBits &= ~( 1 << unit );
+ textureEnabled.put(unit, 0);
+ }
+ textureEnabledDirty=true;
+ }
+ return isEnabled;
+ }
+
+ public void glClientActiveTexture(int textureUnit) {
+ textureUnit -= GL.GL_TEXTURE0;
+ if(0 <= textureUnit && textureUnit<MAX_TEXTURE_UNITS) {
+ clientActiveTextureUnit = textureUnit;
+ } else {
+ throw new GLException("glClientActiveTexture textureUnit not within GL_TEXTURE0 + [0.."+MAX_TEXTURE_UNITS+"]: "+textureUnit);
+ }
+ }
+
+ public void glActiveTexture(int textureUnit) {
+ textureUnit -= GL.GL_TEXTURE0;
+ if(0 <= textureUnit && textureUnit<MAX_TEXTURE_UNITS) {
+ activeTextureUnit = textureUnit;
+ } else {
+ throw new GLException("glActivateTexture textureUnit not within GL_TEXTURE0 + [0.."+MAX_TEXTURE_UNITS+"]: "+textureUnit);
+ }
+ }
public void glTexCoordPointer(GL2ES2 gl, GLArrayData data) {
+ if( GLPointerFunc.GL_TEXTURE_COORD_ARRAY != data.getIndex() ) {
+ throw new GLException("Invalid GLArrayData Index "+toHexString(data.getIndex())+", "+data);
+ }
shaderState.useProgram(gl, true);
- data.setName( getArrayIndexName(data.getIndex()) );
+ data.setName( GLPointerFuncUtil.getPredefinedArrayIndexName(data.getIndex(), clientActiveTextureUnit) ) ;
shaderState.vertexAttribPointer(gl, data);
}
+
+ public void glBindTexture(int target, int texture) {
+ if(GL.GL_TEXTURE_2D == target) {
+ if( texture != boundTextureObject[activeTextureUnit] ) {
+ boundTextureObject[activeTextureUnit] = texture;
+ textureFormatDirty = true;
+ }
+ } else {
+ System.err.println("FixedFuncPipeline: Unimplemented glBindTexture for target "+toHexString(target)+". Texture name "+toHexString(texture));
+ }
+ }
+
+ public void glTexImage2D(int target, /* int level, */ int internalformat, /*, int width, int height, int border, */
+ int format /*, int type, Buffer pixels */) {
+ final int ifmt;
+ if(GL.GL_TEXTURE_2D == target) {
+ switch(internalformat) {
+ case 3:
+ case GL.GL_RGB:
+ case GL.GL_RGB565:
+ case GL.GL_RGB8:
+ case GL.GL_RGB10:
+ ifmt = 3;
+ break;
+ case 4:
+ case GL.GL_RGBA:
+ case GL.GL_RGB5_A1:
+ case GL.GL_RGBA4:
+ case GL.GL_RGBA8:
+ case GL.GL_RGB10_A2:
+ ifmt = 4;
+ break;
+ default:
+ System.err.println("FixedFuncPipeline: glTexImage2D TEXTURE_2D: Unimplemented internalformat "+toHexString(internalformat));
+ ifmt = 4;
+ break;
+ }
+ if( ifmt != texID2Format.put(boundTextureObject[activeTextureUnit], ifmt) ) {
+ textureFormatDirty = true;
+ // System.err.println("glTexImage2D TEXTURE_2D: internalformat ifmt "+toHexString(internalformat)+" fmt "+toHexString(format)+" -> "+toHexString(ifmt));
+ }
+ } else {
+ System.err.println("FixedFuncPipeline: Unimplemented glTexImage2D: target "+toHexString(target)+", internalformat "+toHexString(internalformat));
+ }
+ }
+ /*
+ public void glTexImage2D(int target, int level, int internalformat, int width, int height, int border,
+ int format, int type, long pixels_buffer_offset) {
+ textureFormat.put(activeTextureUnit, internalformat);
+ textureFormatDirty = true;
+ }*/
+
+ public void glTexEnvi(int target, int pname, int value) {
+ if(GL2ES1.GL_TEXTURE_ENV == target && GL2ES1.GL_TEXTURE_ENV_MODE == pname) {
+ final int mode;
+ switch( value ) {
+ case GL2ES1.GL_ADD:
+ mode = 1;
+ break;
+ case GL2ES1.GL_MODULATE:
+ mode = 2;
+ break;
+ case GL2ES1.GL_DECAL:
+ mode = 3;
+ break;
+ case GL2ES1.GL_BLEND:
+ mode = 4;
+ break;
+ case GL2ES1.GL_REPLACE:
+ mode = 5;
+ break;
+ case GL2ES1.GL_COMBINE:
+ mode = 2; // FIXME
+ System.err.println("FixedFuncPipeline: glTexEnv GL_TEXTURE_ENV_MODE: unimplemented mode: "+toHexString(value));
+ break;
+ default:
+ throw new GLException("glTexEnv GL_TEXTURE_ENV_MODE: invalid mode: "+toHexString(value));
+ }
+ setTextureEnvMode(mode);
+ } else if(verbose) {
+ System.err.println("FixedFuncPipeline: Unimplemented TexEnv: target "+toHexString(target)+", pname "+toHexString(pname)+", mode: "+toHexString(value));
+ }
+ }
+ private void setTextureEnvMode(int value) {
+ if( value != textureEnvMode.get(activeTextureUnit) ) {
+ textureEnvMode.put(activeTextureUnit, value);
+ textureEnvModeDirty = true;
+ }
+ }
+ public void glGetTexEnviv(int target, int pname, IntBuffer params) { // FIXME
+ System.err.println("FixedFuncPipeline: Unimplemented glGetTexEnviv: target "+toHexString(target)+", pname "+toHexString(pname));
+ }
+ public void glGetTexEnviv(int target, int pname, int[] params, int params_offset) { // FIXME
+ System.err.println("FixedFuncPipeline: Unimplemented glGetTexEnviv: target "+toHexString(target)+", pname "+toHexString(pname));
+ }
+
+ //
+ // Point Sprites
+ //
+ public void glPointSize(float size) {
+ pointParams.put(0, size);
+ pointParamsDirty = true;
+ }
+ public void glPointParameterf(int pname, float param) {
+ switch(pname) {
+ case GL2ES1.GL_POINT_SIZE_MIN:
+ pointParams.put(2, param);
+ break;
+ case GL2ES1.GL_POINT_SIZE_MAX:
+ pointParams.put(3, param);
+ break;
+ case GL2ES2.GL_POINT_FADE_THRESHOLD_SIZE:
+ pointParams.put(4+3, param);
+ break;
+ }
+ pointParamsDirty = true;
+ }
+ public void glPointParameterfv(int pname, float[] params, int params_offset) {
+ switch(pname) {
+ case GL2ES1.GL_POINT_DISTANCE_ATTENUATION:
+ pointParams.put(4+0, params[params_offset + 0]);
+ pointParams.put(4+1, params[params_offset + 1]);
+ pointParams.put(4+2, params[params_offset + 2]);
+ break;
+ }
+ pointParamsDirty = true;
+ }
+ public void glPointParameterfv(int pname, java.nio.FloatBuffer params) {
+ final int o = params.position();
+ switch(pname) {
+ case GL2ES1.GL_POINT_DISTANCE_ATTENUATION:
+ pointParams.put(4+0, params.get(o + 0));
+ pointParams.put(4+1, params.get(o + 1));
+ pointParams.put(4+2, params.get(o + 2));
+ break;
+ }
+ pointParamsDirty = true;
+ }
+
+ // private int[] pointTexObj = new int[] { 0 };
+
+ private void glDrawPoints(GL2ES2 gl, GLRunnable2<Object,Object> glDrawAction, Object args) {
+ if(gl.isGL2GL3()) {
+ gl.glEnable(GL2GL3.GL_VERTEX_PROGRAM_POINT_SIZE);
+ }
+ if(gl.isGL2ES1()) {
+ gl.glEnable(GL2ES1.GL_POINT_SPRITE);
+ }
+ loadShaderPoints(gl);
+ shaderState.attachShaderProgram(gl, shaderProgramPoints, true);
+ validate(gl, false); // sync uniforms
+
+ glDrawAction.run(gl, args);
+
+ if(gl.isGL2ES1()) {
+ gl.glDisable(GL2ES1.GL_POINT_SPRITE);
+ }
+ if(gl.isGL2GL3()) {
+ gl.glDisable(GL2GL3.GL_VERTEX_PROGRAM_POINT_SIZE);
+ }
+ shaderState.attachShaderProgram(gl, selectShaderProgram(gl, currentShaderSelectionMode), true);
+ }
+ private static final GLRunnable2<Object, Object> glDrawArraysAction = new GLRunnable2<Object,Object>() {
+ @Override
+ public Object run(GL gl, Object args) {
+ int[] _args = (int[])args;
+ gl.glDrawArrays(GL.GL_POINTS, _args[0], _args[1]);
+ return null;
+ }
+ };
+ private final void glDrawPointArrays(GL2ES2 gl, int first, int count) {
+ glDrawPoints(gl, glDrawArraysAction, new int[] { first, count });
+ }
+
+ //
+ // Lighting
+ //
- public void glLightfv(GL2ES2 gl, int light, int pname, java.nio.FloatBuffer params) {
+ public void glLightfv(GL2ES2 gl, int light, int pname, java.nio.FloatBuffer params) {
shaderState.useProgram(gl, true);
light -=GLLightingFunc.GL_LIGHT0;
if(0 <= light && light < MAX_LIGHTS) {
@@ -179,17 +472,14 @@ public class FixedFuncPipeline {
ud = shaderState.getUniform(mgl_LightSource+"["+light+"].quadraticAttenuation");
break;
default:
- if(verbose) {
- System.err.println("glLightfv pname not within [GL_AMBIENT GL_DIFFUSE GL_SPECULAR GL_POSITION GL_SPOT_DIRECTION]: "+pname);
- }
- return;
+ throw new GLException("glLightfv invalid pname: "+toHexString(pname));
}
if(null!=ud) {
ud.setData(params);
shaderState.uniform(gl, ud);
}
- } else if(verbose) {
- System.err.println("glLightfv light not within [0.."+MAX_LIGHTS+"]: "+light);
+ } else {
+ throw new GLException("glLightfv light not within [0.."+MAX_LIGHTS+"]: "+light);
}
}
@@ -201,10 +491,8 @@ public class FixedFuncPipeline {
case GL.GL_FRONT_AND_BACK:
break;
case GL.GL_BACK:
- if(verbose) {
- System.err.println("glMaterialfv face GL_BACK currently not supported");
- }
- break;
+ System.err.println("FixedFuncPipeline: Unimplemented glMaterialfv GL_BACK face");
+ return;
default:
}
@@ -214,7 +502,13 @@ public class FixedFuncPipeline {
ud = shaderState.getUniform(mgl_FrontMaterial+".ambient");
break;
case GLLightingFunc.GL_AMBIENT_AND_DIFFUSE:
- glMaterialfv(gl, face, GLLightingFunc.GL_AMBIENT, params);
+ {
+ ud = shaderState.getUniform(mgl_FrontMaterial+".ambient");
+ if(null!=ud) {
+ ud.setData(params);
+ shaderState.uniform(gl, ud);
+ }
+ }
// fall through intended ..
case GLLightingFunc.GL_DIFFUSE:
ud = shaderState.getUniform(mgl_FrontMaterial+".diffuse");
@@ -229,17 +523,20 @@ public class FixedFuncPipeline {
ud = shaderState.getUniform(mgl_FrontMaterial+".shininess");
break;
default:
- if(verbose) {
- System.err.println("glMaterialfv pname not within [GL_AMBIENT GL_DIFFUSE GL_SPECULAR GL_EMISSION GL_SHININESS]: "+pname);
- }
- return;
+ throw new GLException("glMaterialfv invalid pname: "+toHexString(pname));
}
if(null!=ud) {
ud.setData(params);
shaderState.uniform(gl, ud);
+ } else if(verbose) {
+
}
}
+ //
+ // Misc States
+ //
+
public void glShadeModel(GL2ES2 gl, int mode) {
shaderState.useProgram(gl, true);
GLUniformData ud = shaderState.getUniform(mgl_ShadeModel);
@@ -249,24 +546,72 @@ public class FixedFuncPipeline {
}
}
- public void glActiveTexture(GL2ES2 gl, int textureUnit) {
- textureUnit -= GL.GL_TEXTURE0;
- if(0 <= textureUnit && textureUnit<MAX_TEXTURE_UNITS) {
- shaderState.useProgram(gl, true);
- GLUniformData ud;
- ud = shaderState.getUniform(mgl_ActiveTexture);
- if(null!=ud) {
- ud.setData(textureUnit);
- shaderState.uniform(gl, ud);
+ /** ES2 supports CullFace implicit
+ public void glCullFace(int faceName) {
+ int _cullFace;
+ switch(faceName) {
+ case GL.GL_FRONT:
+ _cullFace = 1;
+ break;
+ case GL.GL_BACK:
+ _cullFace = 2;
+ break;
+ case GL.GL_FRONT_AND_BACK:
+ _cullFace = 3;
+ break;
+ default:
+ throw new GLException("glCullFace invalid faceName: "+toHexString(faceName));
+ }
+ if(0 < _cullFace) {
+ if(0>cullFace) {
+ _cullFace *= -1;
}
- ud = shaderState.getUniform(mgl_ActiveTextureIdx);
- if(null!=ud) {
- ud.setData(textureUnit);
- shaderState.uniform(gl, ud);
+ if(cullFace != _cullFace) {
+ cullFace = _cullFace;
+ cullFaceDirty=true;
+ }
+ }
+ } */
+
+ public void glAlphaFunc(int func, float ref) {
+ int _func;
+ switch(func) {
+ case GL.GL_NEVER:
+ _func = 1;
+ break;
+ case GL.GL_LESS:
+ _func = 2;
+ break;
+ case GL.GL_EQUAL:
+ _func = 3;
+ break;
+ case GL.GL_LEQUAL:
+ _func = 4;
+ break;
+ case GL.GL_GREATER:
+ _func = 5;
+ break;
+ case GL.GL_NOTEQUAL:
+ _func = 6;
+ break;
+ case GL.GL_GEQUAL:
+ _func = 7;
+ break;
+ case GL.GL_ALWAYS:
+ _func = 8;
+ break;
+ default:
+ throw new GLException("glAlphaFunc invalid func: "+toHexString(func));
+ }
+ if(0 < _func) {
+ if(0>alphaTestFunc) {
+ _func *= -1;
+ }
+ if( alphaTestFunc != _func || alphaTestRef != ref ) {
+ alphaTestFunc = _func;
+ alphaTestRef = ref;
+ alphaTestDirty=true;
}
- activeTextureUnit = textureUnit;
- } else {
- throw new GLException("glActivateTexture textureUnit not within GL_TEXTURE0 + [0.."+MAX_TEXTURE_UNITS+"]: "+textureUnit);
}
}
@@ -275,20 +620,61 @@ public class FixedFuncPipeline {
* eg this call must not be passed to an underlying ES2 implementation.
* true if this call shall be passed to an underlying GL2ES2/ES2 implementation as well.
*/
- public boolean glEnable(GL2ES2 gl, int cap, boolean enable) {
+ public boolean glEnable(int cap, boolean enable) {
switch(cap) {
- case GL.GL_TEXTURE_2D:
- textureEnabled=enable;
+ case GL.GL_BLEND:
+ case GL.GL_DEPTH_TEST:
+ case GL.GL_DITHER:
+ case GL.GL_POLYGON_OFFSET_FILL:
+ case GL.GL_SAMPLE_ALPHA_TO_COVERAGE:
+ case GL.GL_SAMPLE_COVERAGE:
+ case GL.GL_SCISSOR_TEST:
+ case GL.GL_STENCIL_TEST:
+ return true;
+
+ case GL.GL_CULL_FACE:
+ /** ES2 supports CullFace implicit
+ final int _cullFace;
+ if(0>cullFace && enable || 0<cullFace && !enable) {
+ _cullFace = cullFace * -1;
+ } else {
+ _cullFace = cullFace;
+ }
+ if(_cullFace != cullFace) {
+ cullFaceDirty=true;
+ cullFace=_cullFace;
+ } */
return true;
+
+ case GL.GL_TEXTURE_2D:
+ glEnableTexture(enable, activeTextureUnit);
+ return false;
+
case GLLightingFunc.GL_LIGHTING:
lightingEnabled=enable;
return false;
- case GL.GL_CULL_FACE:
- cullFace=Math.abs(cullFace);
- if(!enable) {
- cullFace*=-1;
+
+ case GL2ES1.GL_ALPHA_TEST:
+ final int _alphaTestFunc;
+ if(0>alphaTestFunc && enable || 0<alphaTestFunc && !enable) {
+ _alphaTestFunc = alphaTestFunc * -1;
+ } else {
+ _alphaTestFunc = alphaTestFunc;
}
- return true;
+ if(_alphaTestFunc != alphaTestFunc) {
+ alphaTestDirty=true;
+ alphaTestFunc=_alphaTestFunc;
+ }
+ return false;
+
+ case GL2ES1.GL_POINT_SMOOTH:
+ pointParams.put(1, enable ? 1.0f : 0.0f);
+ pointParamsDirty = true;
+ return false;
+
+ case GL2ES1.GL_POINT_SPRITE:
+ // gl_PointCoord always enabled
+ return false;
}
int light = cap - GLLightingFunc.GL_LIGHT0;
@@ -299,52 +685,182 @@ public class FixedFuncPipeline {
return false;
}
}
- return true; // pass it on ..
+ System.err.println("FixedFunctionPipeline: "+(enable ? "glEnable" : "glDisable")+" "+toHexString(cap)+" not handled in emulation and not supported in ES2");
+ return false; // ignore!
}
- public void glCullFace(GL2ES2 gl, int faceName) {
- switch(faceName) {
- case GL.GL_FRONT:
- faceName = 1; break;
- case GL.GL_BACK:
- faceName = 2; break;
- case GL.GL_FRONT_AND_BACK:
- faceName = 3; break;
+ //
+ // Draw
+ //
+
+ public void glDrawArrays(GL2ES2 gl, int mode, int first, int count) {
+ switch(mode) {
+ case GL2.GL_QUAD_STRIP:
+ mode=GL.GL_TRIANGLE_STRIP;
+ break;
+ case GL2.GL_POLYGON:
+ mode=GL.GL_TRIANGLE_FAN;
+ break;
+ case GL2ES1.GL_POINTS:
+ glDrawPointArrays(gl, first, count);
+ return;
}
- if(0>cullFace) {
- faceName *= -1;
+ validate(gl, true);
+ if ( GL2.GL_QUADS == mode && !gl.isGL2() ) {
+ for (int j = first; j < count - 3; j += 4) {
+ gl.glDrawArrays(GL.GL_TRIANGLE_FAN, j, 4);
+ }
+ } else {
+ gl.glDrawArrays(mode, first, count);
}
- cullFace = faceName;
}
-
- public void validate(GL2ES2 gl) {
- shaderState.useProgram(gl, true);
+ public void glDrawElements(GL2ES2 gl, int mode, int count, int type, java.nio.Buffer indices) {
+ validate(gl, true);
+ if ( GL2.GL_QUADS == mode && !gl.isGL2() ) {
+ final int idx0 = indices.position();
+
+ if( GL.GL_UNSIGNED_BYTE == type ) {
+ final ByteBuffer b = (ByteBuffer) indices;
+ for (int j = 0; j < count; j++) {
+ gl.glDrawArrays(GL.GL_TRIANGLE_FAN, (int)(0x000000ff & b.get(idx0+j)), 4);
+ }
+ } else if( GL.GL_UNSIGNED_SHORT == type ){
+ final ShortBuffer b = (ShortBuffer) indices;
+ for (int j = 0; j < count; j++) {
+ gl.glDrawArrays(GL.GL_TRIANGLE_FAN, (int)(0x0000ffff & b.get(idx0+j)), 4);
+ }
+ } else {
+ final IntBuffer b = (IntBuffer) indices;
+ for (int j = 0; j < count; j++) {
+ gl.glDrawArrays(GL.GL_TRIANGLE_FAN, (int)(0xffffffff & b.get(idx0+j)), 4);
+ }
+ }
+ } else if( GL2ES1.GL_POINTS != mode ) {
+ gl.glDrawElements(mode, count, type, indices);
+ } else {
+ // FIXME GL_POINTS !
+ gl.glDrawElements(mode, count, type, indices);
+ }
+ }
+ public void glDrawElements(GL2ES2 gl, int mode, int count, int type, long indices_buffer_offset) {
+ validate(gl, true);
+ if ( GL2.GL_QUADS == mode && !gl.isGL2() ) {
+ throw new GLException("Cannot handle indexed QUADS on !GL2 w/ VBO due to lack of CPU index access");
+ } else if( GL2ES1.GL_POINTS != mode ) {
+ // FIXME GL_POINTS !
+ gl.glDrawElements(mode, count, type, indices_buffer_offset);
+ } else {
+ gl.glDrawElements(mode, count, type, indices_buffer_offset);
+ }
+ }
+
+ private final int textureEnabledCount() {
+ int n=0;
+ for(int i=MAX_TEXTURE_UNITS-1; i>=0; i--) {
+ if( 0 != textureEnabled.get(i) ) {
+ n++;
+ }
+ }
+ return n;
+ }
+
+ public void validate(GL2ES2 gl, boolean selectShader) {
+ if( selectShader ) {
+ if( ShaderSelectionMode.AUTO == requestedShaderSelectionMode) {
+ final ShaderSelectionMode newMode;
+
+ // pre-validate shader switch
+ if( 0 != textureEnabledBits ) {
+ if(lightingEnabled) {
+ newMode = ShaderSelectionMode.COLOR_TEXTURE8_LIGHT_PER_VERTEX;
+ } else {
+ final int n = textureEnabledCount();
+ if( 4 < n ) {
+ newMode = ShaderSelectionMode.COLOR_TEXTURE8;
+ } else if ( 2 < n ) {
+ newMode = ShaderSelectionMode.COLOR_TEXTURE4;
+ } else {
+ newMode = ShaderSelectionMode.COLOR_TEXTURE2;
+ }
+ }
+ } else {
+ if(lightingEnabled) {
+ newMode = ShaderSelectionMode.COLOR_LIGHT_PER_VERTEX;
+ } else {
+ newMode = ShaderSelectionMode.COLOR;
+ }
+ }
+ shaderState.attachShaderProgram(gl, selectShaderProgram(gl, newMode), true); // enables shader-program implicit
+ } else {
+ shaderState.useProgram(gl, true);
+ }
+ }
+
GLUniformData ud;
- if(pmvMatrix.update()) {
+ if( pmvMatrix.update() ) {
ud = shaderState.getUniform(mgl_PMVMatrix);
if(null!=ud) {
+ final FloatBuffer m;
+ if(ShaderSelectionMode.COLOR_TEXTURE8_LIGHT_PER_VERTEX == currentShaderSelectionMode ||
+ ShaderSelectionMode.COLOR_LIGHT_PER_VERTEX== currentShaderSelectionMode ) {
+ m = pmvMatrix.glGetPMvMvitMatrixf();
+ } else {
+ m = pmvMatrix.glGetPMvMatrixf();
+ }
+ if(m != ud.getBuffer()) {
+ ud.setData(m);
+ }
// same data object ..
shaderState.uniform(gl, ud);
} else {
throw new GLException("Failed to update: mgl_PMVMatrix");
}
}
- ud = shaderState.getUniform(mgl_ColorEnabled);
- if(null!=ud) {
- int ca = (shaderState.isVertexAttribArrayEnabled(GLPointerFuncUtil.mgl_Color)==true)?1:0;
- if(ca!=ud.intValue()) {
- ud.setData(ca);
- shaderState.uniform(gl, ud);
+ if(colorVAEnabledDirty) {
+ ud = shaderState.getUniform(mgl_ColorEnabled);
+ if(null!=ud) {
+ int ca = true == shaderState.isVertexAttribArrayEnabled(GLPointerFuncUtil.mgl_Color) ? 1 : 0 ;
+ if(ca!=ud.intValue()) {
+ ud.setData(ca);
+ shaderState.uniform(gl, ud);
+ }
+ } else {
+ throw new GLException("Failed to update: mgl_ColorEnabled");
}
+ colorVAEnabledDirty = false;
}
- ud = shaderState.getUniform(mgl_CullFace);
- if(null!=ud) {
- if(cullFace!=ud.intValue()) {
+ /** ES2 supports CullFace implicit
+ if(cullFaceDirty) {
+ ud = shaderState.getUniform(mgl_CullFace);
+ if(null!=ud) {
ud.setData(cullFace);
shaderState.uniform(gl, ud);
}
- }
+ cullFaceDirty = false;
+ } */
+ if(alphaTestDirty) {
+ ud = shaderState.getUniform(mgl_AlphaTestFunc);
+ if(null!=ud) {
+ ud.setData(alphaTestFunc);
+ shaderState.uniform(gl, ud);
+ }
+ ud = shaderState.getUniform(mgl_AlphaTestRef);
+ if(null!=ud) {
+ ud.setData(alphaTestRef);
+ shaderState.uniform(gl, ud);
+ }
+ alphaTestDirty = false;
+ }
+ if(pointParamsDirty) {
+ ud = shaderState.getUniform(mgl_PointParams);
+ if(null!=ud) {
+ // same data object
+ shaderState.uniform(gl, ud);
+ }
+ pointParamsDirty = false;
+ }
+
if(lightsEnabledDirty) {
ud = shaderState.getUniform(mgl_LightsEnabled);
if(null!=ud) {
@@ -354,102 +870,230 @@ public class FixedFuncPipeline {
lightsEnabledDirty=false;
}
- if(textureCoordsEnabledDirty) {
+ if(textureCoordEnabledDirty) {
ud = shaderState.getUniform(mgl_TexCoordEnabled);
if(null!=ud) {
// same data object
shaderState.uniform(gl, ud);
}
- textureCoordsEnabledDirty=false;
- }
+ textureCoordEnabledDirty=false;
+ }
- if(textureEnabled) {
- if(lightingEnabled) {
- shaderState.attachShaderProgram(gl, shaderProgramColorTextureLight, true);
- } else {
- shaderState.attachShaderProgram(gl, shaderProgramColorTexture, true);
+ if(textureEnvModeDirty) {
+ ud = shaderState.getUniform(mgl_TexEnvMode);
+ if(null!=ud) {
+ // same data object
+ shaderState.uniform(gl, ud);
}
- } else {
- if(lightingEnabled) {
- shaderState.attachShaderProgram(gl, shaderProgramColorLight, true);
- } else {
- shaderState.attachShaderProgram(gl, shaderProgramColor, true);
+ textureEnvModeDirty = false;
+ }
+
+ if(textureFormatDirty) {
+ for(int i = 0; i<MAX_TEXTURE_UNITS; i++) {
+ textureFormat.put(i, texID2Format.get(boundTextureObject[i]));
+ }
+ ud = shaderState.getUniform(mgl_TexFormat);
+ if(null!=ud) {
+ // same data object
+ shaderState.uniform(gl, ud);
+ }
+ textureFormatDirty = false;
+ }
+ if(textureEnabledDirty) {
+ ud = shaderState.getUniform(mgl_TextureEnabled);
+ if(null!=ud) {
+ // same data object
+ shaderState.uniform(gl, ud);
}
+ textureEnabledDirty=false;
}
- if(DEBUG) {
- System.err.println("validate: "+this);
+
+ if(verbose) {
+ System.err.println("validate: "+toString(null, DEBUG).toString());
}
}
- public String toString() {
- return "FixedFuncPipeline[pmv: "+pmvMatrix+
- ", textureEnabled: "+textureEnabled+
- ", textureCoordsEnabled: "+textureCoordsEnabled+
- ", lightingEnabled: "+lightingEnabled+
- ", lightsEnabled: "+lightsEnabled+
- "\n\t, shaderProgramColor: "+shaderProgramColor+
- "\n\t, shaderProgramColorTexture: "+shaderProgramColorTexture+
- "\n\t, shaderProgramColorLight: "+shaderProgramColorLight+
- "\n\t, shaderProgramColorTextureLight: "+shaderProgramColorTextureLight+
- "\n\t, ShaderState: "+shaderState+
- "]";
- }
-
- protected void init(GL2ES2 gl, PMVMatrix pmvMatrix, Class shaderRootClass, String shaderSrcRoot, String shaderBinRoot,
- String vertexColorFile,
- String vertexColorLightFile,
- String fragmentColorFile,
- String fragmentColorTextureFile)
- {
- if(null==pmvMatrix) {
- throw new GLException("PMVMatrix is null");
+ public StringBuilder toString(StringBuilder sb, boolean alsoUnlocated) {
+ if(null == sb) {
+ sb = new StringBuilder();
}
- this.pmvMatrix=pmvMatrix;
- this.shaderState=new ShaderState();
- this.shaderState.setVerbose(verbose);
- ShaderCode vertexColor, vertexColorLight, fragmentColor, fragmentColorTexture;
-
- vertexColor = ShaderCode.create( gl, gl.GL_VERTEX_SHADER, shaderRootClass, shaderSrcRoot,
- shaderBinRoot, vertexColorFile, false);
-
- vertexColorLight = ShaderCode.create( gl, gl.GL_VERTEX_SHADER, shaderRootClass, shaderSrcRoot,
- shaderBinRoot, vertexColorLightFile, false);
-
- fragmentColor = ShaderCode.create( gl, gl.GL_FRAGMENT_SHADER, shaderRootClass, shaderSrcRoot,
- shaderBinRoot, fragmentColorFile, false);
+ sb.append("FixedFuncPipeline[");
+ sb.append(", textureEnabled: "+toHexString(textureEnabledBits)+", "); Buffers.toString(sb, null, textureEnabled);
+ sb.append("\n\t, textureCoordEnabled: "); Buffers.toString(sb, null, textureCoordEnabled);
+ sb.append("\n\t lightingEnabled: "+lightingEnabled);
+ sb.append(", lightsEnabled: "); Buffers.toString(sb, null, lightsEnabled);
+ sb.append("\n\t, shaderProgramColor: "+shaderProgramColor);
+ sb.append("\n\t, shaderProgramColorTexture2: "+shaderProgramColorTexture2);
+ sb.append("\n\t, shaderProgramColorTexture4: "+shaderProgramColorTexture4);
+ sb.append("\n\t, shaderProgramColorTexture8: "+shaderProgramColorTexture8);
+ sb.append("\n\t, shaderProgramColorLight: "+shaderProgramColorLight);
+ sb.append("\n\t, shaderProgramColorTexture8Light: "+shaderProgramColorTexture8Light);
+ sb.append("\n\t, ShaderState: ");
+ shaderState.toString(sb, alsoUnlocated);
+ sb.append("]");
+ return sb;
+ }
+ public String toString() {
+ return toString(null, DEBUG).toString();
+ }
- fragmentColorTexture = ShaderCode.create( gl, gl.GL_FRAGMENT_SHADER, shaderRootClass, shaderSrcRoot,
- shaderBinRoot, fragmentColorTextureFile, false);
+ private static final String constMaxTextures0 = "#define MAX_TEXTURE_UNITS 0\n";
+ private static final String constMaxTextures2 = "#define MAX_TEXTURE_UNITS 2\n";
+ private static final String constMaxTextures4 = "#define MAX_TEXTURE_UNITS 4\n";
+ private static final String constMaxTextures8 = "#define MAX_TEXTURE_UNITS 8\n";
+
+ private final void customizeShader(GL2ES2 gl, ShaderCode vp, ShaderCode fp, String maxTextureDefine) {
+ int rsVpPos = vp.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_vp);
+ int rsFpPos = fp.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_fp);
+ vp.insertShaderSource(0, rsVpPos, maxTextureDefine);
+ fp.insertShaderSource(0, rsFpPos, maxTextureDefine);
+ }
- shaderProgramColor = new ShaderProgram();
- shaderProgramColor.add(vertexColor);
- shaderProgramColor.add(fragmentColor);
- if(!shaderProgramColor.link(gl, System.err)) {
- throw new GLException("Couldn't link VertexColor program: "+shaderProgramColor);
+ private final void loadShaderPoints(GL2ES2 gl) {
+ if( null != shaderProgramPoints ) {
+ return;
}
-
- shaderProgramColorTexture = new ShaderProgram();
- shaderProgramColorTexture.add(vertexColor);
- shaderProgramColorTexture.add(fragmentColorTexture);
- if(!shaderProgramColorTexture.link(gl, System.err)) {
- throw new GLException("Couldn't link VertexColorTexture program: "+shaderProgramColorTexture);
+
+ final ShaderCode vp = ShaderCode.create( gl, GL2ES2.GL_VERTEX_SHADER, shaderRootClass, shaderSrcRoot,
+ shaderBinRoot, shaderPointFileDef, true);
+ final ShaderCode fp = ShaderCode.create( gl, GL2ES2.GL_FRAGMENT_SHADER, shaderRootClass, shaderSrcRoot,
+ shaderBinRoot, shaderPointFileDef, true);
+ customizeShader(gl, vp, fp, constMaxTextures2);
+ shaderProgramPoints = new ShaderProgram();
+ shaderProgramPoints.add(vp);
+ shaderProgramPoints.add(fp);
+ if(!shaderProgramPoints.link(gl, System.err)) {
+ throw new GLException("Couldn't link VertexColor program: "+shaderProgramPoints);
+ }
+ }
+
+ private final void loadShader(GL2ES2 gl, ShaderSelectionMode mode) {
+ final boolean loadColor = ShaderSelectionMode.COLOR == mode;
+ final boolean loadColorTexture2 = ShaderSelectionMode.COLOR_TEXTURE2 == mode;
+ final boolean loadColorTexture4 = ShaderSelectionMode.COLOR_TEXTURE4 == mode;
+ final boolean loadColorTexture8 = ShaderSelectionMode.COLOR_TEXTURE8 == mode;
+ final boolean loadColorTexture = loadColorTexture2 || loadColorTexture4 || loadColorTexture8 ;
+ final boolean loadColorLightPerVertex = ShaderSelectionMode.COLOR_LIGHT_PER_VERTEX == mode;
+ final boolean loadColorTexture8LightPerVertex = ShaderSelectionMode.COLOR_TEXTURE8_LIGHT_PER_VERTEX == mode;
+
+ if( null != shaderProgramColor && loadColor ||
+ null != shaderProgramColorTexture2 && loadColorTexture2 ||
+ null != shaderProgramColorTexture4 && loadColorTexture4 ||
+ null != shaderProgramColorTexture8 && loadColorTexture8 ||
+ null != shaderProgramColorLight && loadColorLightPerVertex ||
+ null != shaderProgramColorTexture8Light && loadColorTexture8LightPerVertex ) {
+ return;
}
-
- shaderProgramColorLight = new ShaderProgram();
- shaderProgramColorLight.add(vertexColorLight);
- shaderProgramColorLight.add(fragmentColor);
- if(!shaderProgramColorLight.link(gl, System.err)) {
- throw new GLException("Couldn't link VertexColorLight program: "+shaderProgramColorLight);
+
+ if( loadColor ) {
+ final ShaderCode vp = ShaderCode.create( gl, GL2ES2.GL_VERTEX_SHADER, shaderRootClass, shaderSrcRoot,
+ shaderBinRoot, vertexColorFile, true);
+ final ShaderCode fp = ShaderCode.create( gl, GL2ES2.GL_FRAGMENT_SHADER, shaderRootClass, shaderSrcRoot,
+ shaderBinRoot, fragmentColorFile, true);
+ customizeShader(gl, vp, fp, constMaxTextures0);
+ shaderProgramColor = new ShaderProgram();
+ shaderProgramColor.add(vp);
+ shaderProgramColor.add(fp);
+ if(!shaderProgramColor.link(gl, System.err)) {
+ throw new GLException("Couldn't link VertexColor program: "+shaderProgramColor);
+ }
+ } else if( loadColorTexture ) {
+ final ShaderCode vp = ShaderCode.create( gl, GL2ES2.GL_VERTEX_SHADER, shaderRootClass, shaderSrcRoot, shaderBinRoot, vertexColorFile, true);
+ final ShaderCode fp = ShaderCode.create( gl, GL2ES2.GL_FRAGMENT_SHADER, shaderRootClass, shaderSrcRoot,
+ shaderBinRoot, fragmentColorTextureFile, true);
+
+ if( loadColorTexture2 ) {
+ customizeShader(gl, vp, fp, constMaxTextures2);
+ shaderProgramColorTexture2 = new ShaderProgram();
+ shaderProgramColorTexture2.add(vp);
+ shaderProgramColorTexture2.add(fp);
+ if(!shaderProgramColorTexture2.link(gl, System.err)) {
+ throw new GLException("Couldn't link VertexColorTexture2 program: "+shaderProgramColorTexture2);
+ }
+ } else if( loadColorTexture4 ) {
+ customizeShader(gl, vp, fp, constMaxTextures4);
+ shaderProgramColorTexture4 = new ShaderProgram();
+ shaderProgramColorTexture4.add(vp);
+ shaderProgramColorTexture4.add(fp);
+ if(!shaderProgramColorTexture4.link(gl, System.err)) {
+ throw new GLException("Couldn't link VertexColorTexture4 program: "+shaderProgramColorTexture4);
+ }
+ } else if( loadColorTexture8 ) {
+ customizeShader(gl, vp, fp, constMaxTextures8);
+ shaderProgramColorTexture8 = new ShaderProgram();
+ shaderProgramColorTexture8.add(vp);
+ shaderProgramColorTexture8.add(fp);
+ if(!shaderProgramColorTexture8.link(gl, System.err)) {
+ throw new GLException("Couldn't link VertexColorTexture8 program: "+shaderProgramColorTexture8);
+ }
+ }
+ } else if( loadColorLightPerVertex ) {
+ final ShaderCode vp = ShaderCode.create( gl, GL2ES2.GL_VERTEX_SHADER, shaderRootClass, shaderSrcRoot,
+ shaderBinRoot, vertexColorLightFile, true);
+ final ShaderCode fp = ShaderCode.create( gl, GL2ES2.GL_FRAGMENT_SHADER, shaderRootClass, shaderSrcRoot,
+ shaderBinRoot, fragmentColorFile, true);
+ customizeShader(gl, vp, fp, constMaxTextures0);
+ shaderProgramColorLight = new ShaderProgram();
+ shaderProgramColorLight.add(vp);
+ shaderProgramColorLight.add(fp);
+ if(!shaderProgramColorLight.link(gl, System.err)) {
+ throw new GLException("Couldn't link VertexColorLight program: "+shaderProgramColorLight);
+ }
+ } else if( loadColorTexture8LightPerVertex ) {
+ final ShaderCode vp = ShaderCode.create( gl, GL2ES2.GL_VERTEX_SHADER, shaderRootClass, shaderSrcRoot,
+ shaderBinRoot, vertexColorLightFile, true);
+ final ShaderCode fp = ShaderCode.create( gl, GL2ES2.GL_FRAGMENT_SHADER, shaderRootClass, shaderSrcRoot,
+ shaderBinRoot, fragmentColorTextureFile, true);
+ customizeShader(gl, vp, fp, constMaxTextures8);
+ shaderProgramColorTexture8Light = new ShaderProgram();
+ shaderProgramColorTexture8Light.add(vp);
+ shaderProgramColorTexture8Light.add(fp);
+ if(!shaderProgramColorTexture8Light.link(gl, System.err)) {
+ throw new GLException("Couldn't link VertexColorLight program: "+shaderProgramColorTexture8Light);
+ }
}
-
- shaderProgramColorTextureLight = new ShaderProgram();
- shaderProgramColorTextureLight.add(vertexColorLight);
- shaderProgramColorTextureLight.add(fragmentColorTexture);
- if(!shaderProgramColorTextureLight.link(gl, System.err)) {
- throw new GLException("Couldn't link VertexColorLight program: "+shaderProgramColorTextureLight);
+ }
+
+ private ShaderProgram selectShaderProgram(GL2ES2 gl, ShaderSelectionMode newMode) {
+ if(ShaderSelectionMode.AUTO == newMode) {
+ newMode = ShaderSelectionMode.COLOR;
+ }
+ loadShader(gl, newMode);
+ final ShaderProgram sp;
+ switch(newMode) {
+ case COLOR_LIGHT_PER_VERTEX:
+ sp = shaderProgramColorLight;
+ break;
+ case COLOR_TEXTURE2:
+ sp = shaderProgramColorTexture2;
+ break;
+ case COLOR_TEXTURE4:
+ sp = shaderProgramColorTexture4;
+ break;
+ case COLOR_TEXTURE8:
+ sp = shaderProgramColorTexture8;
+ break;
+ case COLOR_TEXTURE8_LIGHT_PER_VERTEX:
+ sp = shaderProgramColorTexture8Light;
+ break;
+ case COLOR:
+ default:
+ sp = shaderProgramColor;
}
+ currentShaderSelectionMode = newMode;
+ return sp;
+ }
+
+ private void init(GL2ES2 gl, ShaderSelectionMode mode, PMVMatrix pmvMatrix) {
+ if(null==pmvMatrix) {
+ throw new GLException("PMVMatrix is null");
+ }
+ this.pmvMatrix=pmvMatrix;
+ this.requestedShaderSelectionMode = mode;
+ this.shaderState=new ShaderState();
+ this.shaderState.setVerbose(verbose);
- shaderState.attachShaderProgram(gl, shaderProgramColor, true);
+ shaderState.attachShaderProgram(gl, selectShaderProgram(gl, requestedShaderSelectionMode), true);
// mandatory ..
if(!shaderState.uniform(gl, new GLUniformData(mgl_PMVMatrix, 4, 4, pmvMatrix.glGetPMvMvitMatrixf()))) {
@@ -457,16 +1101,26 @@ public class FixedFuncPipeline {
}
shaderState.uniform(gl, new GLUniformData(mgl_ColorEnabled, 0));
- shaderState.uniform(gl, new GLUniformData(mgl_ColorStatic, 4, zero4f));
- shaderState.uniform(gl, new GLUniformData(mgl_TexCoordEnabled, 1, textureCoordsEnabled));
- shaderState.uniform(gl, new GLUniformData(mgl_ActiveTexture, activeTextureUnit));
- shaderState.uniform(gl, new GLUniformData(mgl_ActiveTextureIdx, activeTextureUnit));
+ shaderState.uniform(gl, new GLUniformData(mgl_ColorStatic, 4, colorStatic));
+
+ texID2Format.setKeyNotFoundValue(0);
+ shaderState.uniform(gl, new GLUniformData(mgl_TexCoordEnabled, 1, textureCoordEnabled));
+ shaderState.uniform(gl, new GLUniformData(mgl_TexEnvMode, 1, textureEnvMode));
+ shaderState.uniform(gl, new GLUniformData(mgl_TexFormat, 1, textureFormat));
+ shaderState.uniform(gl, new GLUniformData(mgl_TextureEnabled, 1, textureEnabled));
+ for(int i=0; i<MAX_TEXTURE_UNITS; i++) {
+ shaderState.uniform(gl, new GLUniformData(mgl_Texture+i, i));
+ }
shaderState.uniform(gl, new GLUniformData(mgl_ShadeModel, 0));
- shaderState.uniform(gl, new GLUniformData(mgl_CullFace, cullFace));
+ /** ES2 supports CullFace implicit
+ shaderState.uniform(gl, new GLUniformData(mgl_CullFace, cullFace)); */
+ shaderState.uniform(gl, new GLUniformData(mgl_AlphaTestFunc, alphaTestFunc));
+ shaderState.uniform(gl, new GLUniformData(mgl_AlphaTestRef, alphaTestRef));
+ shaderState.uniform(gl, new GLUniformData(mgl_PointParams, 4, pointParams));
for(int i=0; i<MAX_LIGHTS; i++) {
shaderState.uniform(gl, new GLUniformData(mgl_LightSource+"["+i+"].ambient", 4, defAmbient));
- shaderState.uniform(gl, new GLUniformData(mgl_LightSource+"["+i+"].diffuse", 4, defDiffuse));
- shaderState.uniform(gl, new GLUniformData(mgl_LightSource+"["+i+"].specular", 4, defSpecular));
+ shaderState.uniform(gl, new GLUniformData(mgl_LightSource+"["+i+"].diffuse", 4, 0==i ? one4f : defDiffuseN));
+ shaderState.uniform(gl, new GLUniformData(mgl_LightSource+"["+i+"].specular", 4, 0==i ? one4f : defSpecularN));
shaderState.uniform(gl, new GLUniformData(mgl_LightSource+"["+i+"].position", 4, defPosition));
shaderState.uniform(gl, new GLUniformData(mgl_LightSource+"["+i+"].spotDirection", 3, defSpotDir));
shaderState.uniform(gl, new GLUniformData(mgl_LightSource+"["+i+"].spotExponent", defSpotExponent));
@@ -474,7 +1128,8 @@ public class FixedFuncPipeline {
shaderState.uniform(gl, new GLUniformData(mgl_LightSource+"["+i+"].constantAttenuation", defConstantAtten));
shaderState.uniform(gl, new GLUniformData(mgl_LightSource+"["+i+"].linearAttenuation", defLinearAtten));
shaderState.uniform(gl, new GLUniformData(mgl_LightSource+"["+i+"].quadraticAttenuation", defQuadraticAtten));
- }
+ }
+ shaderState.uniform(gl, new GLUniformData(mgl_LightModel+".ambient", 4, defLightModelAmbient));
shaderState.uniform(gl, new GLUniformData(mgl_LightsEnabled, 1, lightsEnabled));
shaderState.uniform(gl, new GLUniformData(mgl_FrontMaterial+".ambient", 4, defMatAmbient));
shaderState.uniform(gl, new GLUniformData(mgl_FrontMaterial+".diffuse", 4, defMatDiffuse));
@@ -483,70 +1138,121 @@ public class FixedFuncPipeline {
shaderState.uniform(gl, new GLUniformData(mgl_FrontMaterial+".shininess", defMatShininess));
shaderState.useProgram(gl, false);
+ if(verbose) {
+ System.err.println("init: "+toString(null, DEBUG).toString());
+ }
}
- protected static final boolean DEBUG=false;
- protected boolean verbose=false;
+ private String toHexString(int i) {
+ return "0x"+Integer.toHexString(i);
+ }
+
+ protected boolean verbose = DEBUG;
- protected boolean textureEnabled=false;
- protected IntBuffer textureCoordsEnabled = Buffers.newDirectIntBuffer(new int[] { 0, 0, 0, 0, 0, 0, 0, 0 });
- protected boolean textureCoordsEnabledDirty = false;
- protected int activeTextureUnit=0;
+ private final FloatBuffer colorStatic = Buffers.copyFloatBuffer(one4f);
+
+ private int activeTextureUnit=0;
+ private int clientActiveTextureUnit=0;
+ private final IntIntHashMap texID2Format = new IntIntHashMap();
+ private final int[] boundTextureObject = new int[] { 0, 0, 0, 0, 0, 0, 0, 0 }; // per unit
+ private int textureEnabledBits = 0;
+ private final IntBuffer textureEnabled = Buffers.newDirectIntBuffer(new int[] { 0, 0, 0, 0, 0, 0, 0, 0 }); // per unit
+ private boolean textureEnabledDirty = false;
+ private final IntBuffer textureCoordEnabled = Buffers.newDirectIntBuffer(new int[] { 0, 0, 0, 0, 0, 0, 0, 0 }); // per unit
+ private boolean textureCoordEnabledDirty = false;
+ // textureEnvMode: 1 GL_ADD, 2 GL_MODULATE (default), 3 GL_DECAL, 4 GL_BLEND, 5 GL_REPLACE, 6 GL_COMBINE
+ private final IntBuffer textureEnvMode = Buffers.newDirectIntBuffer(new int[] { 2, 2, 2, 2, 2, 2, 2, 2 });
+ private boolean textureEnvModeDirty = false;
+ private final IntBuffer textureFormat = Buffers.newDirectIntBuffer(new int[] { 0, 0, 0, 0, 0, 0, 0, 0 }); // per unit
+ private boolean textureFormatDirty = false;
- protected int cullFace=-2; // <=0 disabled, 1: front, 2: back (default, but disabled), 3: front & back
+ /** ES2 supports CullFace implicit
+ private int cullFace=-2; // <=0 disabled, 1 GL_FRONT, 2 GL_BACK (default) and 3 GL_FRONT_AND_BACK
+ private boolean cullFaceDirty = false;
+ private static final String mgl_CullFace = "mgl_CullFace"; // 1i (lowp int) */
- protected boolean lightingEnabled=false;
- protected IntBuffer lightsEnabled = Buffers.newDirectIntBuffer(new int[] { 0, 0, 0, 0, 0, 0, 0, 0 });
- protected boolean lightsEnabledDirty = false;
+ private boolean colorVAEnabledDirty = false;
+ private boolean lightingEnabled=false;
+ private final IntBuffer lightsEnabled = Buffers.newDirectIntBuffer(new int[] { 0, 0, 0, 0, 0, 0, 0, 0 });
+ private boolean lightsEnabledDirty = false;
- protected PMVMatrix pmvMatrix;
- protected ShaderState shaderState;
- protected ShaderProgram shaderProgramColor;
- protected ShaderProgram shaderProgramColorTexture;
- protected ShaderProgram shaderProgramColorLight;
- protected ShaderProgram shaderProgramColorTextureLight;
+ private boolean alphaTestDirty=false;
+ private int alphaTestFunc=-8; // <=0 disabled; 1 GL_NEVER, 2 GL_LESS, 3 GL_EQUAL, 4 GL_LEQUAL, 5 GL_GREATER, 6 GL_NOTEQUAL, 7 GL_GEQUAL, and 8 GL_ALWAYS (default)
+ private float alphaTestRef=0f;
+
+ private boolean pointParamsDirty = false;
+ /** ( pointSize, pointSmooth, attn. pointMinSize, attn. pointMaxSize ) , ( attenuation coefficients 1f 0f 0f, attenuation fade theshold 1f ) */
+ private final FloatBuffer pointParams = Buffers.newDirectFloatBuffer(new float[] { 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f });
+
+ private PMVMatrix pmvMatrix;
+ private ShaderState shaderState;
+ private ShaderProgram shaderProgramColor;
+ private ShaderProgram shaderProgramColorTexture2, shaderProgramColorTexture4, shaderProgramColorTexture8;
+ private ShaderProgram shaderProgramColorLight;
+ private ShaderProgram shaderProgramColorTexture8Light;
+ private ShaderProgram shaderProgramPoints;
+
+ private ShaderSelectionMode requestedShaderSelectionMode = ShaderSelectionMode.AUTO;
+ private ShaderSelectionMode currentShaderSelectionMode = requestedShaderSelectionMode;
// uniforms ..
- protected static final String mgl_PMVMatrix = "mgl_PMVMatrix"; // m4fv[4] - P, Mv, Mvi and Mvit
- protected static final String mgl_ColorEnabled = "mgl_ColorEnabled"; // 1i
- protected static final String mgl_ColorStatic = "mgl_ColorStatic"; // 4fv
-
- protected static final String mgl_LightSource = "mgl_LightSource"; // struct mgl_LightSourceParameters[MAX_LIGHTS]
- protected static final String mgl_FrontMaterial = "mgl_FrontMaterial"; // struct mgl_MaterialParameters
- protected static final String mgl_LightsEnabled = "mgl_LightsEnabled"; // int mgl_LightsEnabled[MAX_LIGHTS];
-
- protected static final String mgl_ShadeModel = "mgl_ShadeModel"; // 1i
-
- protected static final String mgl_TexCoordEnabled = "mgl_TexCoordEnabled"; // int mgl_TexCoordEnabled[MAX_TEXTURE_UNITS];
- protected static final String mgl_ActiveTexture = "mgl_ActiveTexture"; // 1i
- protected static final String mgl_ActiveTextureIdx = "mgl_ActiveTextureIdx";// 1i
-
- protected static final String mgl_CullFace = "mgl_CullFace"; // 1i
-
- protected static final FloatBuffer zero4f = Buffers.newDirectFloatBuffer(new float[] { 0.0f, 0.0f, 0.0f, 0.0f });
-
- public static final FloatBuffer defAmbient = Buffers.newDirectFloatBuffer(new float[] { 0f, 0f, 0f, 1f });
- public static final FloatBuffer defDiffuse = zero4f;
- public static final FloatBuffer defSpecular= zero4f;
- public static final FloatBuffer defPosition= Buffers.newDirectFloatBuffer(new float[] { 0f, 0f, 1f, 0f });
- public static final FloatBuffer defSpotDir = Buffers.newDirectFloatBuffer(new float[] { 0f, 0f, -1f });
- public static final float defSpotExponent = 0f;
- public static final float defSpotCutoff = 180f;
- public static final float defConstantAtten = 1f;
- public static final float defLinearAtten = 0f;
- public static final float defQuadraticAtten= 0f;
-
- public static final FloatBuffer defMatAmbient = Buffers.newDirectFloatBuffer(new float[] { 0.2f, 0.2f, 0.2f, 1.0f });
- public static final FloatBuffer defMatDiffuse = Buffers.newDirectFloatBuffer(new float[] { 0.8f, 0.8f, 0.8f, 1.0f });
- public static final FloatBuffer defMatSpecular= Buffers.newDirectFloatBuffer(new float[] { 0f, 0f, 0f, 1f});
- public static final FloatBuffer defMatEmission= Buffers.newDirectFloatBuffer(new float[] { 0f, 0f, 0f, 1f});
+ private static final String mgl_PMVMatrix = "mgl_PMVMatrix"; // m4fv[4] - P, Mv, Mvi and Mvit
+ private static final String mgl_ColorEnabled = "mgl_ColorEnabled"; // 1i
+ private static final String mgl_ColorStatic = "mgl_ColorStatic"; // 4fv
+
+ private static final String mgl_LightModel = "mgl_LightModel"; // struct mgl_LightModelParameters
+ private static final String mgl_LightSource = "mgl_LightSource"; // struct mgl_LightSourceParameters[MAX_LIGHTS]
+ private static final String mgl_FrontMaterial = "mgl_FrontMaterial"; // struct mgl_MaterialParameters
+ private static final String mgl_LightsEnabled = "mgl_LightsEnabled"; // int mgl_LightsEnabled[MAX_LIGHTS];
+
+ private static final String mgl_AlphaTestFunc = "mgl_AlphaTestFunc"; // 1i (lowp int)
+ private static final String mgl_AlphaTestRef = "mgl_AlphaTestRef"; // 1f
+ private static final String mgl_ShadeModel = "mgl_ShadeModel"; // 1i
+ private static final String mgl_PointParams = "mgl_PointParams"; // vec4[2]: { (sz, smooth, attnMinSz, attnMaxSz), (attnCoeff(3), attnFadeTs) }
+
+ private static final String mgl_TextureEnabled = "mgl_TextureEnabled"; // int mgl_TextureEnabled[MAX_TEXTURE_UNITS];
+ private static final String mgl_Texture = "mgl_Texture"; // sampler2D mgl_Texture<0..7>
+ private static final String mgl_TexCoordEnabled = "mgl_TexCoordEnabled"; // int mgl_TexCoordEnabled[MAX_TEXTURE_UNITS];
+ private static final String mgl_TexEnvMode = "mgl_TexEnvMode"; // int mgl_TexEnvMode[MAX_TEXTURE_UNITS];
+ private static final String mgl_TexFormat = "mgl_TexFormat"; // int mgl_TexFormat[MAX_TEXTURE_UNITS];
+
+ // private static final FloatBuffer zero4f = Buffers.newDirectFloatBuffer(new float[] { 0.0f, 0.0f, 0.0f, 0.0f });
+ private static final FloatBuffer neut4f = Buffers.newDirectFloatBuffer(new float[] { 0.0f, 0.0f, 0.0f, 1.0f });
+ private static final FloatBuffer one4f = Buffers.newDirectFloatBuffer(new float[] { 1.0f, 1.0f, 1.0f, 1.0f });
+
+ public static final FloatBuffer defAmbient = neut4f;
+ public static final FloatBuffer defDiffuseN = neut4f;
+ public static final FloatBuffer defSpecularN = neut4f;
+ public static final FloatBuffer defPosition = Buffers.newDirectFloatBuffer(new float[] { 0f, 0f, 1f, 0f });
+ public static final FloatBuffer defSpotDir = Buffers.newDirectFloatBuffer(new float[] { 0f, 0f, -1f });
+ public static final float defSpotExponent = 0f;
+ public static final float defSpotCutoff = 180f;
+ public static final float defConstantAtten = 1f;
+ public static final float defLinearAtten = 0f;
+ public static final float defQuadraticAtten = 0f;
+
+ public static final FloatBuffer defLightModelAmbient = Buffers.newDirectFloatBuffer(new float[] { 0.2f, 0.2f, 0.2f, 1.0f });
+
+ public static final FloatBuffer defMatAmbient = Buffers.newDirectFloatBuffer(new float[] { 0.2f, 0.2f, 0.2f, 1.0f });
+ public static final FloatBuffer defMatDiffuse = Buffers.newDirectFloatBuffer(new float[] { 0.8f, 0.8f, 0.8f, 1.0f });
+ public static final FloatBuffer defMatSpecular = neut4f;
+ public static final FloatBuffer defMatEmission = neut4f;
public static final float defMatShininess = 0f;
- protected static final String vertexColorFileDef = "FixedFuncColor";
- protected static final String vertexColorLightFileDef = "FixedFuncColorLight";
- protected static final String fragmentColorFileDef = "FixedFuncColor";
- protected static final String fragmentColorTextureFileDef = "FixedFuncColorTexture";
- protected static final String shaderSrcRootDef = "shaders" ;
- protected static final String shaderBinRootDef = "shaders/bin" ;
+ private static final String vertexColorFileDef = "FixedFuncColor";
+ private static final String vertexColorLightFileDef = "FixedFuncColorLight";
+ private static final String fragmentColorFileDef = "FixedFuncColor";
+ private static final String fragmentColorTextureFileDef = "FixedFuncColorTexture";
+ private static final String shaderPointFileDef = "FixedFuncPoints";
+ private static final String shaderSrcRootDef = "shaders" ;
+ private static final String shaderBinRootDef = "shaders/bin" ;
+
+ private final Class<?> shaderRootClass;
+ private final String shaderSrcRoot;
+ private final String shaderBinRoot;
+ private final String vertexColorFile;
+ private final String vertexColorLightFile;
+ private final String fragmentColorFile;
+ private final String fragmentColorTextureFile;
}
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncColor.fp b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncColor.fp
index 408ff72..22dd1e6 100644
--- a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncColor.fp
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncColor.fp
@@ -1,16 +1,32 @@
+
+#if __VERSION__ >= 130
+ #define varying in
+ out vec4 mgl_FragColor;
+#else
+ #define mgl_FragColor gl_FragColor
+#endif
+
#include es_precision.glsl
#include mgl_uniform.glsl
#include mgl_varying.glsl
+#include mgl_alphatest.fp
+
void main (void)
{
- if( mgl_CullFace > 0 &&
- ( ( mgl_CullFace == 1 && gl_FrontFacing ) ||
- ( mgl_CullFace == 2 && !gl_FrontFacing ) ||
- ( mgl_CullFace == 3 ) ) ) {
- discard;
+ vec4 color = frontColor;
+
+ /** ES2 supports CullFace implicit ..
+ if( mgl_CullFace > 0 &&
+ ( ( MGL_FRONT == mgl_CullFace && gl_FrontFacing ) ||
+ ( MGL_BACK == mgl_CullFace && !gl_FrontFacing ) ||
+ ( MGL_FRONT_AND_BACK == mgl_CullFace ) ) ) {
+ DISCARD(color);
+ } */
+ if( mgl_AlphaTestFunc > 0 ) {
+ alphaTest(color);
}
- gl_FragColor = frontColor;
+ mgl_FragColor = color;
}
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncColor.vp b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncColor.vp
index 346e401..f39fcfb 100644
--- a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncColor.vp
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncColor.vp
@@ -1,3 +1,9 @@
+
+#if __VERSION__ >= 130
+ #define attribute in
+ #define varying out
+#endif
+
#include es_precision.glsl
#include mgl_const.glsl
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncColorLight.vp b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncColorLight.vp
index 7ce1eed..942a540 100644
--- a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncColorLight.vp
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncColorLight.vp
@@ -1,3 +1,9 @@
+
+#if __VERSION__ >= 130
+ #define attribute in
+ #define varying out
+#endif
+
#include es_precision.glsl
#include mgl_lightdef.glsl
@@ -50,16 +56,18 @@ void main(void)
}
}
}
- ambient *= mgl_FrontMaterial.ambient;
- diffuse *= mgl_FrontMaterial.diffuse;
- specular *= mgl_FrontMaterial.specular;
-
if(mgl_ColorEnabled>0) {
frontColor=mgl_Color;
} else {
frontColor=mgl_ColorStatic;
}
if( lightEnabled ) {
+ // light-ambient + global-ambient
+ // ( mgl_LightSource[0..n].ambient * mgl_FrontMaterial.ambient ) + ( mgl_LightModel.ambient * mgl_FrontMaterial.ambient )
+ ambient = ( ambient + mgl_LightModel.ambient ) * mgl_FrontMaterial.ambient;
+ diffuse *= mgl_FrontMaterial.diffuse;
+ specular *= mgl_FrontMaterial.specular;
+
frontColor *= ambient + diffuse + specular;
}
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncColorTexture.fp b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncColorTexture.fp
index 86e6ace..130711e 100644
--- a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncColorTexture.fp
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncColorTexture.fp
@@ -1,4 +1,13 @@
+#if __VERSION__ >= 130
+ #define varying in
+ out vec4 mgl_FragColor;
+ #define texture2D texture
+#else
+ #define mgl_FragColor gl_FragColor
+#endif
+
+
#include es_precision.glsl
#include mgl_lightdef.glsl
@@ -6,42 +15,103 @@
#include mgl_uniform.glsl
#include mgl_varying.glsl
-vec4 getTexColor(in sampler2D tex, in int idx) {
- vec4 coord;
- if(idx==0) {
- coord= mgl_TexCoords[0];
- } else if(idx==1) {
- coord= mgl_TexCoords[1];
- } else if(idx==2) {
- coord= mgl_TexCoords[2];
- } else if(idx==3) {
- coord= mgl_TexCoords[3];
- } else if(idx==4) {
- coord= mgl_TexCoords[4];
- } else if(idx==5) {
- coord= mgl_TexCoords[5];
- } else if(idx==6) {
- coord= mgl_TexCoords[6];
- } else {
- coord= mgl_TexCoords[7];
+#include mgl_alphatest.fp
+
+const float gamma = 1.5; // FIXME
+const vec3 igammav = vec3(1.0 / gamma); // FIXME
+const vec4 texEnvColor = vec4(0.0); // FIXME
+
+const vec4 zerov4 = vec4(0.0);
+const vec4 onev4 = vec4(1.0);
+
+void calcTexColor(inout vec4 color, vec4 texColor, in int texFormat, in int texEnvMode) {
+ if(MGL_MODULATE == texEnvMode) { // default
+ if( 4 == texFormat ) {
+ color *= texColor;
+ } else {
+ color.rgb *= texColor.rgb;
+ }
+ } else if(MGL_REPLACE == texEnvMode) {
+ if( 4 == texFormat ) {
+ color = texColor;
+ } else {
+ color.rgb = texColor.rgb;
+ }
+ } else if(MGL_ADD == texEnvMode) {
+ if( 4 == texFormat ) {
+ color += texColor;
+ } else {
+ color.rgb += texColor.rgb;
+ }
+ } else if(MGL_BLEND == texEnvMode) {
+ color.rgb = mix(color.rgb, texEnvColor.rgb, texColor.rgb);
+ if( 4 == texFormat ) {
+ color.a *= texColor.a;
+ }
+ } else if(MGL_DECAL == texEnvMode) {
+ if( 4 == texFormat ) {
+ color.rgb = mix(color.rgb, texColor.rgb, texColor.a);
+ } else {
+ color.rgb = texColor.rgb;
+ }
}
- return texture2D(tex, coord.st);
+ color = clamp(color, zerov4, onev4);
}
void main (void)
-{
- if( mgl_CullFace > 0 &&
- ( ( mgl_CullFace == 1 && gl_FrontFacing ) ||
- ( mgl_CullFace == 2 && !gl_FrontFacing ) ||
- ( mgl_CullFace == 3 ) ) ) {
- discard;
- }
-
- vec4 texColor = getTexColor(mgl_ActiveTexture,mgl_ActiveTextureIdx);
-
- if(length(texColor.rgb)>0.0) {
- gl_FragColor = vec4(frontColor.rgb*texColor.rgb, frontColor.a) ;
+{
+ vec4 color = frontColor;
+
+ /** ES2 supports CullFace implicit ..
+ if( mgl_CullFace > 0 &&
+ ( ( MGL_FRONT == mgl_CullFace && gl_FrontFacing ) ||
+ ( MGL_BACK == mgl_CullFace && !gl_FrontFacing ) ||
+ ( MGL_FRONT_AND_BACK == mgl_CullFace ) ) ) {
+ DISCARD(color);
+ } else { */
+ #if MAX_TEXTURE_UNITS >= 2
+ if( 0 != mgl_TextureEnabled[0] ) {
+ calcTexColor(color, texture2D(mgl_Texture0, mgl_TexCoords[0].st), mgl_TexFormat[0], mgl_TexEnvMode[0]);
+ }
+ if( 0 != mgl_TextureEnabled[1] ) {
+ calcTexColor(color, texture2D(mgl_Texture1, mgl_TexCoords[1].st), mgl_TexFormat[1], mgl_TexEnvMode[1]);
+ }
+ #endif
+ #if MAX_TEXTURE_UNITS >= 4
+ if( 0 != mgl_TextureEnabled[2] ) {
+ calcTexColor(color, texture2D(mgl_Texture2, mgl_TexCoords[2].st), mgl_TexFormat[2], mgl_TexEnvMode[2]);
+ }
+ if( 0 != mgl_TextureEnabled[3] ) {
+ calcTexColor(color, texture2D(mgl_Texture3, mgl_TexCoords[3].st), mgl_TexFormat[3], mgl_TexEnvMode[3]);
+ }
+ #endif
+ #if MAX_TEXTURE_UNITS >= 8
+ if( 0 != mgl_TextureEnabled[4] ) {
+ calcTexColor(color, texture2D(mgl_Texture4, mgl_TexCoords[4].st), mgl_TexFormat[4], mgl_TexEnvMode[4]);
+ }
+ if( 0 != mgl_TextureEnabled[5] ) {
+ calcTexColor(color, texture2D(mgl_Texture5, mgl_TexCoords[5].st), mgl_TexFormat[5], mgl_TexEnvMode[5]);
+ }
+ if( 0 != mgl_TextureEnabled[6] ) {
+ calcTexColor(color, texture2D(mgl_Texture6, mgl_TexCoords[6].st), mgl_TexFormat[6], mgl_TexEnvMode[6]);
+ }
+ if( 0 != mgl_TextureEnabled[7] ) {
+ calcTexColor(color, texture2D(mgl_Texture7, mgl_TexCoords[7].st), mgl_TexFormat[7], mgl_TexEnvMode[7]);
+ }
+ #endif
+ if( mgl_AlphaTestFunc > 0 ) {
+ alphaTest(color);
+ }
+ // } /* CullFace */
+
+ mgl_FragColor = color;
+ /**
+ // simple alpha check
+ if (color.a != 0.0) {
+ mgl_FragColor = vec4(pow(color.rgb, igammav), color.a);
} else {
- gl_FragColor = frontColor;
- }
+ // discard; // freezes NV tegra2 compiler
+ mgl_FragColor = color;
+ } */
}
+
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncPoints.fp b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncPoints.fp
new file mode 100644
index 0000000..2d58f23
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncPoints.fp
@@ -0,0 +1,47 @@
+
+#if __VERSION__ >= 130
+ #define varying in
+ out vec4 mgl_FragColor;
+#else
+ #define mgl_FragColor gl_FragColor
+#endif
+
+
+#include es_precision.glsl
+#include mgl_lightdef.glsl
+
+#include mgl_const.glsl
+#include mgl_uniform.glsl
+#include mgl_varying.glsl
+
+// #define TEST 1
+
+void main (void)
+{
+ mgl_FragColor = frontColor;
+
+ if( pointSmooth > 0.5 ) {
+ // smooth (AA)
+ const float border = 0.90; // take/give 10% for AA
+
+ // origin to 0/0, [-1/-1 .. 1/1]
+ vec2 pointPos = 2.0 * gl_PointCoord - 1.0 ;
+ float r = length( pointPos ); // one-circle sqrt(x * x + y * y), range: in-circle [0..1], out >1
+ float r1 = 1.0 - ( step(border, r) * 10.0 * ( r - border ) ) ; // [0..1]
+ #ifndef TEST
+ if( r1 < 0.0 ) {
+ discard;
+ }
+ #endif
+
+ #ifndef TEST
+ mgl_FragColor.a *= r1;
+ #else
+ mgl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
+ mgl_FragColor.r = r1 < 0.0 ? 1.0 : 0.0;
+ mgl_FragColor.g = r > 1.0 ? 1.0 : 0.0;
+ mgl_FragColor.b = r > border ? 1.0 : 0.0;
+ #endif
+ }
+}
+
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncPoints.vp b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncPoints.vp
new file mode 100644
index 0000000..4a5d93a
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncPoints.vp
@@ -0,0 +1,40 @@
+
+#if __VERSION__ >= 130
+ #define attribute in
+ #define varying out
+#endif
+
+#include es_precision.glsl
+
+#include mgl_const.glsl
+#include mgl_uniform.glsl
+#include mgl_attribute.glsl
+#include mgl_varying.glsl
+
+#include mgl_settexcoord.vp
+
+void main(void)
+{
+ if( mgl_ColorEnabled > 0 ) {
+ frontColor = mgl_Color;
+ } else {
+ frontColor = mgl_ColorStatic;
+ }
+
+ vec4 eyeCoord = mgl_PMVMatrix[1] * mgl_Vertex;
+ gl_Position = mgl_PMVMatrix[0] * eyeCoord;
+
+ float dist = distance(eyeCoord, vec4(0.0, 0.0, 0.0, 1.0));
+ float atten = sqrt( 1.0 / ( pointDistanceConstantAtten +
+ ( pointDistanceLinearAtten +
+ pointDistanceQuadraticAtten * dist
+ ) * dist
+ )
+ );
+ float size = clamp(pointSize * atten, pointSizeMin, pointSizeMax);
+ gl_PointSize = max(size, pointFadeThresholdSize);
+
+ float fade = min(size, pointFadeThresholdSize) / pointFadeThresholdSize;
+ frontColor.a *= fade * fade;
+}
+
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_alphatest.fp b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_alphatest.fp
new file mode 100644
index 0000000..2b64cde
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_alphatest.fp
@@ -0,0 +1,33 @@
+
+void alphaTest(inout vec4 color) {
+ if( MGL_GREATER == mgl_AlphaTestFunc ) {
+ if ( color.a <= mgl_AlphaTestRef ) {
+ DISCARD(color);
+ }
+ } else if( MGL_LESS == mgl_AlphaTestFunc ) {
+ if ( color.a >= mgl_AlphaTestRef ) {
+ DISCARD(color);
+ }
+ } else if( MGL_LEQUAL == mgl_AlphaTestFunc ) {
+ if ( color.a > mgl_AlphaTestRef ) {
+ DISCARD(color);
+ }
+ } else if( MGL_GEQUAL == mgl_AlphaTestFunc ) {
+ if ( color.a < mgl_AlphaTestRef ) {
+ DISCARD(color);
+ }
+ } else if( MGL_EQUAL == mgl_AlphaTestFunc ) {
+ if ( abs( color.a - mgl_AlphaTestRef ) > EPSILON ) {
+ DISCARD(color);
+ }
+ } else if( MGL_NOTEQUAL == mgl_AlphaTestFunc ) {
+ if ( abs( color.a - mgl_AlphaTestRef ) <= EPSILON ) {
+ DISCARD(color);
+ }
+ } else if( MGL_NEVER == mgl_AlphaTestFunc ) {
+ DISCARD(color);
+ } /* else if( MGL_ALWAYS == mgl_AlphaTestFunc ) {
+ // NOP
+ } */
+}
+
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_attribute.glsl b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_attribute.glsl
index 09a11ec..f670f7b 100644
--- a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_attribute.glsl
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_attribute.glsl
@@ -4,16 +4,22 @@
#include es_precision.glsl
-attribute HIGHP vec4 mgl_Vertex;
-attribute HIGHP vec4 mgl_Normal;
-attribute HIGHP vec4 mgl_Color;
-attribute HIGHP vec4 mgl_MultiTexCoord0;
-attribute HIGHP vec4 mgl_MultiTexCoord1;
-attribute HIGHP vec4 mgl_MultiTexCoord2;
-attribute HIGHP vec4 mgl_MultiTexCoord3;
-attribute HIGHP vec4 mgl_MultiTexCoord4;
-attribute HIGHP vec4 mgl_MultiTexCoord5;
-attribute HIGHP vec4 mgl_MultiTexCoord6;
-attribute HIGHP vec4 mgl_MultiTexCoord7;
+attribute vec4 mgl_Vertex;
+attribute vec4 mgl_Normal;
+attribute vec4 mgl_Color;
+#if MAX_TEXTURE_UNITS >= 2
+attribute vec4 mgl_MultiTexCoord0;
+attribute vec4 mgl_MultiTexCoord1;
+#endif
+#if MAX_TEXTURE_UNITS >= 4
+attribute vec4 mgl_MultiTexCoord2;
+attribute vec4 mgl_MultiTexCoord3;
+#endif
+#if MAX_TEXTURE_UNITS >= 8
+attribute vec4 mgl_MultiTexCoord4;
+attribute vec4 mgl_MultiTexCoord5;
+attribute vec4 mgl_MultiTexCoord6;
+attribute vec4 mgl_MultiTexCoord7;
+#endif
#endif // mgl_attribute_glsl
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_const.glsl b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_const.glsl
index 1a464a1..4f97292 100644
--- a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_const.glsl
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_const.glsl
@@ -4,7 +4,36 @@
#include es_precision.glsl
-const LOWP int MAX_TEXTURE_UNITS = 8; // <=gl_MaxTextureImageUnits
+// will be defined at runtime: MAX_TEXTURE_UNITS [0|2|4|8]
const LOWP int MAX_LIGHTS = 8;
+const float EPSILON = 0.0000001; // FIXME: determine proper hw-precision
+
+// discard freezes NV tegra2 compiler (STILL TRUE?)
+// #define DISCARD(c) (c.a = 0.0)
+#define DISCARD(c) discard
+
+// Texture Environment / Multi Texturing
+#define MGL_ADD 1
+#define MGL_MODULATE 2
+#define MGL_DECAL 3
+#define MGL_BLEND 4
+#define MGL_REPLACE 5
+#define MGL_COMBINE 6
+
+// Alpha Test
+#define MGL_NEVER 1
+#define MGL_LESS 2
+#define MGL_EQUAL 3
+#define MGL_LEQUAL 4
+#define MGL_GREATER 5
+#define MGL_NOTEQUAL 6
+#define MGL_GEQUAL 7
+#define MGL_ALWAYS 8
+
+// Cull Face
+#define MGL_FRONT 1
+#define MGL_BACK 2
+#define MGL_FRONT_AND_BACK 3
+
#endif // mgl_const_glsl
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_lightdef.glsl b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_lightdef.glsl
index 98e2141..deaf954 100644
--- a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_lightdef.glsl
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_lightdef.glsl
@@ -1,6 +1,9 @@
#ifndef mgl_lightdef_glsl
#define mgl_lightdef_glsl
+struct mgl_LightModelParameters {
+ vec4 ambient;
+};
struct mgl_LightSourceParameters {
vec4 ambient;
vec4 diffuse;
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_settexcoord.vp b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_settexcoord.vp
index 1efe328..cbf0db6 100644
--- a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_settexcoord.vp
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_settexcoord.vp
@@ -22,14 +22,20 @@ void setTexCoord(in vec4 defpos) {
mgl_TexCoords[7] = ( 0 != (mgl_TexCoordEnabled & 128) ) ? mgl_MultiTexCoord7 : defpos;
*/
+ #if MAX_TEXTURE_UNITS >= 2
mgl_TexCoords[0] = ( 0 != mgl_TexCoordEnabled[0] ) ? mgl_MultiTexCoord0 : defpos;
mgl_TexCoords[1] = ( 0 != mgl_TexCoordEnabled[1] ) ? mgl_MultiTexCoord1 : defpos;
+ #endif
+ #if MAX_TEXTURE_UNITS >= 4
mgl_TexCoords[2] = ( 0 != mgl_TexCoordEnabled[2] ) ? mgl_MultiTexCoord2 : defpos;
mgl_TexCoords[3] = ( 0 != mgl_TexCoordEnabled[3] ) ? mgl_MultiTexCoord3 : defpos;
+ #endif
+ #if MAX_TEXTURE_UNITS >= 8
mgl_TexCoords[4] = ( 0 != mgl_TexCoordEnabled[4] ) ? mgl_MultiTexCoord4 : defpos;
mgl_TexCoords[5] = ( 0 != mgl_TexCoordEnabled[5] ) ? mgl_MultiTexCoord5 : defpos;
mgl_TexCoords[6] = ( 0 != mgl_TexCoordEnabled[6] ) ? mgl_MultiTexCoord6 : defpos;
mgl_TexCoords[7] = ( 0 != mgl_TexCoordEnabled[7] ) ? mgl_MultiTexCoord7 : defpos;
+ #endif
}
#endif // mgl_settexcoord_vp
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_uniform.glsl b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_uniform.glsl
index 4c4000d..5029e4b 100644
--- a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_uniform.glsl
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_uniform.glsl
@@ -6,12 +6,45 @@
#include mgl_const.glsl
-uniform HIGHP mat4 mgl_PMVMatrix[4]; // P, Mv, Mvi and Mvit (transpose(inverse(ModelView)) == normalMatrix)
+uniform mat4 mgl_PMVMatrix[4]; // P, Mv, Mvi and Mvit (transpose(inverse(ModelView)) == normalMatrix)
uniform LOWP int mgl_ColorEnabled;
-uniform HIGHP vec4 mgl_ColorStatic;
+uniform vec4 mgl_ColorStatic;
+uniform LOWP int mgl_AlphaTestFunc;
+uniform float mgl_AlphaTestRef;
+
+// [0].rgba: size, smooth, attnMinSz, attnMaxSz
+// [1].rgba: attnCoeff(3), attnFadeTs
+uniform MEDIUMP vec4 mgl_PointParams[2];
+
+#define pointSize (mgl_PointParams[0].r)
+#define pointSmooth (mgl_PointParams[0].g)
+#define pointSizeMin (mgl_PointParams[0].b)
+#define pointSizeMax (mgl_PointParams[0].a)
+#define pointDistanceConstantAtten (mgl_PointParams[1].r)
+#define pointDistanceLinearAtten (mgl_PointParams[1].g)
+#define pointDistanceQuadraticAtten (mgl_PointParams[1].b)
+#define pointFadeThresholdSize (mgl_PointParams[1].a)
+
+// uniform LOWP int mgl_CullFace; // ES2 supports CullFace implicit ..
+#if MAX_TEXTURE_UNITS > 0
+uniform LOWP int mgl_TextureEnabled[MAX_TEXTURE_UNITS];
uniform LOWP int mgl_TexCoordEnabled[MAX_TEXTURE_UNITS];
-uniform sampler2D mgl_ActiveTexture;
-uniform LOWP int mgl_ActiveTextureIdx;
-uniform LOWP int mgl_CullFace;
+uniform LOWP int mgl_TexEnvMode[MAX_TEXTURE_UNITS];
+uniform LOWP int mgl_TexFormat[MAX_TEXTURE_UNITS];
+#if MAX_TEXTURE_UNITS >= 2
+uniform sampler2D mgl_Texture0;
+uniform sampler2D mgl_Texture1;
+#endif
+#if MAX_TEXTURE_UNITS >= 4
+uniform sampler2D mgl_Texture2;
+uniform sampler2D mgl_Texture3;
+#endif
+#if MAX_TEXTURE_UNITS >= 8
+uniform sampler2D mgl_Texture4;
+uniform sampler2D mgl_Texture5;
+uniform sampler2D mgl_Texture6;
+uniform sampler2D mgl_Texture7;
+#endif
+#endif
#endif // mgl_uniform_glsl
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_uniform_light.glsl b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_uniform_light.glsl
index 0dedb5d..5b34fd9 100644
--- a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_uniform_light.glsl
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_uniform_light.glsl
@@ -9,6 +9,7 @@
uniform LOWP int mgl_LightsEnabled[MAX_LIGHTS];
+uniform mgl_LightModelParameters mgl_LightModel;
uniform mgl_LightSourceParameters mgl_LightSource[MAX_LIGHTS];
uniform mgl_MaterialParameters mgl_FrontMaterial;
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_varying.glsl b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_varying.glsl
index fc9f735..599ac4a 100644
--- a/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_varying.glsl
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/mgl_varying.glsl
@@ -7,6 +7,8 @@
#include mgl_const.glsl
varying vec4 frontColor;
+#if MAX_TEXTURE_UNITS > 0
varying vec4 mgl_TexCoords[MAX_TEXTURE_UNITS];
+#endif
#endif // mgl_varying_glsl
diff --git a/src/jogl/classes/jogamp/opengl/util/pngj/chunks/PngChunkTIME.java b/src/jogl/classes/jogamp/opengl/util/pngj/chunks/PngChunkTIME.java
index 37e617a..fa61f62 100644
--- a/src/jogl/classes/jogamp/opengl/util/pngj/chunks/PngChunkTIME.java
+++ b/src/jogl/classes/jogamp/opengl/util/pngj/chunks/PngChunkTIME.java
@@ -75,7 +75,7 @@ public class PngChunkTIME extends PngChunk {
/** format YYYY/MM/DD HH:mm:SS */
public String getAsString() {
- return String.format("%04/%02d/%02d %02d:%02d:%02d", year, mon, day, hour, min, sec);
+ return String.format("%04d/%02d/%02d %02d:%02d:%02d", year, mon, day, hour, min, sec);
}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WGLGLCapabilities.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WGLGLCapabilities.java
index 6a4ce5a..99064b1 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WGLGLCapabilities.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WGLGLCapabilities.java
@@ -28,6 +28,8 @@
package jogamp.opengl.windows.wgl;
+import java.nio.IntBuffer;
+
import jogamp.nativewindow.windows.GDI;
import jogamp.nativewindow.windows.PIXELFORMATDESCRIPTOR;
@@ -75,12 +77,13 @@ public class WGLGLCapabilities extends GLCapabilities {
return true;
}
- public boolean setValuesByARB(final int[] iattribs, final int niattribs, final int[] iresults) {
+ public boolean setValuesByARB(final IntBuffer iattribs, final int niattribs, final IntBuffer iresults) {
arb_pixelformat = 1;
int alphaBits = 0;
for (int i = 0; i < niattribs; i++) {
- int attr = iattribs[i];
+ final int attr = iattribs.get(i);
+ final int res = iresults.get(i);
switch (attr) {
case WGLExt.WGL_DRAW_TO_WINDOW_ARB:
case WGLExt.WGL_DRAW_TO_BITMAP_ARB:
@@ -88,37 +91,37 @@ public class WGLGLCapabilities extends GLCapabilities {
break;
case WGLExt.WGL_ACCELERATION_ARB:
- setHardwareAccelerated(iresults[i] == WGLExt.WGL_FULL_ACCELERATION_ARB);
+ setHardwareAccelerated(res == WGLExt.WGL_FULL_ACCELERATION_ARB);
break;
case WGLExt.WGL_SUPPORT_OPENGL_ARB:
- if (iresults[i] != GL.GL_TRUE) {
+ if (res != GL.GL_TRUE) {
return false;
}
break;
case WGLExt.WGL_DEPTH_BITS_ARB:
- setDepthBits(iresults[i]);
+ setDepthBits(res);
break;
case WGLExt.WGL_STENCIL_BITS_ARB:
- setStencilBits(iresults[i]);
+ setStencilBits(res);
break;
case WGLExt.WGL_DOUBLE_BUFFER_ARB:
- setDoubleBuffered(iresults[i] == GL.GL_TRUE);
+ setDoubleBuffered(res == GL.GL_TRUE);
break;
case WGLExt.WGL_STEREO_ARB:
- setStereo(iresults[i] == GL.GL_TRUE);
+ setStereo(res == GL.GL_TRUE);
break;
case WGLExt.WGL_PIXEL_TYPE_ARB:
- if(iresults[i] == WGLExt.WGL_TYPE_COLORINDEX_ARB) {
+ if(res == WGLExt.WGL_TYPE_COLORINDEX_ARB) {
return false; // color index not supported
}
- if (iresults[i] == WGLExt.WGL_TYPE_RGBA_FLOAT_ARB) {
+ if (res == WGLExt.WGL_TYPE_RGBA_FLOAT_ARB) {
setPbufferFloatingPointBuffers(true);
}
@@ -127,54 +130,54 @@ public class WGLGLCapabilities extends GLCapabilities {
break;
case WGLExt.WGL_FLOAT_COMPONENTS_NV:
- if (iresults[i] != 0) {
+ if (res != 0) {
setPbufferFloatingPointBuffers(true);
}
break;
case WGLExt.WGL_RED_BITS_ARB:
- setRedBits(iresults[i]);
+ setRedBits(res);
break;
case WGLExt.WGL_GREEN_BITS_ARB:
- setGreenBits(iresults[i]);
+ setGreenBits(res);
break;
case WGLExt.WGL_BLUE_BITS_ARB:
- setBlueBits(iresults[i]);
+ setBlueBits(res);
break;
case WGLExt.WGL_ALPHA_BITS_ARB:
// ALPHA shall be set at last - due to it's auto setting by !opaque / samples
- alphaBits = iresults[i];
+ alphaBits = res;
break;
case WGLExt.WGL_ACCUM_RED_BITS_ARB:
- setAccumRedBits(iresults[i]);
+ setAccumRedBits(res);
break;
case WGLExt.WGL_ACCUM_GREEN_BITS_ARB:
- setAccumGreenBits(iresults[i]);
+ setAccumGreenBits(res);
break;
case WGLExt.WGL_ACCUM_BLUE_BITS_ARB:
- setAccumBlueBits(iresults[i]);
+ setAccumBlueBits(res);
break;
case WGLExt.WGL_ACCUM_ALPHA_BITS_ARB:
- setAccumAlphaBits(iresults[i]);
+ setAccumAlphaBits(res);
break;
case WGLExt.WGL_SAMPLE_BUFFERS_ARB:
- setSampleBuffers(iresults[i] != 0);
+ setSampleBuffers(res != 0);
break;
case WGLExt.WGL_SAMPLES_ARB:
- setNumSamples(iresults[i]);
+ setNumSamples(res);
break;
default:
- throw new GLException("Unknown pixel format attribute " + iattribs[i]);
+ throw new GLException("Unknown pixel format attribute " + attr);
}
}
setAlphaBits(alphaBits);
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java
index 96c1187..f6cc295 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java
@@ -50,8 +50,8 @@ import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
-import com.jogamp.nativewindow.WrappedSurface;
+import jogamp.nativewindow.WrappedSurface;
import jogamp.nativewindow.windows.GDI;
import jogamp.opengl.GLContextShareSet;
@@ -102,7 +102,7 @@ public class WindowsExternalWGLContext extends WindowsWGLContext {
System.err.println("WindowsExternalWGLContext valid hdc/pfd, retrieved cfg: " + cfg);
}
}
- return new WindowsExternalWGLContext(new Drawable(factory, new WrappedSurface(cfg, hdc, 64, 64, null)), ctx, cfg);
+ return new WindowsExternalWGLContext(new Drawable(factory, new WrappedSurface(cfg, hdc, 64, 64, true)), ctx, cfg);
}
@Override
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLDrawable.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLDrawable.java
index 15bd005..f8c237c 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLDrawable.java
@@ -49,10 +49,10 @@ import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
+import jogamp.nativewindow.WrappedSurface;
import jogamp.nativewindow.windows.GDI;
import jogamp.nativewindow.windows.GDIUtil;
-import com.jogamp.nativewindow.WrappedSurface;
public class WindowsExternalWGLDrawable extends WindowsWGLDrawable {
@@ -72,7 +72,7 @@ public class WindowsExternalWGLDrawable extends WindowsWGLDrawable {
final AbstractGraphicsScreen aScreen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_WINDOWS);
final WindowsWGLGraphicsConfiguration cfg = WindowsWGLGraphicsConfiguration.createFromExternal(factory, hdc, pfdID, glp, aScreen, true);
- return new WindowsExternalWGLDrawable(factory, new WrappedSurface(cfg, hdc, 64, 64, null));
+ return new WindowsExternalWGLDrawable(factory, new WrappedSurface(cfg, hdc, 64, 64, true));
}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java
index 1756223..7a512c8 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java
@@ -40,6 +40,10 @@
package jogamp.opengl.windows.wgl;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+
+import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.NativeWindowException;
import javax.media.nativewindow.MutableSurface;
@@ -50,8 +54,11 @@ import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
+import com.jogamp.common.nio.Buffers;
+
import jogamp.nativewindow.windows.GDI;
import jogamp.opengl.GLDrawableImpl;
+import jogamp.opengl.GLGraphicsConfigurationUtil;
import jogamp.opengl.windows.wgl.WindowsWGLDrawableFactory.SharedResource;
// import javax.media.opengl.GLPbuffer;
@@ -127,13 +134,16 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable {
System.out.println("Pbuffer config: " + config);
}
- int[] iattributes = new int [2*WindowsWGLGraphicsConfiguration.MAX_ATTRIBS];
- float[] fattributes = new float[1];
+ final int winattrPbuffer = GLGraphicsConfigurationUtil.getExclusiveWinAttributeBits(false /* onscreen */, false /* fbo */, true /* pbuffer */, false /* bitmap */);
+
+ final IntBuffer iattributes = Buffers.newDirectIntBuffer(2*WindowsWGLGraphicsConfiguration.MAX_ATTRIBS);
+ final FloatBuffer fattributes = Buffers.newDirectFloatBuffer(1);
int[] floatModeTmp = new int[1];
int niattribs = 0;
- GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable)config.getChosenCapabilities();
- GLProfile glProfile = chosenCaps.getGLProfile();
+ final GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable)config.getChosenCapabilities();
+ final GLProfile glProfile = chosenCaps.getGLProfile();
+ final AbstractGraphicsDevice device = config.getScreen().getDevice();
if (DEBUG) {
System.out.println("Pbuffer parentHdc = " + toHexString(sharedHdc));
@@ -156,18 +166,14 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable {
ati = (floatMode == GLPbuffer.ATI_FLOAT);
} */
- int[] pformats = new int[WindowsWGLGraphicsConfiguration.MAX_PFORMATS];
- int nformats;
- int[] nformatsTmp = new int[1];
+ final IntBuffer pformats = Buffers.newDirectIntBuffer(WindowsWGLGraphicsConfiguration.MAX_PFORMATS);
+ final IntBuffer nformatsTmp = Buffers.newDirectIntBuffer(1);
if (!wglExt.wglChoosePixelFormatARB(sharedHdc,
- iattributes, 0,
- fattributes, 0,
- WindowsWGLGraphicsConfiguration.MAX_PFORMATS,
- pformats, 0,
- nformatsTmp, 0)) {
+ iattributes, fattributes, WindowsWGLGraphicsConfiguration.MAX_PFORMATS,
+ pformats, nformatsTmp)) {
throw new GLException("pbuffer creation error: wglChoosePixelFormat() failed");
}
- nformats = nformatsTmp[0];
+ final int nformats = nformatsTmp.get(0);
if (nformats <= 0) {
throw new GLException("pbuffer creation error: Couldn't find a suitable pixel format");
}
@@ -175,8 +181,9 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable {
if (DEBUG) {
System.err.println("" + nformats + " suitable pixel formats found");
for (int i = 0; i < nformats; i++) {
- WGLGLCapabilities dbgCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedResource, sharedHdc, pformats[i], glProfile, false, true);
- System.err.println("pixel format " + pformats[i] + " (index " + i + "): " + dbgCaps);
+ WGLGLCapabilities dbgCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedResource, device, glProfile,
+ sharedHdc, pformats.get(i), winattrPbuffer);
+ System.err.println("pixel format " + pformats.get(i) + " (index " + i + "): " + dbgCaps);
}
}
@@ -186,32 +193,32 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable {
int whichFormat;
// Loop is a workaround for bugs in NVidia's recent drivers
for (whichFormat = 0; whichFormat < nformats; whichFormat++) {
- int format = pformats[whichFormat];
+ int format = pformats.get(whichFormat);
// Create the p-buffer.
niattribs = 0;
if (rtt) {
- iattributes[niattribs++] = WGLExt.WGL_TEXTURE_FORMAT_ARB;
+ iattributes.put(niattribs++, WGLExt.WGL_TEXTURE_FORMAT_ARB);
if (useFloat) {
- iattributes[niattribs++] = WGLExt.WGL_TEXTURE_FLOAT_RGB_NV;
+ iattributes.put(niattribs++, WGLExt.WGL_TEXTURE_FLOAT_RGB_NV);
} else {
- iattributes[niattribs++] = WGLExt.WGL_TEXTURE_RGBA_ARB;
+ iattributes.put(niattribs++, WGLExt.WGL_TEXTURE_RGBA_ARB);
}
- iattributes[niattribs++] = WGLExt.WGL_TEXTURE_TARGET_ARB;
- iattributes[niattribs++] = rect ? WGLExt.WGL_TEXTURE_RECTANGLE_NV : WGLExt.WGL_TEXTURE_2D_ARB;
+ iattributes.put(niattribs++, WGLExt.WGL_TEXTURE_TARGET_ARB);
+ iattributes.put(niattribs++, rect ? WGLExt.WGL_TEXTURE_RECTANGLE_NV : WGLExt.WGL_TEXTURE_2D_ARB);
- iattributes[niattribs++] = WGLExt.WGL_MIPMAP_TEXTURE_ARB;
- iattributes[niattribs++] = GL.GL_FALSE;
+ iattributes.put(niattribs++, WGLExt.WGL_MIPMAP_TEXTURE_ARB);
+ iattributes.put(niattribs++, GL.GL_FALSE);
- iattributes[niattribs++] = WGLExt.WGL_PBUFFER_LARGEST_ARB; // exact
- iattributes[niattribs++] = GL.GL_FALSE;
+ iattributes.put(niattribs++, WGLExt.WGL_PBUFFER_LARGEST_ARB); // exact
+ iattributes.put(niattribs++, GL.GL_FALSE);
}
- iattributes[niattribs++] = 0;
+ iattributes.put(niattribs++, 0);
- tmpBuffer = wglExt.wglCreatePbufferARB(sharedHdc, format, getWidth(), getHeight(), iattributes, 0);
+ tmpBuffer = wglExt.wglCreatePbufferARB(sharedHdc, format, getWidth(), getHeight(), iattributes);
if (tmpBuffer != 0) {
// Done
break;
@@ -222,7 +229,7 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable {
throw new GLException("pbuffer creation error: wglCreatePbuffer() failed: tried " + nformats +
" pixel formats, last error was: " + wglGetLastError());
}
- pfdid = pformats[whichFormat];
+ pfdid = pformats.get(whichFormat);
}
// Get the device context.
@@ -239,7 +246,8 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable {
// Re-query chosen pixel format
{
- WGLGLCapabilities newCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedResource, sharedHdc, pfdid, glProfile, false, true);
+ WGLGLCapabilities newCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedResource, device, glProfile,
+ sharedHdc, pfdid, winattrPbuffer);
if(null == newCaps) {
throw new GLException("pbuffer creation error: unable to re-query chosen PFD ID: " + pfdid + ", hdc " + GLDrawableImpl.toHexString(tmpHdc));
}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java
index 8825bad..57f1652 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java
@@ -41,6 +41,7 @@
package jogamp.opengl.windows.wgl;
import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
import java.util.HashMap;
import java.util.Map;
@@ -51,6 +52,7 @@ import javax.media.opengl.GLContext;
import javax.media.opengl.GLException;
import javax.media.opengl.GLCapabilitiesImmutable;
+import com.jogamp.common.nio.Buffers;
import com.jogamp.gluegen.runtime.ProcAddressTable;
import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver;
import com.jogamp.opengl.GLExtensions;
@@ -235,7 +237,8 @@ public class WindowsWGLContext extends GLContextImpl {
}
try {
- ctx = _wglExt.wglCreateContextAttribsARB(drawable.getHandle(), share, attribs, 0);
+ final IntBuffer attribsNIO = Buffers.newDirectIntBuffer(attribs);
+ ctx = _wglExt.wglCreateContextAttribsARB(drawable.getHandle(), share, attribsNIO);
} catch (RuntimeException re) {
if(DEBUG) {
Throwable t = new Throwable("Info: WindowWGLContext.createContextARBImpl wglCreateContextAttribsARB failed with "+getGLVersion(major, minor, ctp, "@creation"), re);
@@ -487,9 +490,12 @@ public class WindowsWGLContext extends GLContextImpl {
if (initSwapGroupImpl(wglExt)>0) {
final NativeSurface ns = drawable.getNativeSurface();
try {
- if( wglExt.wglQueryMaxSwapGroupsNV(ns.getDisplayHandle(),
- maxGroups, maxGroups_offset,
- maxBarriers, maxBarriers_offset) ) {
+ final IntBuffer maxGroupsNIO = Buffers.newDirectIntBuffer(maxGroups.length - maxGroups_offset);
+ final IntBuffer maxBarriersNIO = Buffers.newDirectIntBuffer(maxBarriers.length - maxBarriers_offset);
+
+ if( wglExt.wglQueryMaxSwapGroupsNV(ns.getDisplayHandle(), maxGroupsNIO, maxBarriersNIO) ) {
+ maxGroupsNIO.get(maxGroups, maxGroups_offset, maxGroupsNIO.remaining());
+ maxBarriersNIO.get(maxGroups, maxGroups_offset, maxBarriersNIO.remaining());
res = true;
}
} catch (Throwable t) { hasSwapGroupNV=-1; }
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawable.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawable.java
index ca7886e..3b3f0c1 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawable.java
@@ -73,27 +73,28 @@ public abstract class WindowsWGLDrawable extends GLDrawableImpl {
}
@Override
- protected final void swapBuffersImpl() {
- // single-buffer is already filtered out @ GLDrawableImpl#swapBuffers()
- final long t0;
- if (PROFILING) {
- t0 = System.currentTimeMillis();
- } else {
- t0 = 0;
- }
-
- if (!WGLUtil.SwapBuffers(getHandle()) && (GDI.GetLastError() != GDI.ERROR_SUCCESS)) {
- throw new GLException("Error swapping buffers");
- }
-
- if (PROFILING) {
- profilingSwapBuffersTime += System.currentTimeMillis() - t0;
- if (++profilingSwapBuffersTicks == PROFILING_TICKS) {
- System.err.println("SwapBuffers calls: " + profilingSwapBuffersTime + " ms / " + PROFILING_TICKS + " calls (" +
- ((float) profilingSwapBuffersTime / (float) PROFILING_TICKS) + " ms/call)");
- profilingSwapBuffersTime = 0;
- profilingSwapBuffersTicks = 0;
- }
+ protected final void swapBuffersImpl(boolean doubleBuffered) {
+ if(doubleBuffered) {
+ final long t0;
+ if (PROFILING) {
+ t0 = System.currentTimeMillis();
+ } else {
+ t0 = 0;
+ }
+
+ if (!WGLUtil.SwapBuffers(getHandle()) && (GDI.GetLastError() != GDI.ERROR_SUCCESS)) {
+ throw new GLException("Error swapping buffers");
+ }
+
+ if (PROFILING) {
+ profilingSwapBuffersTime += System.currentTimeMillis() - t0;
+ if (++profilingSwapBuffersTicks == PROFILING_TICKS) {
+ System.err.println("SwapBuffers calls: " + profilingSwapBuffersTime + " ms / " + PROFILING_TICKS + " calls (" +
+ ((float) profilingSwapBuffersTime / (float) PROFILING_TICKS) + " ms/call)");
+ profilingSwapBuffersTime = 0;
+ profilingSwapBuffersTicks = 0;
+ }
+ }
}
}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
index 09e97ff..c6bc61a 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
@@ -52,7 +52,7 @@ import javax.media.nativewindow.AbstractGraphicsScreen;
import javax.media.nativewindow.DefaultGraphicsScreen;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.ProxySurface;
-import javax.media.nativewindow.ProxySurface.UpstreamSurfaceHook;
+import javax.media.nativewindow.UpstreamSurfaceHook;
import javax.media.opengl.GL;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesChooser;
@@ -61,11 +61,11 @@ import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawable;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
-import javax.media.opengl.GLProfile.ShutdownType;
+import jogamp.nativewindow.WrappedSurface;
import jogamp.nativewindow.windows.GDI;
+import jogamp.nativewindow.windows.GDIDummyUpstreamSurfaceHook;
import jogamp.nativewindow.windows.GDISurface;
-import jogamp.nativewindow.windows.GDIUtil;
import jogamp.nativewindow.windows.RegisteredClassFactory;
import jogamp.opengl.DesktopGLDynamicLookupHelper;
import jogamp.opengl.GLContextImpl;
@@ -80,7 +80,6 @@ import com.jogamp.common.nio.PointerBuffer;
import com.jogamp.common.os.Platform;
import com.jogamp.common.util.ReflectionUtil;
import com.jogamp.common.util.VersionNumber;
-import com.jogamp.nativewindow.WrappedSurface;
import com.jogamp.nativewindow.windows.WindowsGraphicsDevice;
import com.jogamp.opengl.GLExtensions;
@@ -130,7 +129,13 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
}
@Override
- protected final void destroy(ShutdownType shutdownType) {
+ protected final boolean isComplete() {
+ return null != windowsWGLDynamicLookupHelper;
+ }
+
+
+ @Override
+ protected final void destroy() {
if(null != sharedResourceRunner) {
sharedResourceRunner.stop();
sharedResourceRunner = null;
@@ -143,10 +148,9 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
/**
* Pulling away the native library may cause havoc ..
*
- if(ShutdownType.COMPLETE == shutdownType && null != windowsWGLDynamicLookupHelper) {
- windowsWGLDynamicLookupHelper.destroy();
- windowsWGLDynamicLookupHelper = null;
- } */
+ windowsWGLDynamicLookupHelper.destroy();
+ */
+ windowsWGLDynamicLookupHelper = null;
RegisteredClassFactory.shutdownSharedClasses();
}
@@ -314,7 +318,8 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
if (null == glp) {
throw new GLException("Couldn't get default GLProfile for device: "+sharedDevice);
}
- final GLDrawableImpl sharedDrawable = createOnscreenDrawableImpl(createDummySurfaceImpl(sharedDevice, false, new GLCapabilities(glp), null, 64, 64));
+ final GLCapabilitiesImmutable caps = new GLCapabilities(glp);
+ final GLDrawableImpl sharedDrawable = createOnscreenDrawableImpl(createDummySurfaceImpl(sharedDevice, false, caps, caps, null, 64, 64));
sharedDrawable.setRealized(true);
final GLContextImpl sharedContext = (GLContextImpl) sharedDrawable.createContext(null);
@@ -537,9 +542,9 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
@Override
protected final ProxySurface createMutableSurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice,
GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested,
- GLCapabilitiesChooser chooser, int width, int height, UpstreamSurfaceHook lifecycleHook) {
+ GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstreamHook) {
final WindowsGraphicsDevice device;
- if(createNewDevice) {
+ if(createNewDevice || !(deviceReq instanceof WindowsGraphicsDevice)) {
device = new WindowsGraphicsDevice(deviceReq.getConnection(), deviceReq.getUnitID());
} else {
device = (WindowsGraphicsDevice)deviceReq;
@@ -549,75 +554,33 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
if(null == config) {
throw new GLException("Choosing GraphicsConfiguration failed w/ "+capsChosen+" on "+screen);
}
- return new WrappedSurface(config, 0, width, height, lifecycleHook);
+ return new WrappedSurface(config, 0, upstreamHook, createNewDevice);
}
@Override
public final ProxySurface createDummySurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice,
- GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height) {
+ GLCapabilitiesImmutable chosenCaps, GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height) {
final WindowsGraphicsDevice device;
- if(createNewDevice) {
+ if( createNewDevice || !(deviceReq instanceof WindowsGraphicsDevice) ) {
device = new WindowsGraphicsDevice(deviceReq.getConnection(), deviceReq.getUnitID());
} else {
device = (WindowsGraphicsDevice)deviceReq;
}
final AbstractGraphicsScreen screen = new DefaultGraphicsScreen(device, 0);
- final GLCapabilitiesImmutable chosenCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(requestedCaps);
+ chosenCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(chosenCaps);
final WindowsWGLGraphicsConfiguration config = WindowsWGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(chosenCaps, requestedCaps, chooser, screen);
if(null == config) {
- throw new GLException("Choosing GraphicsConfiguration failed w/ "+requestedCaps+" on "+screen);
+ throw new GLException("Choosing GraphicsConfiguration failed w/ "+chosenCaps+" on "+screen);
}
- return new GDISurface(config, 0, width, height, dummySurfaceLifecycleHook);
- }
- private static final ProxySurface.UpstreamSurfaceHook dummySurfaceLifecycleHook = new ProxySurface.UpstreamSurfaceHook() {
- @Override
- public final void create(ProxySurface s) {
- final GDISurface ms = (GDISurface)s;
- if(0 == ms.getWindowHandle()) {
- final long windowHandle = GDIUtil.CreateDummyWindow(0, 0, s.getWidth(), s.getHeight());
- if(0 == windowHandle) {
- throw new GLException("Error windowHandle 0, werr: "+GDI.GetLastError());
- }
- ms.setWindowHandle(windowHandle);
- if(DEBUG) {
- System.err.println("WindowsWGLDrawableFactory.dummySurfaceLifecycleHook.create: "+ms);
- }
- }
- }
- @Override
- public final void destroy(ProxySurface s) {
- final GDISurface ms = (GDISurface)s;
- if(0 != ms.getWindowHandle()) {
- GDI.ShowWindow(ms.getWindowHandle(), GDI.SW_HIDE);
- GDIUtil.DestroyDummyWindow(ms.getWindowHandle());
- ms.setWindowHandle(0);
- if(DEBUG) {
- System.err.println("WindowsWGLDrawableFactory.dummySurfaceLifecycleHook.destroy: "+ms);
- }
- }
- }
- @Override
- public final int getWidth(ProxySurface s) {
- return s.initialWidth;
- }
- @Override
- public final int getHeight(ProxySurface s) {
- return s.initialHeight;
- }
-
- @Override
- public String toString() {
- return "GDISurfaceLifecycleHook[]";
- }
- };
-
+ return new GDISurface(config, 0, new GDIDummyUpstreamSurfaceHook(width, height), createNewDevice);
+ }
@Override
protected final ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice deviceReq, int screenIdx, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstream) {
final WindowsGraphicsDevice device = new WindowsGraphicsDevice(deviceReq.getConnection(), deviceReq.getUnitID());
final AbstractGraphicsScreen screen = new DefaultGraphicsScreen(device, screenIdx);
final WindowsWGLGraphicsConfiguration cfg = WindowsWGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsRequested, capsRequested, chooser, screen);
- return new GDISurface(cfg, windowHandle, 0, 0, upstream);
+ return new GDISurface(cfg, windowHandle, upstream, true);
}
@Override
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java
index 209589b..70da113 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java
@@ -33,6 +33,8 @@
package jogamp.opengl.windows.wgl;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
import java.util.ArrayList;
import java.util.List;
@@ -47,6 +49,7 @@ import javax.media.opengl.GLException;
import javax.media.opengl.GLPbuffer;
import javax.media.opengl.GLProfile;
+import com.jogamp.common.nio.Buffers;
import com.jogamp.nativewindow.MutableGraphicsConfiguration;
import com.jogamp.opengl.GLExtensions;
@@ -57,6 +60,7 @@ import jogamp.nativewindow.windows.PIXELFORMATDESCRIPTOR;
import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLGraphicsConfigurationUtil;
+ at SuppressWarnings("deprecation")
public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguration implements Cloneable {
protected static final int MAX_PFORMATS = 256;
protected static final int MAX_ATTRIBS = 256;
@@ -104,9 +108,9 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
WGLGLCapabilities caps = null;
if(hasARB) {
- caps = wglARBPFID2GLCapabilities(sharedResource, hdc, pfdID, glp, onscreen, true /* pbuffer */);
+ caps = wglARBPFID2GLCapabilities(sharedResource, device, glp, hdc, pfdID, GLGraphicsConfigurationUtil.ALL_BITS);
} else {
- caps = PFD2GLCapabilities(glp, hdc, pfdID, onscreen);
+ caps = PFD2GLCapabilities(device, glp, hdc, pfdID, GLGraphicsConfigurationUtil.ALL_BITS);
}
if(null==caps) {
throw new GLException("Couldn't choose Capabilities by: HDC 0x"+Long.toHexString(hdc)+
@@ -185,7 +189,7 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
}
}
if (DEBUG) {
- System.err.println("setPixelFormat (ARB): hdc "+toHexString(hdc) +", "+caps);
+ System.err.println("setPixelFormat: hdc "+toHexString(hdc) +", "+caps);
}
setCapsPFD(caps);
}
@@ -224,38 +228,38 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
public final int getPixelFormatID() { return isDetermined ? ((WGLGLCapabilities)capabilitiesChosen).getPFDID() : 0; }
public final boolean isChoosenByARB() { return isDetermined ? ((WGLGLCapabilities)capabilitiesChosen).isSetByARB() : false; }
- static int fillAttribsForGeneralWGLARBQuery(WindowsWGLDrawableFactory.SharedResource sharedResource, int[] iattributes) {
+ static int fillAttribsForGeneralWGLARBQuery(WindowsWGLDrawableFactory.SharedResource sharedResource, IntBuffer iattributes) {
int niattribs = 0;
- iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_WINDOW_ARB;
+ iattributes.put(niattribs++, WGLExt.WGL_DRAW_TO_WINDOW_ARB);
if(sharedResource.hasARBPBuffer()) {
- iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_PBUFFER_ARB;
- }
- iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_BITMAP_ARB;
- iattributes[niattribs++] = WGLExt.WGL_ACCELERATION_ARB;
- iattributes[niattribs++] = WGLExt.WGL_SUPPORT_OPENGL_ARB;
- iattributes[niattribs++] = WGLExt.WGL_DEPTH_BITS_ARB;
- iattributes[niattribs++] = WGLExt.WGL_STENCIL_BITS_ARB;
- iattributes[niattribs++] = WGLExt.WGL_DOUBLE_BUFFER_ARB;
- iattributes[niattribs++] = WGLExt.WGL_STEREO_ARB;
- iattributes[niattribs++] = WGLExt.WGL_PIXEL_TYPE_ARB;
- iattributes[niattribs++] = WGLExt.WGL_RED_BITS_ARB;
- iattributes[niattribs++] = WGLExt.WGL_GREEN_BITS_ARB;
- iattributes[niattribs++] = WGLExt.WGL_BLUE_BITS_ARB;
- iattributes[niattribs++] = WGLExt.WGL_ALPHA_BITS_ARB;
- iattributes[niattribs++] = WGLExt.WGL_ACCUM_RED_BITS_ARB;
- iattributes[niattribs++] = WGLExt.WGL_ACCUM_GREEN_BITS_ARB;
- iattributes[niattribs++] = WGLExt.WGL_ACCUM_BLUE_BITS_ARB;
- iattributes[niattribs++] = WGLExt.WGL_ACCUM_ALPHA_BITS_ARB;
+ iattributes.put(niattribs++, WGLExt.WGL_DRAW_TO_PBUFFER_ARB);
+ }
+ iattributes.put(niattribs++, WGLExt.WGL_DRAW_TO_BITMAP_ARB);
+ iattributes.put(niattribs++, WGLExt.WGL_ACCELERATION_ARB);
+ iattributes.put(niattribs++, WGLExt.WGL_SUPPORT_OPENGL_ARB);
+ iattributes.put(niattribs++, WGLExt.WGL_DEPTH_BITS_ARB);
+ iattributes.put(niattribs++, WGLExt.WGL_STENCIL_BITS_ARB);
+ iattributes.put(niattribs++, WGLExt.WGL_DOUBLE_BUFFER_ARB);
+ iattributes.put(niattribs++, WGLExt.WGL_STEREO_ARB);
+ iattributes.put(niattribs++, WGLExt.WGL_PIXEL_TYPE_ARB);
+ iattributes.put(niattribs++, WGLExt.WGL_RED_BITS_ARB);
+ iattributes.put(niattribs++, WGLExt.WGL_GREEN_BITS_ARB);
+ iattributes.put(niattribs++, WGLExt.WGL_BLUE_BITS_ARB);
+ iattributes.put(niattribs++, WGLExt.WGL_ALPHA_BITS_ARB);
+ iattributes.put(niattribs++, WGLExt.WGL_ACCUM_RED_BITS_ARB);
+ iattributes.put(niattribs++, WGLExt.WGL_ACCUM_GREEN_BITS_ARB);
+ iattributes.put(niattribs++, WGLExt.WGL_ACCUM_BLUE_BITS_ARB);
+ iattributes.put(niattribs++, WGLExt.WGL_ACCUM_ALPHA_BITS_ARB);
if(sharedResource.hasARBMultisample()) {
- iattributes[niattribs++] = WGLExt.WGL_SAMPLE_BUFFERS_ARB;
- iattributes[niattribs++] = WGLExt.WGL_SAMPLES_ARB;
+ iattributes.put(niattribs++, WGLExt.WGL_SAMPLE_BUFFERS_ARB);
+ iattributes.put(niattribs++, WGLExt.WGL_SAMPLES_ARB);
}
if(sharedResource.hasARBPBuffer()) {
GLContextImpl sharedCtx = sharedResource.getContext();
if(null != sharedCtx && sharedCtx.isExtensionAvailable(WindowsWGLDrawableFactory.WGL_NV_float_buffer)) {
// pbo float buffer
- iattributes[niattribs++] = WGLExt.WGL_FLOAT_COMPONENTS_NV; // nvidia
+ iattributes.put(niattribs++, WGLExt.WGL_FLOAT_COMPONENTS_NV); // nvidia
}
}
@@ -263,73 +267,72 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
}
static boolean wglARBPFIDValid(WindowsWGLContext sharedCtx, long hdc, int pfdID) {
- int[] in = new int[1];
- int[] out = new int[1];
- in[0] = WGLExt.WGL_COLOR_BITS_ARB;
- if (!sharedCtx.getWGLExt().wglGetPixelFormatAttribivARB(hdc, pfdID, 0, 1, in, 0, out, 0)) {
+ final IntBuffer out = Buffers.newDirectIntBuffer(1);
+ final IntBuffer in = Buffers.newDirectIntBuffer(1);
+ in.put(0, WGLExt.WGL_COLOR_BITS_ARB);
+ if (!sharedCtx.getWGLExt().wglGetPixelFormatAttribivARB(hdc, pfdID, 0, 1, in, out)) {
// Some GPU's falsely fails with a zero error code (success)
return GDI.GetLastError() == GDI.ERROR_SUCCESS ;
}
return true;
}
- static int[] wglAllARBPFIDs(WindowsWGLContext sharedCtx, long hdc) {
- int[] iattributes = new int[1];
- int[] iresults = new int[1];
+ static int wglARBPFDIDCount(WindowsWGLContext sharedCtx, long hdc) {
+ final IntBuffer iresults = Buffers.newDirectIntBuffer(1);
+ final IntBuffer iattributes = Buffers.newDirectIntBuffer(1);
+ iattributes.put(0, WGLExt.WGL_NUMBER_PIXEL_FORMATS_ARB);
WGLExt wglExt = sharedCtx.getWGLExt();
- iattributes[0] = WGLExt.WGL_NUMBER_PIXEL_FORMATS_ARB;
- if (!wglExt.wglGetPixelFormatAttribivARB(hdc, 0, 0, 1, iattributes, 0, iresults, 0)) {
+ // pfdID shall be ignored here (spec), however, pass a valid pdf index '1' below (possible driver bug)
+ if (!wglExt.wglGetPixelFormatAttribivARB(hdc, 1 /* pfdID */, 0, 1, iattributes, iresults)) {
if(DEBUG) {
System.err.println("GetPixelFormatAttribivARB: Failed - HDC 0x" + Long.toHexString(hdc) +
+ ", value "+iresults.get(0)+
", LastError: " + GDI.GetLastError());
Thread.dumpStack();
}
- return null;
+ return 0;
}
- int numFormats = iresults[0];
- if(0 == numFormats) {
+ final int pfdIDCount = iresults.get(0);
+ if(0 == pfdIDCount) {
if(DEBUG) {
System.err.println("GetPixelFormatAttribivARB: No formats - HDC 0x" + Long.toHexString(hdc) +
", LastError: " + GDI.GetLastError());
Thread.dumpStack();
}
- return null;
}
- int[] pfdIDs = new int[numFormats];
- for (int i = 0; i < numFormats; i++) {
+ return pfdIDCount;
+ }
+
+ static int[] wglAllARBPFDIDs(int pfdIDCount) {
+ int[] pfdIDs = new int[pfdIDCount];
+ for (int i = 0; i < pfdIDCount; i++) {
pfdIDs[i] = 1 + i;
}
return pfdIDs;
}
-
+
static WGLGLCapabilities wglARBPFID2GLCapabilities(WindowsWGLDrawableFactory.SharedResource sharedResource,
- long hdc, int pfdID,
- GLProfile glp, boolean onscreen, boolean usePBuffer) {
+ AbstractGraphicsDevice device, GLProfile glp,
+ long hdc, int pfdID, int winattrbits) {
if (!sharedResource.hasARBPixelFormat()) {
return null;
}
- int[] iattributes = new int [2*MAX_ATTRIBS];
- int[] iresults = new int [2*MAX_ATTRIBS];
-
- int niattribs = fillAttribsForGeneralWGLARBQuery(sharedResource, iattributes);
+ final IntBuffer iattributes = Buffers.newDirectIntBuffer(2*MAX_ATTRIBS);
+ final IntBuffer iresults = Buffers.newDirectIntBuffer(2*MAX_ATTRIBS);
+ final int niattribs = fillAttribsForGeneralWGLARBQuery(sharedResource, iattributes);
- if (!((WindowsWGLContext)sharedResource.getContext()).getWGLExt().wglGetPixelFormatAttribivARB(hdc, pfdID, 0, niattribs, iattributes, 0, iresults, 0)) {
+ if (!((WindowsWGLContext)sharedResource.getContext()).getWGLExt().wglGetPixelFormatAttribivARB(hdc, pfdID, 0, niattribs, iattributes, iresults)) {
throw new GLException("wglARBPFID2GLCapabilities: Error getting pixel format attributes for pixel format " + pfdID +
" of device context " + toHexString(hdc) + ", werr " + GDI.GetLastError());
}
- List<GLCapabilitiesImmutable> bucket = new ArrayList<GLCapabilitiesImmutable>(1);
- final int winattrbits = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer, false);
- if(AttribList2GLCapabilities(bucket, glp, hdc, pfdID, iattributes, niattribs, iresults, winattrbits)) {
- return (WGLGLCapabilities) bucket.get(0);
- }
- return null;
+ return AttribList2GLCapabilities(device, glp, hdc, pfdID, iattributes, niattribs, iresults, winattrbits);
}
- static int[] wglChoosePixelFormatARB(long hdc, WindowsWGLDrawableFactory.SharedResource sharedResource,
+ static int[] wglChoosePixelFormatARB(WindowsWGLDrawableFactory.SharedResource sharedResource, AbstractGraphicsDevice device,
GLCapabilitiesImmutable capabilities,
- int[] iattributes, int accelerationMode, float[] fattributes)
+ long hdc, IntBuffer iattributes, int accelerationMode, FloatBuffer fattributes)
{
if ( !WindowsWGLGraphicsConfiguration.GLCapabilities2AttribList(capabilities,
@@ -342,160 +345,167 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
return null;
}
- int[] pformatsTmp = new int[WindowsWGLGraphicsConfiguration.MAX_PFORMATS];
- int[] numFormatsTmp = new int[1];
- if ( !((WindowsWGLContext)sharedResource.getContext()).getWGLExt().wglChoosePixelFormatARB(hdc, iattributes, 0,
- fattributes, 0,
- WindowsWGLGraphicsConfiguration.MAX_PFORMATS,
- pformatsTmp, 0, numFormatsTmp, 0))
- {
+ final WGLExt wglExt = ((WindowsWGLContext)sharedResource.getContext()).getWGLExt();
+ final IntBuffer pformatsTmp = Buffers.newDirectIntBuffer(WindowsWGLGraphicsConfiguration.MAX_PFORMATS);
+ final IntBuffer numFormatsTmp = Buffers.newDirectIntBuffer(1);
+
+ if ( !wglExt.wglChoosePixelFormatARB(hdc, iattributes, fattributes,
+ WindowsWGLGraphicsConfiguration.MAX_PFORMATS,
+ pformatsTmp, numFormatsTmp) ) {
if (DEBUG) {
System.err.println("wglChoosePixelFormatARB: wglChoosePixelFormatARB failed: " + GDI.GetLastError());
Thread.dumpStack();
}
return null;
}
- int numFormats = numFormatsTmp[0];
- int[] pformats = null;
+ final int numFormats = numFormatsTmp.get(0);
+ final int[] pformats;
if( 0 < numFormats ) {
pformats = new int[numFormats];
- System.arraycopy(pformatsTmp, 0, pformats, 0, numFormats);
+ pformatsTmp.get(pformats, 0, numFormats);
+ } else {
+ pformats = null;
}
if (DEBUG) {
System.err.println("wglChoosePixelFormatARB: NumFormats (wglChoosePixelFormatARB) accelMode 0x"
+ Integer.toHexString(accelerationMode) + ": " + numFormats);
for (int i = 0; i < numFormats; i++) {
WGLGLCapabilities dbgCaps0 = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(
- sharedResource, hdc, pformats[i],
- capabilities.getGLProfile(), capabilities.isOnscreen(), capabilities.isPBuffer());
+ sharedResource, device, capabilities.getGLProfile(), hdc, pformats[i], GLGraphicsConfigurationUtil.ALL_BITS);
System.err.println("pixel format " + pformats[i] + " (index " + i + "): " + dbgCaps0);
}
}
return pformats;
}
- static List<GLCapabilitiesImmutable> wglARBPFIDs2GLCapabilities(WindowsWGLDrawableFactory.SharedResource sharedResource,
- long hdc, int[] pfdIDs, GLProfile glp, boolean onscreen, boolean usePBuffer) {
- final int winattrbits = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer, false);
- return wglARBPFIDs2GLCapabilitiesImpl(sharedResource, hdc, pfdIDs, glp, winattrbits);
- }
-
- static List <GLCapabilitiesImmutable> wglARBPFIDs2AllGLCapabilities(WindowsWGLDrawableFactory.SharedResource sharedResource,
- long hdc, int[] pfdIDs, GLProfile glp) {
- return wglARBPFIDs2GLCapabilitiesImpl(sharedResource, hdc, pfdIDs, glp, GLGraphicsConfigurationUtil.ALL_BITS);
- }
-
- private static List <GLCapabilitiesImmutable> wglARBPFIDs2GLCapabilitiesImpl(WindowsWGLDrawableFactory.SharedResource sharedResource,
- long hdc, int[] pfdIDs, GLProfile glp, int winattrbits) {
+ static List <GLCapabilitiesImmutable> wglARBPFIDs2GLCapabilities(WindowsWGLDrawableFactory.SharedResource sharedResource,
+ AbstractGraphicsDevice device, GLProfile glp, long hdc, int[] pfdIDs, int winattrbits) {
if (!sharedResource.hasARBPixelFormat()) {
return null;
}
final int numFormats = pfdIDs.length;
- int[] iattributes = new int [2*MAX_ATTRIBS];
- int[] iresults = new int [2*MAX_ATTRIBS];
- int niattribs = fillAttribsForGeneralWGLARBQuery(sharedResource, iattributes);
+ final IntBuffer iattributes = Buffers.newDirectIntBuffer(2*MAX_ATTRIBS);
+ final IntBuffer iresults = Buffers.newDirectIntBuffer(2*MAX_ATTRIBS);
+ final int niattribs = fillAttribsForGeneralWGLARBQuery(sharedResource, iattributes);
ArrayList<GLCapabilitiesImmutable> bucket = new ArrayList<GLCapabilitiesImmutable>();
for(int i = 0; i<numFormats; i++) {
if ( pfdIDs[i] >= 1 &&
- ((WindowsWGLContext)sharedResource.getContext()).getWGLExt().wglGetPixelFormatAttribivARB(hdc, pfdIDs[i], 0, niattribs, iattributes, 0, iresults, 0) ) {
- AttribList2GLCapabilities(bucket, glp, hdc, pfdIDs[i], iattributes, niattribs, iresults, winattrbits);
+ ((WindowsWGLContext)sharedResource.getContext()).getWGLExt().wglGetPixelFormatAttribivARB(hdc, pfdIDs[i], 0, niattribs, iattributes, iresults) ) {
+ final GLCapabilitiesImmutable caps = AttribList2GLCapabilities(device, glp, hdc, pfdIDs[i], iattributes, niattribs, iresults, winattrbits);
+ if(null != caps) {
+ bucket.add(caps);
+ if(DEBUG) {
+ final int j = bucket.size() - 1;
+ System.err.println("wglARBPFIDs2GLCapabilities: bucket["+i+" -> "+j+"]: "+caps);
+ }
+ } else if(DEBUG) {
+ GLCapabilitiesImmutable skipped = AttribList2GLCapabilities(device, glp, hdc, pfdIDs[i], iattributes, niattribs, iresults, GLGraphicsConfigurationUtil.ALL_BITS);
+ System.err.println("wglARBPFIDs2GLCapabilities: bucket["+i+" -> skip]: pfdID "+pfdIDs[i]+", "+skipped+", winattr "+GLGraphicsConfigurationUtil.winAttributeBits2String(null, winattrbits).toString());
+ }
} else if (DEBUG) {
- System.err.println("wglARBPFIDs2GLCapabilities: Cannot get pixel format attributes for pixel format " +
- i + "/" + numFormats + ": " + pfdIDs[i] + ", " +
- GLGraphicsConfigurationUtil.winAttributeBits2String(null, winattrbits).toString());
+ if( 1 > pfdIDs[i] ) {
+ System.err.println("wglARBPFIDs2GLCapabilities: Invalid pfdID " + i + "/" + numFormats + ": " + pfdIDs[i]);
+ } else {
+ System.err.println("wglARBPFIDs2GLCapabilities: Cannot get pixel format attributes for pixel format " +
+ i + "/" + numFormats + ": " + pfdIDs[i] + ", hdc " + toHexString(hdc));
+ }
}
}
return bucket;
}
static boolean GLCapabilities2AttribList(GLCapabilitiesImmutable caps,
- int[] iattributes,
+ IntBuffer iattributes,
WindowsWGLDrawableFactory.SharedResource sharedResource,
int accelerationValue,
- int[] floatMode) throws GLException {
+ int[] floatMode) throws GLException {
if (!sharedResource.hasARBPixelFormat()) {
return false;
}
- boolean onscreen = caps.isOnscreen();
- boolean pbuffer = caps.isPBuffer();
-
int niattribs = 0;
- iattributes[niattribs++] = WGLExt.WGL_SUPPORT_OPENGL_ARB;
- iattributes[niattribs++] = GL.GL_TRUE;
+ iattributes.put(niattribs++, WGLExt.WGL_SUPPORT_OPENGL_ARB);
+ iattributes.put(niattribs++, GL.GL_TRUE);
if(accelerationValue>0) {
- iattributes[niattribs++] = WGLExt.WGL_ACCELERATION_ARB;
- iattributes[niattribs++] = accelerationValue;
- }
- if (onscreen) {
- iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_WINDOW_ARB;
- iattributes[niattribs++] = GL.GL_TRUE;
- } else if (pbuffer && sharedResource.hasARBPBuffer()) {
- iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_PBUFFER_ARB;
- iattributes[niattribs++] = GL.GL_TRUE;
- } else {
- iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_BITMAP_ARB;
- iattributes[niattribs++] = GL.GL_TRUE;
+ iattributes.put(niattribs++, WGLExt.WGL_ACCELERATION_ARB);
+ iattributes.put(niattribs++, accelerationValue);
}
- iattributes[niattribs++] = WGLExt.WGL_DOUBLE_BUFFER_ARB;
+ final boolean usePBuffer = caps.isPBuffer() && sharedResource.hasARBPBuffer() ;
+
+ final int surfaceType;
+ if( caps.isOnscreen() ) {
+ surfaceType = WGLExt.WGL_DRAW_TO_WINDOW_ARB;
+ } else if( caps.isFBO() ) {
+ surfaceType = WGLExt.WGL_DRAW_TO_WINDOW_ARB; // native replacement!
+ } else if( usePBuffer ) {
+ surfaceType = WGLExt.WGL_DRAW_TO_PBUFFER_ARB;
+ } else if( caps.isBitmap() ) {
+ surfaceType = WGLExt.WGL_DRAW_TO_BITMAP_ARB;
+ } else {
+ throw new GLException("no surface type set in caps: "+caps);
+ }
+ iattributes.put(niattribs++, surfaceType);
+ iattributes.put(niattribs++, GL.GL_TRUE);
+
+ iattributes.put(niattribs++, WGLExt.WGL_DOUBLE_BUFFER_ARB);
if (caps.getDoubleBuffered()) {
- iattributes[niattribs++] = GL.GL_TRUE;
+ iattributes.put(niattribs++, GL.GL_TRUE);
} else {
- iattributes[niattribs++] = GL.GL_FALSE;
+ iattributes.put(niattribs++, GL.GL_FALSE);
}
- iattributes[niattribs++] = WGLExt.WGL_STEREO_ARB;
+ iattributes.put(niattribs++, WGLExt.WGL_STEREO_ARB);
if (caps.getStereo()) {
- iattributes[niattribs++] = GL.GL_TRUE;
+ iattributes.put(niattribs++, GL.GL_TRUE);
} else {
- iattributes[niattribs++] = GL.GL_FALSE;
+ iattributes.put(niattribs++, GL.GL_FALSE);
}
- iattributes[niattribs++] = WGLExt.WGL_RED_BITS_ARB;
- iattributes[niattribs++] = caps.getRedBits();
- iattributes[niattribs++] = WGLExt.WGL_GREEN_BITS_ARB;
- iattributes[niattribs++] = caps.getGreenBits();
- iattributes[niattribs++] = WGLExt.WGL_BLUE_BITS_ARB;
- iattributes[niattribs++] = caps.getBlueBits();
+ iattributes.put(niattribs++, WGLExt.WGL_RED_BITS_ARB);
+ iattributes.put(niattribs++, caps.getRedBits());
+ iattributes.put(niattribs++, WGLExt.WGL_GREEN_BITS_ARB);
+ iattributes.put(niattribs++, caps.getGreenBits());
+ iattributes.put(niattribs++, WGLExt.WGL_BLUE_BITS_ARB);
+ iattributes.put(niattribs++, caps.getBlueBits());
if(caps.getAlphaBits()>0) {
- iattributes[niattribs++] = WGLExt.WGL_ALPHA_BITS_ARB;
- iattributes[niattribs++] = caps.getAlphaBits();
+ iattributes.put(niattribs++, WGLExt.WGL_ALPHA_BITS_ARB);
+ iattributes.put(niattribs++, caps.getAlphaBits());
}
if(caps.getStencilBits()>0) {
- iattributes[niattribs++] = WGLExt.WGL_STENCIL_BITS_ARB;
- iattributes[niattribs++] = caps.getStencilBits();
+ iattributes.put(niattribs++, WGLExt.WGL_STENCIL_BITS_ARB);
+ iattributes.put(niattribs++, caps.getStencilBits());
}
- iattributes[niattribs++] = WGLExt.WGL_DEPTH_BITS_ARB;
- iattributes[niattribs++] = caps.getDepthBits();
+ iattributes.put(niattribs++, WGLExt.WGL_DEPTH_BITS_ARB);
+ iattributes.put(niattribs++, caps.getDepthBits());
if (caps.getAccumRedBits() > 0 ||
caps.getAccumGreenBits() > 0 ||
caps.getAccumBlueBits() > 0 ||
caps.getAccumAlphaBits() > 0) {
- iattributes[niattribs++] = WGLExt.WGL_ACCUM_BITS_ARB;
- iattributes[niattribs++] = (caps.getAccumRedBits() +
- caps.getAccumGreenBits() +
- caps.getAccumBlueBits() +
- caps.getAccumAlphaBits());
- iattributes[niattribs++] = WGLExt.WGL_ACCUM_RED_BITS_ARB;
- iattributes[niattribs++] = caps.getAccumRedBits();
- iattributes[niattribs++] = WGLExt.WGL_ACCUM_GREEN_BITS_ARB;
- iattributes[niattribs++] = caps.getAccumGreenBits();
- iattributes[niattribs++] = WGLExt.WGL_ACCUM_BLUE_BITS_ARB;
- iattributes[niattribs++] = caps.getAccumBlueBits();
- iattributes[niattribs++] = WGLExt.WGL_ACCUM_ALPHA_BITS_ARB;
- iattributes[niattribs++] = caps.getAccumAlphaBits();
+ iattributes.put(niattribs++, WGLExt.WGL_ACCUM_BITS_ARB);
+ iattributes.put(niattribs++, ( caps.getAccumRedBits() +
+ caps.getAccumGreenBits() +
+ caps.getAccumBlueBits() +
+ caps.getAccumAlphaBits() ) );
+ iattributes.put(niattribs++, WGLExt.WGL_ACCUM_RED_BITS_ARB);
+ iattributes.put(niattribs++, caps.getAccumRedBits());
+ iattributes.put(niattribs++, WGLExt.WGL_ACCUM_GREEN_BITS_ARB);
+ iattributes.put(niattribs++, caps.getAccumGreenBits());
+ iattributes.put(niattribs++, WGLExt.WGL_ACCUM_BLUE_BITS_ARB);
+ iattributes.put(niattribs++, caps.getAccumBlueBits());
+ iattributes.put(niattribs++, WGLExt.WGL_ACCUM_ALPHA_BITS_ARB);
+ iattributes.put(niattribs++, caps.getAccumAlphaBits());
}
if (caps.getSampleBuffers() && sharedResource.hasARBMultisample()) {
- iattributes[niattribs++] = WGLExt.WGL_SAMPLE_BUFFERS_ARB;
- iattributes[niattribs++] = GL.GL_TRUE;
- iattributes[niattribs++] = WGLExt.WGL_SAMPLES_ARB;
- iattributes[niattribs++] = caps.getNumSamples();
+ iattributes.put(niattribs++, WGLExt.WGL_SAMPLE_BUFFERS_ARB);
+ iattributes.put(niattribs++, GL.GL_TRUE);
+ iattributes.put(niattribs++, WGLExt.WGL_SAMPLES_ARB);
+ iattributes.put(niattribs++, caps.getNumSamples());
}
boolean rtt = caps.getPbufferRenderToTexture();
@@ -503,7 +513,7 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
boolean useFloat = caps.getPbufferFloatingPointBuffers();
boolean ati = false;
boolean nvidia = false;
- if (pbuffer && sharedResource.hasARBPBuffer()) {
+ if ( usePBuffer ) {
// Check some invariants and set up some state
if (rect && !rtt) {
throw new GLException("Render-to-texture-rectangle requires render-to-texture to be specified");
@@ -541,22 +551,22 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
if (rtt) {
throw new GLException("Render-to-floating-point-texture not supported on ATI hardware");
} else {
- iattributes[niattribs++] = WGLExt.WGL_PIXEL_TYPE_ARB;
- iattributes[niattribs++] = WGLExt.WGL_TYPE_RGBA_FLOAT_ARB;
+ iattributes.put(niattribs++, WGLExt.WGL_PIXEL_TYPE_ARB);
+ iattributes.put(niattribs++, WGLExt.WGL_TYPE_RGBA_FLOAT_ARB);
}
} else {
if (!rtt) {
// Currently we don't support non-truecolor visuals in the
// GLCapabilities, so we don't offer the option of making
// color-index pbuffers.
- iattributes[niattribs++] = WGLExt.WGL_PIXEL_TYPE_ARB;
- iattributes[niattribs++] = WGLExt.WGL_TYPE_RGBA_ARB;
+ iattributes.put(niattribs++, WGLExt.WGL_PIXEL_TYPE_ARB);
+ iattributes.put(niattribs++, WGLExt.WGL_TYPE_RGBA_ARB);
}
}
if (useFloat && nvidia) {
- iattributes[niattribs++] = WGLExt.WGL_FLOAT_COMPONENTS_NV;
- iattributes[niattribs++] = GL.GL_TRUE;
+ iattributes.put(niattribs++, WGLExt.WGL_FLOAT_COMPONENTS_NV);
+ iattributes.put(niattribs++, GL.GL_TRUE);
}
if (rtt) {
@@ -566,66 +576,72 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
if (!rect) {
throw new GLException("Render-to-floating-point-texture only supported on NVidia hardware with render-to-texture-rectangle");
}
- iattributes[niattribs++] = WGLExt.WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV;
- iattributes[niattribs++] = GL.GL_TRUE;
+ iattributes.put(niattribs++, WGLExt.WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV);
+ iattributes.put(niattribs++, GL.GL_TRUE);
} else {
- iattributes[niattribs++] = rect ? WGLExt.WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV : WGLExt.WGL_BIND_TO_TEXTURE_RGB_ARB;
- iattributes[niattribs++] = GL.GL_TRUE;
+ iattributes.put(niattribs++, rect ? WGLExt.WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV : WGLExt.WGL_BIND_TO_TEXTURE_RGB_ARB);
+ iattributes.put(niattribs++, GL.GL_TRUE);
}
}
} else {
- iattributes[niattribs++] = WGLExt.WGL_PIXEL_TYPE_ARB;
- iattributes[niattribs++] = WGLExt.WGL_TYPE_RGBA_ARB;
+ iattributes.put(niattribs++, WGLExt.WGL_PIXEL_TYPE_ARB);
+ iattributes.put(niattribs++, WGLExt.WGL_TYPE_RGBA_ARB);
}
- iattributes[niattribs++] = 0;
+ iattributes.put(niattribs++, 0);
return true;
}
- static int AttribList2DrawableTypeBits(final int[] iattribs, final int niattribs, final int[] iresults) {
+ static int AttribList2DrawableTypeBits(final IntBuffer iattribs,
+ final int niattribs, final IntBuffer iresults) {
int val = 0;
for (int i = 0; i < niattribs; i++) {
- int attr = iattribs[i];
+ final int attr = iattribs.get(i);
switch (attr) {
case WGLExt.WGL_DRAW_TO_WINDOW_ARB:
- if(iresults[i] == GL.GL_TRUE) val |= GLGraphicsConfigurationUtil.WINDOW_BIT;
+ if(iresults.get(i) == GL.GL_TRUE) {
+ val |= GLGraphicsConfigurationUtil.WINDOW_BIT |
+ GLGraphicsConfigurationUtil.FBO_BIT;
+ }
break;
case WGLExt.WGL_DRAW_TO_BITMAP_ARB:
- if(iresults[i] == GL.GL_TRUE) val |= GLGraphicsConfigurationUtil.BITMAP_BIT;
+ if(iresults.get(i) == GL.GL_TRUE) {
+ val |= GLGraphicsConfigurationUtil.BITMAP_BIT;
+ }
break;
case WGLExt.WGL_DRAW_TO_PBUFFER_ARB:
- if(iresults[i] == GL.GL_TRUE) val |= GLGraphicsConfigurationUtil.PBUFFER_BIT;
+ if(iresults.get(i) == GL.GL_TRUE) {
+ val |= GLGraphicsConfigurationUtil.PBUFFER_BIT;
+ }
break;
}
}
return val;
}
- static boolean AttribList2GLCapabilities( List<GLCapabilitiesImmutable> capsBucket,
- final GLProfile glp, final long hdc, final int pfdID, final int[] iattribs,
- final int niattribs,
- final int[] iresults, final int winattrmask) {
+ static WGLGLCapabilities AttribList2GLCapabilities(final AbstractGraphicsDevice device,
+ final GLProfile glp, final long hdc, final int pfdID,
+ final IntBuffer iattribs, final int niattribs, IntBuffer iresults, final int winattrmask) {
final int allDrawableTypeBits = AttribList2DrawableTypeBits(iattribs, niattribs, iresults);
int drawableTypeBits = winattrmask & allDrawableTypeBits;
if( 0 == drawableTypeBits ) {
- return false;
+ return null;
}
PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor();
if (WGLUtil.DescribePixelFormat(hdc, pfdID, PIXELFORMATDESCRIPTOR.size(), pfd) == 0) {
// remove displayable bits, since pfdID is non displayable
- drawableTypeBits = drawableTypeBits & ~(GLGraphicsConfigurationUtil.WINDOW_BIT | GLGraphicsConfigurationUtil.BITMAP_BIT);
+ drawableTypeBits = drawableTypeBits & ~(GLGraphicsConfigurationUtil.WINDOW_BIT | GLGraphicsConfigurationUtil.BITMAP_BIT | GLGraphicsConfigurationUtil.FBO_BIT );
if( 0 == drawableTypeBits ) {
- return false;
+ return null;
}
// non displayable requested (pbuffer)
}
- WGLGLCapabilities res = new WGLGLCapabilities(pfd, pfdID, glp);
+ final WGLGLCapabilities res = new WGLGLCapabilities(pfd, pfdID, glp);
res.setValuesByARB(iattribs, niattribs, iresults);
-
- return GLGraphicsConfigurationUtil.addGLCapabilitiesPermutations(capsBucket, res, drawableTypeBits );
+ return (WGLGLCapabilities) GLGraphicsConfigurationUtil.fixWinAttribBitsAndHwAccel(device, drawableTypeBits, res);
}
//
@@ -651,7 +667,8 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
int dwFlags = pfd.getDwFlags();
if( 0 != (GDI.PFD_DRAW_TO_WINDOW & dwFlags ) ) {
- val |= GLGraphicsConfigurationUtil.WINDOW_BIT;
+ val |= GLGraphicsConfigurationUtil.WINDOW_BIT |
+ GLGraphicsConfigurationUtil.FBO_BIT;
}
if( 0 != (GDI.PFD_DRAW_TO_BITMAP & dwFlags ) ) {
val |= GLGraphicsConfigurationUtil.BITMAP_BIT;
@@ -659,107 +676,124 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
return val;
}
- static WGLGLCapabilities PFD2GLCapabilities(GLProfile glp, long hdc, int pfdID, boolean onscreen) {
- final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, false, false);
- List<GLCapabilitiesImmutable> capsBucket = new ArrayList<GLCapabilitiesImmutable>(1);
- if( PFD2GLCapabilities(capsBucket, glp, hdc, pfdID, winattrmask) ) {
- return (WGLGLCapabilities) capsBucket.get(0);
- }
- return null;
- }
-
- static boolean PFD2GLCapabilities(List<GLCapabilitiesImmutable> capsBucket, final GLProfile glp, final long hdc, final int pfdID, final int winattrmask) {
+ static WGLGLCapabilities PFD2GLCapabilities(AbstractGraphicsDevice device, final GLProfile glp, final long hdc, final int pfdID, final int winattrmask) {
PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor(hdc, pfdID);
if(null == pfd) {
- return false;
+ return null;
}
if ((pfd.getDwFlags() & GDI.PFD_SUPPORT_OPENGL) == 0) {
- return false;
+ return null;
}
final int allDrawableTypeBits = PFD2DrawableTypeBits(pfd);
final int drawableTypeBits = winattrmask & allDrawableTypeBits;
if( 0 == drawableTypeBits ) {
- return false;
+ return null;
}
- WGLGLCapabilities res = new WGLGLCapabilities(pfd, pfdID, glp);
+ final WGLGLCapabilities res = new WGLGLCapabilities(pfd, pfdID, glp);
res.setValuesByGDI();
+ return (WGLGLCapabilities) GLGraphicsConfigurationUtil.fixWinAttribBitsAndHwAccel(device, drawableTypeBits, res);
+ }
- return GLGraphicsConfigurationUtil.addGLCapabilitiesPermutations(capsBucket, res, drawableTypeBits );
- }
-
- static PIXELFORMATDESCRIPTOR GLCapabilities2PFD(GLCapabilitiesImmutable caps, PIXELFORMATDESCRIPTOR pfd) {
- int colorDepth = (caps.getRedBits() +
- caps.getGreenBits() +
- caps.getBlueBits());
- if (colorDepth < 15) {
- throw new GLException("Bit depths < 15 (i.e., non-true-color) not supported");
- }
- int pfdFlags = (GDI.PFD_SUPPORT_OPENGL |
- GDI.PFD_GENERIC_ACCELERATED);
- if (caps.getDoubleBuffered()) {
- pfdFlags |= GDI.PFD_DOUBLEBUFFER;
- }
- if (caps.isOnscreen()) {
- pfdFlags |= GDI.PFD_DRAW_TO_WINDOW;
- } else {
- pfdFlags |= GDI.PFD_DRAW_TO_BITMAP;
- }
- if (caps.getStereo()) {
- pfdFlags |= GDI.PFD_STEREO;
- }
- pfd.setDwFlags(pfdFlags);
- pfd.setIPixelType((byte) GDI.PFD_TYPE_RGBA);
- pfd.setCColorBits((byte) colorDepth);
- pfd.setCRedBits ((byte) caps.getRedBits());
- pfd.setCGreenBits((byte) caps.getGreenBits());
- pfd.setCBlueBits ((byte) caps.getBlueBits());
- pfd.setCAlphaBits((byte) caps.getAlphaBits());
- int accumDepth = (caps.getAccumRedBits() +
- caps.getAccumGreenBits() +
- caps.getAccumBlueBits());
- pfd.setCAccumBits ((byte) accumDepth);
- pfd.setCAccumRedBits ((byte) caps.getAccumRedBits());
- pfd.setCAccumGreenBits((byte) caps.getAccumGreenBits());
- pfd.setCAccumBlueBits ((byte) caps.getAccumBlueBits());
- pfd.setCAccumAlphaBits((byte) caps.getAccumAlphaBits());
- pfd.setCDepthBits((byte) caps.getDepthBits());
- pfd.setCStencilBits((byte) caps.getStencilBits());
- pfd.setILayerType((byte) GDI.PFD_MAIN_PLANE);
-
- // n/a with non ARB/GDI method:
- // multisample
- // opaque
- // pbuffer
- return pfd;
- }
-
- static PIXELFORMATDESCRIPTOR createPixelFormatDescriptor(long hdc, int pfdID) {
- PIXELFORMATDESCRIPTOR pfd = PIXELFORMATDESCRIPTOR.create();
- pfd.setNSize((short) PIXELFORMATDESCRIPTOR.size());
- pfd.setNVersion((short) 1);
- if(0 != hdc && 1 <= pfdID) {
- if (WGLUtil.DescribePixelFormat(hdc, pfdID, PIXELFORMATDESCRIPTOR.size(), pfd) == 0) {
- // Accelerated pixel formats that are non displayable
- if(DEBUG) {
- System.err.println("Info: Non displayable pixel format " + pfdID + " of device context: error code " + GDI.GetLastError());
- }
+ static WGLGLCapabilities PFD2GLCapabilitiesNoCheck(AbstractGraphicsDevice device, final GLProfile glp, final long hdc, final int pfdID) {
+ PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor(hdc, pfdID);
+ return PFD2GLCapabilitiesNoCheck(device, glp, pfd, pfdID);
+ }
+
+ static WGLGLCapabilities PFD2GLCapabilitiesNoCheck(AbstractGraphicsDevice device, GLProfile glp, PIXELFORMATDESCRIPTOR pfd, int pfdID) {
+ if(null == pfd) {
return null;
}
- }
- return pfd;
- }
-
- static PIXELFORMATDESCRIPTOR createPixelFormatDescriptor() {
- return createPixelFormatDescriptor(0, 0);
- }
-
- public String toString() {
- return "WindowsWGLGraphicsConfiguration["+getScreen()+", pfdID " + getPixelFormatID() + ", ARB-Choosen " + isChoosenByARB() +
- ",\n\trequested " + getRequestedCapabilities() +
- ",\n\tchosen " + getChosenCapabilities() +
- "]";
- }
+ final WGLGLCapabilities res = new WGLGLCapabilities(pfd, pfdID, glp);
+ res.setValuesByGDI();
+
+ return (WGLGLCapabilities) GLGraphicsConfigurationUtil.fixWinAttribBitsAndHwAccel(device, PFD2DrawableTypeBits(pfd), res);
+ }
+
+ static PIXELFORMATDESCRIPTOR GLCapabilities2PFD(GLCapabilitiesImmutable caps, PIXELFORMATDESCRIPTOR pfd) {
+ int colorDepth = (caps.getRedBits() +
+ caps.getGreenBits() +
+ caps.getBlueBits());
+ if (colorDepth < 15) {
+ throw new GLException("Bit depths < 15 (i.e., non-true-color) not supported");
+ }
+ int pfdFlags = ( GDI.PFD_SUPPORT_OPENGL | GDI.PFD_GENERIC_ACCELERATED );
+
+ if( caps.isOnscreen() ) {
+ pfdFlags |= GDI.PFD_DRAW_TO_WINDOW;
+ } else if( caps.isFBO() ) {
+ pfdFlags |= GDI.PFD_DRAW_TO_WINDOW; // native replacement!
+ } else if( caps.isPBuffer() ) {
+ pfdFlags |= GDI.PFD_DRAW_TO_BITMAP; // pbuffer n/a, use bitmap
+ } else if( caps.isBitmap() ) {
+ pfdFlags |= GDI.PFD_DRAW_TO_BITMAP;
+ } else {
+ throw new GLException("no surface type set in caps: "+caps);
+ }
+
+ if ( caps.getDoubleBuffered() ) {
+ if( caps.isBitmap() || caps.isPBuffer() ) {
+ pfdFlags |= GDI.PFD_DOUBLEBUFFER_DONTCARE; // bitmaps probably don't have dbl buffering
+ } else {
+ pfdFlags |= GDI.PFD_DOUBLEBUFFER;
+ }
+ }
+
+ if (caps.getStereo()) {
+ pfdFlags |= GDI.PFD_STEREO;
+ }
+ pfd.setDwFlags(pfdFlags);
+ pfd.setIPixelType((byte) GDI.PFD_TYPE_RGBA);
+ pfd.setCColorBits((byte) colorDepth);
+ pfd.setCRedBits ((byte) caps.getRedBits());
+ pfd.setCGreenBits((byte) caps.getGreenBits());
+ pfd.setCBlueBits ((byte) caps.getBlueBits());
+ pfd.setCAlphaBits((byte) caps.getAlphaBits());
+ int accumDepth = (caps.getAccumRedBits() +
+ caps.getAccumGreenBits() +
+ caps.getAccumBlueBits());
+ pfd.setCAccumBits ((byte) accumDepth);
+ pfd.setCAccumRedBits ((byte) caps.getAccumRedBits());
+ pfd.setCAccumGreenBits((byte) caps.getAccumGreenBits());
+ pfd.setCAccumBlueBits ((byte) caps.getAccumBlueBits());
+ pfd.setCAccumAlphaBits((byte) caps.getAccumAlphaBits());
+ pfd.setCDepthBits((byte) caps.getDepthBits());
+ pfd.setCStencilBits((byte) caps.getStencilBits());
+ pfd.setILayerType((byte) GDI.PFD_MAIN_PLANE);
+
+ // n/a with non ARB/GDI method:
+ // multisample
+ // opaque
+ // pbuffer
+ return pfd;
+ }
+
+ static PIXELFORMATDESCRIPTOR createPixelFormatDescriptor(long hdc, int pfdID) {
+ PIXELFORMATDESCRIPTOR pfd = PIXELFORMATDESCRIPTOR.create();
+ pfd.setNSize((short) PIXELFORMATDESCRIPTOR.size());
+ pfd.setNVersion((short) 1);
+ if(0 != hdc && 1 <= pfdID) {
+ if (WGLUtil.DescribePixelFormat(hdc, pfdID, PIXELFORMATDESCRIPTOR.size(), pfd) == 0) {
+ // Accelerated pixel formats that are non displayable
+ if(DEBUG) {
+ System.err.println("Info: Non displayable pixel format " + pfdID + " of device context: error code " + GDI.GetLastError());
+ }
+ return null;
+ }
+ }
+ return pfd;
+ }
+
+ static PIXELFORMATDESCRIPTOR createPixelFormatDescriptor() {
+ return createPixelFormatDescriptor(0, 0);
+ }
+
+ public String toString() {
+ return "WindowsWGLGraphicsConfiguration["+getScreen()+", pfdID " + getPixelFormatID() + ", ARB-Choosen " + isChoosenByARB() +
+ ",\n\trequested " + getRequestedCapabilities() +
+ ",\n\tchosen " + getChosenCapabilities() +
+ "]";
+ }
}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
index 00ed91b..7b3bc3a 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
@@ -50,12 +50,16 @@ import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
+import com.jogamp.common.nio.Buffers;
+
import jogamp.nativewindow.windows.GDI;
import jogamp.nativewindow.windows.PIXELFORMATDESCRIPTOR;
import jogamp.opengl.GLDrawableImpl;
import jogamp.opengl.GLGraphicsConfigurationFactory;
import jogamp.opengl.GLGraphicsConfigurationUtil;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -85,7 +89,11 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilities objects - requested");
}
- return chooseGraphicsConfigurationStatic((GLCapabilitiesImmutable)capsChosen, (GLCapabilitiesImmutable)capsRequested, chooser, absScreen);
+ if (chooser != null && !(chooser instanceof GLCapabilitiesChooser)) {
+ throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilitiesChooser objects");
+ }
+
+ return chooseGraphicsConfigurationStatic((GLCapabilitiesImmutable)capsChosen, (GLCapabilitiesImmutable)capsRequested, (GLCapabilitiesChooser)chooser, absScreen);
}
static WindowsWGLGraphicsConfiguration createDefaultGraphicsConfiguration(GLCapabilitiesImmutable caps,
@@ -95,27 +103,25 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
static WindowsWGLGraphicsConfiguration chooseGraphicsConfigurationStatic(GLCapabilitiesImmutable capsChosen,
GLCapabilitiesImmutable capsReq,
- CapabilitiesChooser chooser,
+ GLCapabilitiesChooser chooser,
AbstractGraphicsScreen absScreen) {
if(null==absScreen) {
absScreen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_WINDOWS);
}
final AbstractGraphicsDevice absDevice = absScreen.getDevice();
- final GLDrawableFactory factory = GLDrawableFactory.getDesktopFactory();
- capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities(
- capsChosen, GLContext.isFBOAvailable(absDevice, capsChosen.getGLProfile()), factory.canCreateGLPbuffer(absDevice) );
-
+ capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( capsChosen, GLDrawableFactory.getDesktopFactory(), absDevice);
return new WindowsWGLGraphicsConfiguration( absScreen, capsChosen, capsReq, (GLCapabilitiesChooser)chooser );
}
protected static List<GLCapabilitiesImmutable> getAvailableCapabilities(WindowsWGLDrawableFactory factory, AbstractGraphicsDevice device) {
- WindowsWGLDrawableFactory.SharedResource sharedResource = factory.getOrCreateSharedResource(device);
+ final WindowsWGLDrawableFactory.SharedResource sharedResource = factory.getOrCreateSharedResource(device);
if(null == sharedResource) {
throw new GLException("Shared resource for device n/a: "+device);
}
- GLDrawableImpl sharedDrawable = sharedResource.getDrawable();
- GLCapabilitiesImmutable capsChosen = sharedDrawable.getChosenGLCapabilities();
- GLContext sharedContext = sharedResource.getContext();
+ final GLDrawableImpl sharedDrawable = sharedResource.getDrawable();
+ final GLContext sharedContext = sharedResource.getContext();
+ final GLProfile glp = GLProfile.getDefault(device);
+
List<GLCapabilitiesImmutable> availableCaps = null;
if ( sharedResource.needsCurrentContext4ARBPFDQueries() ) {
@@ -131,10 +137,10 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
throw new GLException("Error: HDC is null");
}
if (sharedResource.hasARBPixelFormat()) {
- availableCaps = getAvailableGLCapabilitiesARB(hdc, sharedResource, capsChosen.getGLProfile());
+ availableCaps = WindowsWGLGraphicsConfigurationFactory.getAvailableGLCapabilitiesARB(sharedResource, sharedResource.getDevice(), glp, hdc);
}
if( null == availableCaps || availableCaps.isEmpty() ) {
- availableCaps = getAvailableGLCapabilitiesGDI(hdc, capsChosen.getGLProfile());
+ availableCaps = getAvailableGLCapabilitiesGDI(device, glp, hdc);
}
} finally {
if ( sharedResource.needsCurrentContext4ARBPFDQueries() ) {
@@ -150,17 +156,21 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
return availableCaps;
}
- static List<GLCapabilitiesImmutable> getAvailableGLCapabilitiesARB(long hdc, WindowsWGLDrawableFactory.SharedResource sharedResource, GLProfile glProfile) {
- int[] pformats = WindowsWGLGraphicsConfiguration.wglAllARBPFIDs((WindowsWGLContext)sharedResource.getContext(), hdc);
- return WindowsWGLGraphicsConfiguration.wglARBPFIDs2AllGLCapabilities(sharedResource, hdc, pformats, glProfile);
+ static List<GLCapabilitiesImmutable> getAvailableGLCapabilitiesARB(WindowsWGLDrawableFactory.SharedResource sharedResource, AbstractGraphicsDevice device, GLProfile glProfile, long hdc) {
+ final int pfdIDCount = WindowsWGLGraphicsConfiguration.wglARBPFDIDCount((WindowsWGLContext)sharedResource.getContext(), hdc);
+ final int[] pformats = WindowsWGLGraphicsConfiguration.wglAllARBPFDIDs(pfdIDCount);
+ return WindowsWGLGraphicsConfiguration.wglARBPFIDs2GLCapabilities(sharedResource, device, glProfile, hdc, pformats, GLGraphicsConfigurationUtil.ALL_BITS);
}
- static List<GLCapabilitiesImmutable> getAvailableGLCapabilitiesGDI(long hdc, GLProfile glProfile) {
+ static List<GLCapabilitiesImmutable> getAvailableGLCapabilitiesGDI(AbstractGraphicsDevice device, GLProfile glProfile, long hdc) {
int[] pformats = WindowsWGLGraphicsConfiguration.wglAllGDIPFIDs(hdc);
int numFormats = pformats.length;
List<GLCapabilitiesImmutable> bucket = new ArrayList<GLCapabilitiesImmutable>(numFormats);
for (int i = 0; i < numFormats; i++) {
- WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(bucket, glProfile, hdc, pformats[i], GLGraphicsConfigurationUtil.ALL_BITS);
+ final GLCapabilitiesImmutable caps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(device, glProfile, hdc, pformats[i], GLGraphicsConfigurationUtil.ALL_BITS);
+ if(null != caps) {
+ bucket.add(caps);
+ }
}
return bucket;
}
@@ -274,8 +284,8 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
}
}
try {
- if( !updateGraphicsConfigurationARB(hdc, extHDC, config, chooser, (WindowsWGLDrawableFactory)factory, pfdIDs) ) {
- updateGraphicsConfigurationGDI(hdc, extHDC, config, chooser, pfdIDs);
+ if( !updateGraphicsConfigurationARB((WindowsWGLDrawableFactory)factory, config, chooser, hdc, extHDC, pfdIDs) ) {
+ updateGraphicsConfigurationGDI(config, chooser, hdc, extHDC, pfdIDs);
}
} finally {
if (null != sharedContext) {
@@ -284,10 +294,10 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
}
}
- private static boolean updateGraphicsConfigurationARB(long hdc, boolean extHDC, WindowsWGLGraphicsConfiguration config,
- CapabilitiesChooser chooser, WindowsWGLDrawableFactory factory, int[] pformats) {
- AbstractGraphicsDevice device = config.getScreen().getDevice();
- WindowsWGLDrawableFactory.SharedResource sharedResource = factory.getOrCreateSharedResource(device);
+ private static boolean updateGraphicsConfigurationARB(WindowsWGLDrawableFactory factory, WindowsWGLGraphicsConfiguration config, CapabilitiesChooser chooser,
+ long hdc, boolean extHDC, int[] pformats) {
+ final AbstractGraphicsDevice device = config.getScreen().getDevice();
+ final WindowsWGLDrawableFactory.SharedResource sharedResource = factory.getOrCreateSharedResource(device);
if (null == sharedResource) {
if (DEBUG) {
@@ -302,16 +312,25 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
return false;
}
- GLCapabilitiesImmutable capsChosen = (GLCapabilitiesImmutable) config.getChosenCapabilities();
- boolean isOpaque = capsChosen.isBackgroundOpaque() && GDI.DwmIsCompositionEnabled();
- boolean onscreen = capsChosen.isOnscreen();
- boolean usePBuffer = capsChosen.isPBuffer();
- GLProfile glProfile = capsChosen.getGLProfile();
+ final GLCapabilitiesImmutable capsChosen = (GLCapabilitiesImmutable) config.getChosenCapabilities();
+ final boolean isOpaque = capsChosen.isBackgroundOpaque() && GDI.DwmIsCompositionEnabled();
+ final int winattrbits = GLGraphicsConfigurationUtil.getExclusiveWinAttributeBits(capsChosen);
+ final GLProfile glProfile = capsChosen.getGLProfile();
+
+ final int pfdIDCount = WindowsWGLGraphicsConfiguration.wglARBPFDIDCount((WindowsWGLContext)sharedResource.getContext(), hdc);
if(DEBUG) {
- System.err.println("translucency requested: "+(!capsChosen.isBackgroundOpaque())+", compositioning enabled: "+GDI.DwmIsCompositionEnabled()+" -> translucency "+(!isOpaque));
+ System.err.println("updateGraphicsConfigurationARB: hdc "+toHexString(hdc)+", pfdIDCount(hdc) "+pfdIDCount+", capsChosen "+capsChosen+", "+GLGraphicsConfigurationUtil.winAttributeBits2String(null, winattrbits).toString());
+ System.err.println("isOpaque "+isOpaque+" (translucency requested: "+(!capsChosen.isBackgroundOpaque())+", compositioning enabled: "+GDI.DwmIsCompositionEnabled()+")");
}
+ if(0 >= pfdIDCount) {
+ if (DEBUG) {
+ System.err.println("updateGraphicsConfigurationARB: failed due to 0 pfdIDs for hdc "+toHexString(hdc)+" - hdc incompatible w/ ARB ext.");
+ }
+ return false;
+ }
+
WGLGLCapabilities pixelFormatCaps = null; // chosen or preset PFD ID's caps
boolean pixelFormatSet = false; // indicates a preset PFD ID [caps]
final int presetPFDID = extHDC ? -1 : WGLUtil.GetPixelFormat(hdc) ;
@@ -325,7 +344,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
+ ", pixelformat " + presetPFDID);
}
pixelFormatSet = true;
- pixelFormatCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedResource, hdc, presetPFDID, glProfile, onscreen, usePBuffer);
+ pixelFormatCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedResource, device, glProfile, hdc, presetPFDID, winattrbits);
pixelFormatCaps = (WGLGLCapabilities) GLGraphicsConfigurationUtil.fixOpaqueGLCapabilities(pixelFormatCaps, isOpaque);
} else {
int recommendedIndex = -1; // recommended index
@@ -334,20 +353,20 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
// No given PFD IDs
//
// 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice
- int[] iattributes = new int[2 * WindowsWGLGraphicsConfiguration.MAX_ATTRIBS];
- float[] fattributes = new float[1];
+ final IntBuffer iattributes = Buffers.newDirectIntBuffer(2*WindowsWGLGraphicsConfiguration.MAX_ATTRIBS);
+ final FloatBuffer fattributes = Buffers.newDirectFloatBuffer(1);
int accelerationMode = WGLExt.WGL_FULL_ACCELERATION_ARB;
- pformats = WindowsWGLGraphicsConfiguration.wglChoosePixelFormatARB(hdc, sharedResource, capsChosen,
- iattributes, accelerationMode, fattributes);
+ pformats = WindowsWGLGraphicsConfiguration.wglChoosePixelFormatARB(sharedResource, device, capsChosen,
+ hdc, iattributes, accelerationMode, fattributes);
if (null == pformats) {
accelerationMode = WGLExt.WGL_GENERIC_ACCELERATION_ARB;
- pformats = WindowsWGLGraphicsConfiguration.wglChoosePixelFormatARB(hdc, sharedResource, capsChosen,
- iattributes, accelerationMode, fattributes);
+ pformats = WindowsWGLGraphicsConfiguration.wglChoosePixelFormatARB(sharedResource, device, capsChosen,
+ hdc, iattributes, accelerationMode, fattributes);
}
if (null == pformats) {
accelerationMode = -1; // use what we are offered ..
- pformats = WindowsWGLGraphicsConfiguration.wglChoosePixelFormatARB(hdc, sharedResource, capsChosen,
- iattributes, accelerationMode, fattributes);
+ pformats = WindowsWGLGraphicsConfiguration.wglChoosePixelFormatARB(sharedResource, device, capsChosen,
+ hdc, iattributes, accelerationMode, fattributes);
}
if (null != pformats) {
recommendedIndex = 0;
@@ -356,7 +375,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
System.err.println("updateGraphicsConfigurationARB: wglChoosePixelFormatARB failed with: "+capsChosen);
}
// 2nd choice: get all GLCapabilities available, no preferred recommendedIndex available
- pformats = WindowsWGLGraphicsConfiguration.wglAllARBPFIDs((WindowsWGLContext)sharedResource.getContext(), hdc);
+ pformats = WindowsWGLGraphicsConfiguration.wglAllARBPFDIDs(pfdIDCount);
if (DEBUG) {
final int len = ( null != pformats ) ? pformats.length : 0;
System.err.println("updateGraphicsConfigurationARB: NumFormats (wglAllARBPFIDs) " + len);
@@ -371,13 +390,12 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
}
}
- List<GLCapabilitiesImmutable> availableCaps =
- WindowsWGLGraphicsConfiguration.wglARBPFIDs2GLCapabilities(sharedResource, hdc, pformats,
- glProfile, onscreen, usePBuffer);
+ List<GLCapabilitiesImmutable> availableCaps =
+ WindowsWGLGraphicsConfiguration.wglARBPFIDs2GLCapabilities(sharedResource, device, glProfile, hdc, pformats, winattrbits);
+
if( null == availableCaps || 0 == availableCaps.size() ) {
if (DEBUG) {
- System.err.println("updateGraphicsConfigurationARB: wglARBPFIDs2GLCapabilities failed with " + pformats.length +
- " pfd ids, onscreen " + onscreen + ", pbuffer " + usePBuffer);
+ System.err.println("updateGraphicsConfigurationARB: wglARBPFIDs2GLCapabilities failed with " + pformats.length + " pfd ids");
Thread.dumpStack();
}
return false;
@@ -385,7 +403,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
if (DEBUG) {
System.err.println("updateGraphicsConfigurationARB: " + pformats.length +
- " pfd ids, onscreen " + onscreen + ", pbuffer " + usePBuffer + ", " + availableCaps.size() + " glcaps");
+ " pfd ids, " + GLGraphicsConfigurationUtil.winAttributeBits2String(null, winattrbits).toString() + ", " + availableCaps.size() + " glcaps");
if(0 <= recommendedIndex) {
System.err.println("updateGraphicsConfigurationARB: Used wglChoosePixelFormatARB to recommend pixel format " +
pformats[recommendedIndex] + ", idx " + recommendedIndex +", "+availableCaps.get(recommendedIndex));
@@ -420,19 +438,25 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
return true;
}
- private static boolean updateGraphicsConfigurationGDI(long hdc, boolean extHDC, WindowsWGLGraphicsConfiguration config,
- CapabilitiesChooser chooser, int[] pformats) {
+ private static boolean updateGraphicsConfigurationGDI(WindowsWGLGraphicsConfiguration config, CapabilitiesChooser chooser, long hdc,
+ boolean extHDC, int[] pformats) {
GLCapabilitiesImmutable capsChosen = (GLCapabilitiesImmutable) config.getChosenCapabilities();
- if(capsChosen.isPBuffer()) {
+ if( !capsChosen.isOnscreen() && capsChosen.isPBuffer() ) {
if (DEBUG) {
System.err.println("updateGraphicsConfigurationGDI: no pbuffer supported on GDI: " + capsChosen);
}
return false;
}
- boolean onscreen = capsChosen.isOnscreen();
- GLProfile glProfile = capsChosen.getGLProfile();
-
- List<GLCapabilitiesImmutable> availableCaps = new ArrayList<GLCapabilitiesImmutable>();
+ // final boolean onscreen = capsChosen.isOnscreen();
+ // final boolean useFBO = capsChosen.isFBO();
+ final GLProfile glProfile = capsChosen.getGLProfile();
+ final int winattrmask = GLGraphicsConfigurationUtil.getExclusiveWinAttributeBits(capsChosen);
+
+ if(DEBUG) {
+ System.err.println("updateGraphicsConfigurationGDI: capsChosen "+capsChosen+", "+GLGraphicsConfigurationUtil.winAttributeBits2String(null, winattrmask).toString());
+ }
+
+ AbstractGraphicsDevice device = config.getScreen().getDevice();
int pfdID; // chosen or preset PFD ID
WGLGLCapabilities pixelFormatCaps = null; // chosen or preset PFD ID's caps
boolean pixelFormatSet = false; // indicates a preset PFD ID [caps]
@@ -447,15 +471,29 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
+ ", pixelformat " + pfdID);
}
pixelFormatSet = true;
- pixelFormatCaps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, hdc, pfdID, onscreen);
+ pixelFormatCaps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(device, glProfile, hdc, pfdID, winattrmask);
+ if(null == pixelFormatCaps) {
+ throw new GLException("Could not map PFD2GLCaps w/ already chosen pfdID "+pfdID);
+ }
} else {
- if(null == pformats) {
+ final boolean givenPFormats = null != pformats;
+ if( !givenPFormats ) {
pformats = WindowsWGLGraphicsConfiguration.wglAllGDIPFIDs(hdc);
}
- final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, false, false);
+ List<GLCapabilitiesImmutable> availableCaps = new ArrayList<GLCapabilitiesImmutable>();
for (int i = 0; i < pformats.length; i++) {
- WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(availableCaps, glProfile, hdc, pformats[i], winattrmask);
+ final GLCapabilitiesImmutable caps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(device, glProfile, hdc, pformats[i], winattrmask);
+ if(null != caps) {
+ availableCaps.add(caps);
+ if(DEBUG) {
+ final int j = availableCaps.size() - 1;
+ System.err.println("updateGraphicsConfigurationGDI: availableCaps["+i+" -> "+j+"]: "+caps);
+ }
+ } else if(DEBUG) {
+ GLCapabilitiesImmutable skipped = WindowsWGLGraphicsConfiguration.PFD2GLCapabilitiesNoCheck(device, glProfile, hdc, pformats[i]);
+ System.err.println("updateGraphicsConfigurationGDI: availableCaps["+i+" -> skip]: pfdID "+pformats[i]+", "+skipped);
+ }
}
// 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice
@@ -464,16 +502,21 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
pfdID = WGLUtil.ChoosePixelFormat(hdc, pfd);
int recommendedIndex = -1 ;
if( 1 <= pfdID ) {
- // seek index ..
+ // seek index .. in all formats _or_ in given formats!
for (recommendedIndex = availableCaps.size() - 1 ;
0 <= recommendedIndex && pfdID != ((WGLGLCapabilities) availableCaps.get(recommendedIndex)).getPFDID();
recommendedIndex--)
{ /* nop */ }
+ if(DEBUG && 0 > recommendedIndex) {
+ final GLCapabilitiesImmutable reqPFDCaps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilitiesNoCheck(device, glProfile, pfd, pfdID);
+ final GLCapabilitiesImmutable chosenCaps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(device, glProfile, hdc, pfdID, winattrmask);
+ System.err.println("Chosen PFDID "+pfdID+", but not found in available caps (use given pfdIDs "+givenPFormats+", reqPFDCaps "+reqPFDCaps+", chosenCaps: "+chosenCaps);
+ }
}
- // 2nd choice: if no preferred recommendedIndex available
if (DEBUG) {
- System.err.println("updateGraphicsConfigurationGDI: ChoosePixelFormat(HDC " + toHexString(hdc) + ") = " + pfdID + ", idx " + recommendedIndex + " (LastError: " + GDI.GetLastError() + ")");
+ System.err.println("updateGraphicsConfigurationGDI: ChoosePixelFormat(HDC " + toHexString(hdc) + ") = pfdID " + pfdID + ", idx " + recommendedIndex + " (LastError: " + GDI.GetLastError() + ")");
}
+ // 2nd choice: if no preferred recommendedIndex available
int chosenIndex = chooseCapabilities(chooser, capsChosen, availableCaps, recommendedIndex);
if ( 0 > chosenIndex ) {
if (DEBUG) {
@@ -484,8 +527,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
}
pixelFormatCaps = (WGLGLCapabilities) availableCaps.get(chosenIndex);
if (DEBUG) {
- System.err.println("chosen pfdID (GDI): native recommended "+ (recommendedIndex+1) +
- ", caps " + pixelFormatCaps);
+ System.err.println("chosen pfdID (GDI): chosenIndex "+ chosenIndex + ", caps " + pixelFormatCaps);
}
}
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/GLXUtil.java b/src/jogl/classes/jogamp/opengl/x11/glx/GLXUtil.java
index 7cc2d0f..2c591cf 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/GLXUtil.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/GLXUtil.java
@@ -33,10 +33,13 @@
package jogamp.opengl.x11.glx;
+import java.nio.IntBuffer;
+
import javax.media.opengl.GLException;
import jogamp.opengl.Debug;
+import com.jogamp.common.nio.Buffers;
import com.jogamp.common.util.VersionNumber;
import com.jogamp.nativewindow.x11.X11GraphicsDevice;
@@ -51,34 +54,68 @@ public class GLXUtil {
throw new IllegalArgumentException("null X11GraphicsDevice display handle");
}
boolean glXAvailable = false;
+ x11Device.lock();
try {
- glXAvailable = GLX.glXQueryExtension(x11Device.getHandle(), null, 0, null, 0);
- } catch (Throwable t) { /* n/a */ }
+ glXAvailable = GLX.glXQueryExtension(x11Device.getHandle(), null, null);
+ } catch (Throwable t) { /* n/a */
+ } finally {
+ x11Device.unlock();
+ }
return glXAvailable;
}
- public static VersionNumber getGLXServerVersionNumber(long display) {
- int[] major = new int[1];
- int[] minor = new int[1];
+ public static String getGLXClientString(X11GraphicsDevice x11Device, int name) {
+ x11Device.lock();
+ try {
+ return GLX.glXGetClientString(x11Device.getHandle(), name);
+ } finally {
+ x11Device.unlock();
+ }
+ }
+ public static String queryGLXServerString(X11GraphicsDevice x11Device, int screen_idx, int name) {
+ x11Device.lock();
+ try {
+ return GLX.glXQueryServerString(x11Device.getHandle(), screen_idx, name);
+ } finally {
+ x11Device.unlock();
+ }
+ }
+ public static String queryGLXExtensionsString(X11GraphicsDevice x11Device, int screen_idx) {
+ x11Device.lock();
+ try {
+ return GLX.glXQueryExtensionsString(x11Device.getHandle(), screen_idx);
+ } finally {
+ x11Device.unlock();
+ }
+ }
+
+ public static VersionNumber getGLXServerVersionNumber(X11GraphicsDevice x11Device) {
+ final IntBuffer major = Buffers.newDirectIntBuffer(1);
+ final IntBuffer minor = Buffers.newDirectIntBuffer(1);
- if (!GLX.glXQueryVersion(display, major, 0, minor, 0)) {
- throw new GLException("glXQueryVersion failed");
+ x11Device.lock();
+ try {
+ if (!GLX.glXQueryVersion(x11Device.getHandle(), major, minor)) {
+ throw new GLException("glXQueryVersion failed");
+ }
+
+ // Work around bugs in ATI's Linux drivers where they report they
+ // only implement GLX version 1.2 on the server side
+ if (major.get(0) == 1 && minor.get(0) == 2) {
+ String str = GLX.glXGetClientString(x11Device.getHandle(), GLX.GLX_VERSION);
+ try {
+ // e.g. "1.3"
+ major.put(0, Integer.valueOf(str.substring(0, 1)).intValue());
+ minor.put(0, Integer.valueOf(str.substring(2, 3)).intValue());
+ } catch (Exception e) {
+ major.put(0, 1);
+ minor.put(0, 2);
+ }
+ }
+ } finally {
+ x11Device.unlock();
}
-
- // Work around bugs in ATI's Linux drivers where they report they
- // only implement GLX version 1.2 on the server side
- if (major[0] == 1 && minor[0] == 2) {
- String str = GLX.glXGetClientString(display, GLX.GLX_VERSION);
- try {
- // e.g. "1.3"
- major[0] = Integer.valueOf(str.substring(0, 1)).intValue();
- minor[0] = Integer.valueOf(str.substring(2, 3)).intValue();
- } catch (Exception e) {
- major[0] = 1;
- minor[0] = 2;
- }
- }
- return new VersionNumber(major[0], minor[0], 0);
+ return new VersionNumber(major.get(0), minor.get(0), 0);
}
public static boolean isMultisampleAvailable(String extensions) {
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXContext.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXContext.java
index 1f3edbd..bebb4e6 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXContext.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXContext.java
@@ -40,6 +40,8 @@
package jogamp.opengl.x11.glx;
+import java.nio.IntBuffer;
+
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.VisualIDHolder;
import javax.media.opengl.GLCapabilities;
@@ -48,10 +50,11 @@ import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
+import jogamp.nativewindow.WrappedSurface;
import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLContextShareSet;
-import com.jogamp.nativewindow.WrappedSurface;
+import com.jogamp.common.nio.Buffers;
import com.jogamp.nativewindow.x11.X11GraphicsScreen;
public class X11ExternalGLXContext extends X11GLXContext {
@@ -78,34 +81,34 @@ public class X11ExternalGLXContext extends X11GLXContext {
if (drawable == 0) {
throw new GLException("Error: attempted to make an external GLDrawable without a drawable/context current");
}
- int[] val = new int[1];
+ IntBuffer val = Buffers.newDirectIntBuffer(1);
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.glXQueryDrawable(display, drawable, GLX.GLX_WIDTH, val);
+ w=val.get(0);
+ GLX.glXQueryDrawable(display, drawable, GLX.GLX_HEIGHT, val);
+ h=val.get(0);
- GLX.glXQueryContext(display, ctx, GLX.GLX_SCREEN, val, 0);
- X11GraphicsScreen x11Screen = (X11GraphicsScreen) X11GraphicsScreen.createScreenDevice(display, val[0], false);
+ GLX.glXQueryContext(display, ctx, GLX.GLX_SCREEN, val);
+ X11GraphicsScreen x11Screen = (X11GraphicsScreen) X11GraphicsScreen.createScreenDevice(display, val.get(0), false);
- GLX.glXQueryContext(display, ctx, GLX.GLX_FBCONFIG_ID, val, 0);
+ GLX.glXQueryContext(display, ctx, GLX.GLX_FBCONFIG_ID, val);
X11GLXGraphicsConfiguration cfg = null;
// sometimes glXQueryContext on an external context gives us a framebuffer config ID
// of 0, which doesn't work in a subsequent call to glXChooseFBConfig; if this happens,
// create and use a default config (this has been observed when running on CentOS 5.5 inside
// of VMWare Server 2.0 with the Mesa 6.5.1 drivers)
- if( VisualIDHolder.VID_UNDEFINED == val[0] || !X11GLXGraphicsConfiguration.GLXFBConfigIDValid(display, x11Screen.getIndex(), val[0]) ) {
+ if( VisualIDHolder.VID_UNDEFINED == val.get(0) || !X11GLXGraphicsConfiguration.GLXFBConfigIDValid(display, x11Screen.getIndex(), val.get(0)) ) {
GLCapabilities glcapsDefault = new GLCapabilities(GLProfile.getDefault());
cfg = X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(glcapsDefault, glcapsDefault, null, x11Screen, VisualIDHolder.VID_UNDEFINED);
if(DEBUG) {
- System.err.println("X11ExternalGLXContext invalid FBCONFIG_ID "+val[0]+", using default cfg: " + cfg);
+ System.err.println("X11ExternalGLXContext invalid FBCONFIG_ID "+val.get(0)+", using default cfg: " + cfg);
}
} else {
- cfg = X11GLXGraphicsConfiguration.create(glp, x11Screen, val[0]);
+ cfg = X11GLXGraphicsConfiguration.create(glp, x11Screen, val.get(0));
}
- final WrappedSurface ns = new WrappedSurface(cfg, drawable, w, h, null);
+ final WrappedSurface ns = new WrappedSurface(cfg, drawable, w, h, true);
return new X11ExternalGLXContext(new Drawable(factory, ns), ctx);
}
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXDrawable.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXDrawable.java
index 8652e2d..fca36c0 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXDrawable.java
@@ -39,13 +39,17 @@
package jogamp.opengl.x11.glx;
+import java.nio.IntBuffer;
+
import javax.media.nativewindow.NativeSurface;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
-import com.jogamp.nativewindow.WrappedSurface;
+import jogamp.nativewindow.WrappedSurface;
+
+import com.jogamp.common.nio.Buffers;
import com.jogamp.nativewindow.x11.X11GraphicsScreen;
@@ -68,26 +72,27 @@ public class X11ExternalGLXDrawable extends X11GLXDrawable {
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], false);
+ IntBuffer val = Buffers.newDirectIntBuffer(1);
+
+ GLX.glXQueryContext(display, context, GLX.GLX_SCREEN, val);
+ X11GraphicsScreen x11Screen = (X11GraphicsScreen) X11GraphicsScreen.createScreenDevice(display, val.get(0), false);
- GLX.glXQueryContext(display, context, GLX.GLX_FBCONFIG_ID, val, 0);
- X11GLXGraphicsConfiguration cfg = X11GLXGraphicsConfiguration.create(glp, x11Screen, val[0]);
+ GLX.glXQueryContext(display, context, GLX.GLX_FBCONFIG_ID, val);
+ X11GLXGraphicsConfiguration cfg = X11GLXGraphicsConfiguration.create(glp, x11Screen, val.get(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.glXQueryDrawable(display, drawable, GLX.GLX_WIDTH, val);
+ w=val.get(0);
+ GLX.glXQueryDrawable(display, drawable, GLX.GLX_HEIGHT, val);
+ h=val.get(0);
- GLX.glXQueryContext(display, context, GLX.GLX_RENDER_TYPE, val, 0);
- if ((val[0] & GLX.GLX_RGBA_TYPE) == 0) {
+ GLX.glXQueryContext(display, context, GLX.GLX_RENDER_TYPE, val);
+ if ((val.get(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])+")");
+ System.err.println("X11ExternalGLXDrawable: WARNING: forcing GLX_RGBA_TYPE for newly created contexts (current 0x"+Integer.toHexString(val.get(0))+")");
}
}
- return new X11ExternalGLXDrawable(factory, new WrappedSurface(cfg, drawable, w, h, null));
+ return new X11ExternalGLXDrawable(factory, new WrappedSurface(cfg, drawable, w, h, true));
}
@Override
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java
index e1e25be..76e0bc1 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java
@@ -53,14 +53,16 @@ import javax.media.opengl.GLContext;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
-import jogamp.nativewindow.x11.X11Lib;
import jogamp.nativewindow.x11.X11Util;
import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLDrawableImpl;
+import jogamp.opengl.GLXExtensions;
import com.jogamp.common.nio.Buffers;
+import com.jogamp.common.util.VersionNumber;
import com.jogamp.gluegen.runtime.ProcAddressTable;
import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver;
+import com.jogamp.nativewindow.x11.X11GraphicsDevice;
import com.jogamp.opengl.GLExtensions;
public abstract class X11GLXContext extends GLContextImpl {
@@ -70,13 +72,16 @@ public abstract class X11GLXContext extends GLContextImpl {
// Table that holds the addresses of the native C-language entry points for
// GLX extension functions.
private GLXExtProcAddressTable glXExtProcAddressTable;
- private int hasSwapIntervalSGI = 0;
+ /** 1 MESA, 2 SGI, 0 undefined, -1 none */
+ private int hasSwapInterval = 0;
private int hasSwapGroupNV = 0;
// 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;
+ protected volatile VersionNumber glXServerVersion;
+ protected volatile boolean isGLXVersionGreaterEqualOneThree;
static {
functionNameMap = new HashMap<String, String>();
@@ -97,9 +102,11 @@ public abstract class X11GLXContext extends GLContextImpl {
protected void resetStates() {
// no inner state _glXExt=null;
glXExtProcAddressTable = null;
- hasSwapIntervalSGI = 0;
+ hasSwapInterval = 0;
hasSwapGroupNV = 0;
isDirect = false;
+ glXServerVersion = null;
+ isGLXVersionGreaterEqualOneThree = false;
super.resetStates();
}
@@ -130,8 +137,13 @@ public abstract class X11GLXContext extends GLContextImpl {
@Override
protected Map<String, String> getExtensionNameMap() { return extensionNameMap; }
- protected final boolean isGLXVersionGreaterEqualOneThree() {
- return ((X11GLXDrawableFactory)drawable.getFactoryImpl()).isGLXVersionGreaterEqualOneThree(drawable.getNativeSurface().getGraphicsConfiguration().getScreen().getDevice());
+ protected final boolean isGLXVersionGreaterEqualOneThree() { // fast-path: use cached boolean
+ if(null != glXServerVersion) {
+ return isGLXVersionGreaterEqualOneThree;
+ }
+ glXServerVersion = ((X11GLXDrawableFactory)drawable.getFactoryImpl()).getGLXVersionNumber(drawable.getNativeSurface().getGraphicsConfiguration().getScreen().getDevice());
+ isGLXVersionGreaterEqualOneThree = null != glXServerVersion ? glXServerVersion.compareTo(X11GLXDrawableFactory.versionOneThree) >= 0 : false;
+ return isGLXVersionGreaterEqualOneThree;
}
@Override
@@ -144,8 +156,10 @@ public abstract class X11GLXContext extends GLContextImpl {
try {
if ( isGLXVersionGreaterEqualOneThree() ) {
+ // System.err.println(getThreadName() +": X11GLXContext.makeCurrent: obj " + toHexString(hashCode()) + " / ctx "+toHexString(contextHandle)+": ctx "+toHexString(ctx)+", [write "+toHexString(writeDrawable)+", read "+toHexString(readDrawable)+"] - switch");
res = GLX.glXMakeContextCurrent(dpy, writeDrawable, readDrawable, ctx);
} else if ( writeDrawable == readDrawable ) {
+ // System.err.println(getThreadName() +": X11GLXContext.makeCurrent: obj " + toHexString(hashCode()) + " / ctx "+toHexString(contextHandle)+": ctx "+toHexString(ctx)+", [write "+toHexString(writeDrawable)+"] - switch");
res = GLX.glXMakeCurrent(dpy, writeDrawable, ctx);
} else {
// should not happen due to 'isGLReadDrawableAvailable()' query in GLContextImpl
@@ -166,13 +180,11 @@ public abstract class X11GLXContext extends GLContextImpl {
@Override
protected void destroyContextARBImpl(long ctx) {
- X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeSurface().getGraphicsConfiguration();
- long display = config.getScreen().getDevice().getHandle();
+ final long display = drawable.getNativeSurface().getDisplayHandle();
glXMakeContextCurrent(display, 0, 0, 0);
GLX.glXDestroyContext(display, ctx);
}
-
private static final int ctx_arb_attribs_idx_major = 0;
private static final int ctx_arb_attribs_idx_minor = 2;
private static final int ctx_arb_attribs_idx_flags = 6;
@@ -228,20 +240,20 @@ public abstract class X11GLXContext extends GLContextImpl {
X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeSurface().getGraphicsConfiguration();
AbstractGraphicsDevice device = config.getScreen().getDevice();
- long display = device.getHandle();
+ final long display = device.getHandle();
try {
// critical path, a remote display might not support this command,
// hence we need to catch the X11 Error within this block.
- X11Lib.XSync(display, false);
+ X11Util.setX11ErrorHandler(true, DEBUG ? false : true); // make sure X11 error handler is set
ctx = _glXExt.glXCreateContextAttribsARB(display, config.getFBConfig(), share, direct, attribs);
- X11Lib.XSync(display, false);
} catch (RuntimeException re) {
if(DEBUG) {
Throwable t = new Throwable(getThreadName()+": Info: X11GLXContext.createContextARBImpl glXCreateContextAttribsARB failed with "+getGLVersion(major, minor, ctp, "@creation"), re);
t.printStackTrace();
}
}
+
if(0!=ctx) {
if (!glXMakeContextCurrent(display, drawable.getHandle(), drawableRead.getHandle(), ctx)) {
if(DEBUG) {
@@ -263,16 +275,6 @@ public abstract class X11GLXContext extends GLContextImpl {
@Override
protected boolean createImpl(GLContextImpl shareWith) {
- // covers the whole context creation loop incl createContextARBImpl and destroyContextARBImpl
- X11Util.setX11ErrorHandler(true, DEBUG ? false : true);
- try {
- return createImplRaw(shareWith);
- } finally {
- X11Util.setX11ErrorHandler(false, false);
- }
- }
-
- private boolean createImplRaw(GLContextImpl shareWith) {
boolean direct = true; // try direct always
isDirect = false; // fall back
@@ -401,14 +403,9 @@ public abstract class X11GLXContext extends GLContextImpl {
protected void makeCurrentImpl() throws GLException {
long dpy = drawable.getNativeSurface().getDisplayHandle();
- if (GLX.glXGetCurrentContext() != contextHandle) {
- X11Util.setX11ErrorHandler(true, DEBUG ? false : true);
- try {
- if (!glXMakeContextCurrent(dpy, drawable.getHandle(), drawableRead.getHandle(), contextHandle)) {
- throw new GLException(getThreadName()+": Error making context current: "+this);
- }
- } finally {
- X11Util.setX11ErrorHandler(false, false);
+ if (GLX.glXGetCurrentContext() != contextHandle) {
+ if (!glXMakeContextCurrent(dpy, drawable.getHandle(), drawableRead.getHandle(), contextHandle)) {
+ throw new GLException(getThreadName()+": Error making context current: "+this);
}
}
}
@@ -416,19 +413,14 @@ public abstract class X11GLXContext extends GLContextImpl {
@Override
protected void releaseImpl() throws GLException {
long display = drawable.getNativeSurface().getDisplayHandle();
- X11Util.setX11ErrorHandler(true, DEBUG ? false : true);
- try {
- if (!glXMakeContextCurrent(display, 0, 0, 0)) {
- throw new GLException(getThreadName()+": Error freeing OpenGL context");
- }
- } finally {
- X11Util.setX11ErrorHandler(false, false);
+ if (!glXMakeContextCurrent(display, 0, 0, 0)) {
+ throw new GLException(getThreadName()+": Error freeing OpenGL context");
}
}
@Override
protected void destroyImpl() throws GLException {
- GLX.glXDestroyContext(drawable.getNativeSurface().getDisplayHandle(), contextHandle);
+ destroyContextARBImpl(contextHandle);
}
@Override
@@ -474,35 +466,40 @@ public abstract class X11GLXContext extends GLContextImpl {
@Override
protected final StringBuilder getPlatformExtensionsStringImpl() {
- StringBuilder sb = new StringBuilder();
- if (DEBUG) {
- System.err.println("GLX Version client version "+ GLXUtil.getClientVersionNumber()+
- ", server: "+
- ((X11GLXDrawableFactory)drawable.getFactoryImpl()).getGLXVersionNumber(drawable.getNativeSurface().getGraphicsConfiguration().getScreen().getDevice()));
- }
final NativeSurface ns = drawable.getNativeSurface();
- if(((X11GLXDrawableFactory)drawable.getFactoryImpl()).isGLXVersionGreaterEqualOneOne(ns.getGraphicsConfiguration().getScreen().getDevice())) {
- {
- final String ret = GLX.glXGetClientString(ns.getDisplayHandle(), GLX.GLX_EXTENSIONS);
- if (DEBUG) {
- System.err.println("GLX extensions (glXGetClientString): " + ret);
- }
- sb.append(ret).append(" ");
+ final X11GraphicsDevice x11Device = (X11GraphicsDevice) ns.getGraphicsConfiguration().getScreen().getDevice();
+ StringBuilder sb = new StringBuilder();
+ x11Device.lock();
+ try{
+ if (DEBUG) {
+ System.err.println("GLX Version client version "+ GLXUtil.getClientVersionNumber()+
+ ", server: "+ GLXUtil.getGLXServerVersionNumber(x11Device));
}
- {
- final String ret = GLX.glXQueryExtensionsString(ns.getDisplayHandle(), ns.getScreenIndex());
- if (DEBUG) {
- System.err.println("GLX extensions (glXQueryExtensionsString): " + ret);
+ if(((X11GLXDrawableFactory)drawable.getFactoryImpl()).isGLXVersionGreaterEqualOneOne(x11Device)) {
+ {
+ final String ret = GLX.glXGetClientString(x11Device.getHandle(), GLX.GLX_EXTENSIONS);
+ if (DEBUG) {
+ System.err.println("GLX extensions (glXGetClientString): " + ret);
+ }
+ sb.append(ret).append(" ");
}
- sb.append(ret).append(" ");
- }
- {
- final String ret = GLX.glXQueryServerString(ns.getDisplayHandle(), ns.getScreenIndex(), GLX.GLX_EXTENSIONS);
- if (DEBUG) {
- System.err.println("GLX extensions (glXQueryServerString): " + ret);
+ {
+ final String ret = GLX.glXQueryExtensionsString(x11Device.getHandle(), ns.getScreenIndex());
+ if (DEBUG) {
+ System.err.println("GLX extensions (glXQueryExtensionsString): " + ret);
+ }
+ sb.append(ret).append(" ");
+ }
+ {
+ final String ret = GLX.glXQueryServerString(x11Device.getHandle(), ns.getScreenIndex(), GLX.GLX_EXTENSIONS);
+ if (DEBUG) {
+ System.err.println("GLX extensions (glXQueryServerString): " + ret);
+ }
+ sb.append(ret).append(" ");
}
- sb.append(ret).append(" ");
}
+ } finally {
+ x11Device.unlock();
}
return sb;
}
@@ -519,20 +516,36 @@ public abstract class X11GLXContext extends GLContextImpl {
@Override
protected boolean setSwapIntervalImpl(int interval) {
- X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeSurface().getGraphicsConfiguration();
- GLCapabilitiesImmutable glCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
- if(!glCaps.isOnscreen()) { return false; }
+ if( !drawable.getChosenGLCapabilities().isOnscreen() ) { return false; }
- GLXExt glXExt = getGLXExt();
- if(0==hasSwapIntervalSGI) {
+ final GLXExt glXExt = getGLXExt();
+ if(0==hasSwapInterval) {
try {
- hasSwapIntervalSGI = glXExt.isExtensionAvailable("GLX_SGI_swap_control")?1:-1;
- } catch (Throwable t) { hasSwapIntervalSGI=1; }
- }
- if (hasSwapIntervalSGI>0) {
+ /** Same impl. ..
+ if( glXExt.isExtensionAvailable(GLXExtensions.GLX_MESA_swap_control) ) {
+ if(DEBUG) { System.err.println("X11GLXContext.setSwapInterval using: "+GLXExtensions.GLX_MESA_swap_control); }
+ hasSwapInterval = 1;
+ } else */
+ if ( glXExt.isExtensionAvailable(GLXExtensions.GLX_SGI_swap_control) ) {
+ if(DEBUG) { System.err.println("X11GLXContext.setSwapInterval using: "+GLXExtensions.GLX_SGI_swap_control); }
+ hasSwapInterval = 2;
+ } else {
+ hasSwapInterval = -1;
+ }
+ } catch (Throwable t) { hasSwapInterval=-1; }
+ }
+ /* try {
+ switch( hasSwapInterval ) {
+ case 1:
+ return 0 == glXExt.glXSwapIntervalMESA(interval);
+ case 2:
+ return 0 == glXExt.glXSwapIntervalSGI(interval);
+ }
+ } catch (Throwable t) { hasSwapInterval = -1; } */
+ if (2 == hasSwapInterval) {
try {
return 0 == glXExt.glXSwapIntervalSGI(interval);
- } catch (Throwable t) { hasSwapIntervalSGI=-1; }
+ } catch (Throwable t) { hasSwapInterval=-1; }
}
return false;
}
@@ -540,10 +553,10 @@ public abstract class X11GLXContext extends GLContextImpl {
private final int initSwapGroupImpl(GLXExt glXExt) {
if(0==hasSwapGroupNV) {
try {
- hasSwapGroupNV = glXExt.isExtensionAvailable("GLX_NV_swap_group")?1:-1;
+ hasSwapGroupNV = glXExt.isExtensionAvailable(GLXExtensions.GLX_NV_swap_group)?1:-1;
} catch (Throwable t) { hasSwapGroupNV=1; }
if(DEBUG) {
- System.err.println("initSwapGroupImpl: hasSwapGroupNV: "+hasSwapGroupNV);
+ System.err.println("initSwapGroupImpl: "+GLXExtensions.GLX_NV_swap_group+": "+hasSwapGroupNV);
}
}
return hasSwapGroupNV;
@@ -557,9 +570,13 @@ public abstract class X11GLXContext extends GLContextImpl {
if (initSwapGroupImpl(glXExt)>0) {
final NativeSurface ns = drawable.getNativeSurface();
try {
+ final IntBuffer maxGroupsNIO = Buffers.newDirectIntBuffer(maxGroups.length - maxGroups_offset);
+ final IntBuffer maxBarriersNIO = Buffers.newDirectIntBuffer(maxBarriers.length - maxBarriers_offset);
+
if( glXExt.glXQueryMaxSwapGroupsNV(ns.getDisplayHandle(), ns.getScreenIndex(),
- maxGroups, maxGroups_offset,
- maxBarriers, maxBarriers_offset) ) {
+ maxGroupsNIO, maxBarriersNIO) ) {
+ maxGroupsNIO.get(maxGroups, maxGroups_offset, maxGroupsNIO.remaining());
+ maxBarriersNIO.get(maxGroups, maxGroups_offset, maxBarriersNIO.remaining());
res = true;
}
} catch (Throwable t) { hasSwapGroupNV=-1; }
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawable.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawable.java
index e9912ce..8c64277 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawable.java
@@ -69,9 +69,10 @@ public abstract class X11GLXDrawable extends GLDrawableImpl {
}
@Override
- protected final void swapBuffersImpl() {
- // single-buffer is already filtered out @ GLDrawableImpl#swapBuffers()
- GLX.glXSwapBuffers(getNativeSurface().getDisplayHandle(), getHandle());
+ protected final void swapBuffersImpl(boolean doubleBuffered) {
+ if(doubleBuffered) {
+ GLX.glXSwapBuffers(getNativeSurface().getDisplayHandle(), getHandle());
+ }
}
//---------------------------------------------------------------------------
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
index b2e74f9..e38aabe 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
@@ -47,9 +47,8 @@ import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.AbstractGraphicsScreen;
import javax.media.nativewindow.NativeSurface;
-import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.ProxySurface;
-import javax.media.nativewindow.ProxySurface.UpstreamSurfaceHook;
+import javax.media.nativewindow.UpstreamSurfaceHook;
import javax.media.nativewindow.VisualIDHolder;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesChooser;
@@ -58,8 +57,9 @@ import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawable;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
-import javax.media.opengl.GLProfile.ShutdownType;
+import jogamp.nativewindow.WrappedSurface;
+import jogamp.nativewindow.x11.X11DummyUpstreamSurfaceHook;
import jogamp.nativewindow.x11.X11Lib;
import jogamp.nativewindow.x11.X11Util;
import jogamp.opengl.DesktopGLDynamicLookupHelper;
@@ -71,7 +71,6 @@ import jogamp.opengl.GLGraphicsConfigurationUtil;
import jogamp.opengl.SharedResourceRunner;
import com.jogamp.common.util.VersionNumber;
-import com.jogamp.nativewindow.WrappedSurface;
import com.jogamp.nativewindow.x11.X11GraphicsDevice;
import com.jogamp.nativewindow.x11.X11GraphicsScreen;
@@ -124,7 +123,12 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
}
@Override
- protected final void destroy(ShutdownType shutdownType) {
+ protected final boolean isComplete() {
+ return null != x11GLXDynamicLookupHelper;
+ }
+
+ @Override
+ protected final void destroy() {
if(null != sharedResourceRunner) {
sharedResourceRunner.stop();
sharedResourceRunner = null;
@@ -137,14 +141,9 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
/**
* Pulling away the native library may cause havoc ..
*
- if(ShutdownType.COMPLETE == shutdownType && null != x11GLXDynamicLookupHelper) {
- x11GLXDynamicLookupHelper.destroy();
- x11GLXDynamicLookupHelper = null;
- } */
-
- // Don't really close pending Display connections,
- // since this may trigger a JVM exception
- X11Util.shutdown( false, DEBUG );
+ x11GLXDynamicLookupHelper.destroy();
+ */
+ x11GLXDynamicLookupHelper = null;
}
@Override
@@ -230,33 +229,26 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
@Override
public SharedResourceRunner.Resource createSharedResource(String connection) {
- final X11GraphicsDevice sharedDevice =
- new X11GraphicsDevice(X11Util.openDisplay(connection), AbstractGraphicsDevice.DEFAULT_UNIT,
- true); // own non-shared display connection, w/ locking
- // new X11GraphicsDevice(X11Util.openDisplay(connection), AbstractGraphicsDevice.DEFAULT_UNIT,
- // NativeWindowFactory.getNullToolkitLock(), true); // own non-shared display connection, w/o locking
+ final X11GraphicsDevice sharedDevice = new X11GraphicsDevice(X11Util.openDisplay(connection), AbstractGraphicsDevice.DEFAULT_UNIT, true /* owner */);
sharedDevice.lock();
try {
- final X11GraphicsScreen sharedScreen = new X11GraphicsScreen(sharedDevice, 0);
+ final X11GraphicsScreen sharedScreen = new X11GraphicsScreen(sharedDevice, sharedDevice.getDefaultScreen());
if(!GLXUtil.isGLXAvailableOnServer(sharedDevice)) {
throw new GLException("GLX not available on device/server: "+sharedDevice);
}
GLXUtil.initGLXClientDataSingleton(sharedDevice);
final String glXServerVendorName = GLX.glXQueryServerString(sharedDevice.getHandle(), 0, GLX.GLX_VENDOR);
- final VersionNumber glXServerVersion = GLXUtil.getGLXServerVersionNumber(sharedDevice.getHandle());
+ final VersionNumber glXServerVersion = GLXUtil.getGLXServerVersionNumber(sharedDevice);
final boolean glXServerMultisampleAvailable = GLXUtil.isMultisampleAvailable(GLX.glXQueryServerString(sharedDevice.getHandle(), 0, GLX.GLX_EXTENSIONS));
- if(X11Util.ATI_HAS_XCLOSEDISPLAY_BUG && GLXUtil.isVendorATI(glXServerVendorName)) {
- X11Util.setMarkAllDisplaysUnclosable(true);
- X11Util.markDisplayUncloseable(sharedDevice.getHandle());
- }
final GLProfile glp = GLProfile.get(sharedDevice, GLProfile.GL_PROFILE_LIST_MIN_DESKTOP, false);
if (null == glp) {
throw new GLException("Couldn't get default GLProfile for device: "+sharedDevice);
}
-
- final GLDrawableImpl sharedDrawable = createOnscreenDrawableImpl(createDummySurfaceImpl(sharedDevice, false, new GLCapabilities(glp), null, 64, 64));
+
+ final GLCapabilitiesImmutable caps = new GLCapabilities(glp);
+ final GLDrawableImpl sharedDrawable = createOnscreenDrawableImpl(createDummySurfaceImpl(sharedDevice, false, caps, caps, null, 64, 64));
sharedDrawable.setRealized(true);
final GLContextImpl sharedContext = (GLContextImpl) sharedDrawable.createContext(null);
@@ -457,7 +449,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
return sr.getGLXVersion();
}
if( device instanceof X11GraphicsDevice ) {
- return GLXUtil.getGLXServerVersionNumber(device.getHandle());
+ return GLXUtil.getGLXServerVersionNumber((X11GraphicsDevice)device);
}
}
return null;
@@ -470,7 +462,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
return sr.isGLXVersionGreaterEqualOneOne();
}
if( device instanceof X11GraphicsDevice ) {
- final VersionNumber glXServerVersion = GLXUtil.getGLXServerVersionNumber(device.getHandle());
+ final VersionNumber glXServerVersion = GLXUtil.getGLXServerVersionNumber((X11GraphicsDevice)device);
return glXServerVersion.compareTo(versionOneOne) >= 0;
}
}
@@ -484,7 +476,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
return sr.isGLXVersionGreaterEqualOneThree();
}
if( device instanceof X11GraphicsDevice ) {
- final VersionNumber glXServerVersion = GLXUtil.getGLXServerVersionNumber(device.getHandle());
+ final VersionNumber glXServerVersion = GLXUtil.getGLXServerVersionNumber((X11GraphicsDevice)device);
return glXServerVersion.compareTo(versionOneThree) >= 0;
}
}
@@ -506,82 +498,31 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
protected final ProxySurface createMutableSurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice,
GLCapabilitiesImmutable capsChosen,
GLCapabilitiesImmutable capsRequested,
- GLCapabilitiesChooser chooser, int width, int height, UpstreamSurfaceHook lifecycleHook) {
+ GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstreamHook) {
final X11GraphicsDevice device;
- if(createNewDevice) {
- // Null X11 locking, due to private non-shared Display handle
- device = new X11GraphicsDevice(X11Util.openDisplay(deviceReq.getConnection()), deviceReq.getUnitID(), NativeWindowFactory.getNullToolkitLock(), true);
+ if( createNewDevice || !(deviceReq instanceof X11GraphicsDevice) ) {
+ device = new X11GraphicsDevice(X11Util.openDisplay(deviceReq.getConnection()), deviceReq.getUnitID(), true /* owner */);
} else {
- device = (X11GraphicsDevice)deviceReq;
+ device = (X11GraphicsDevice) deviceReq;
}
- final X11GraphicsScreen screen = new X11GraphicsScreen(device, 0);
+ final X11GraphicsScreen screen = new X11GraphicsScreen(device, device.getDefaultScreen());
final X11GLXGraphicsConfiguration config = X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsChosen, capsRequested, chooser, screen, VisualIDHolder.VID_UNDEFINED);
if(null == config) {
throw new GLException("Choosing GraphicsConfiguration failed w/ "+capsChosen+" on "+screen);
}
- return new WrappedSurface( config, 0, width, height, lifecycleHook);
+ return new WrappedSurface(config, 0, upstreamHook, createNewDevice);
}
-
+
@Override
public final ProxySurface createDummySurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice,
- GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height) {
- final GLCapabilitiesImmutable chosenCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(requestedCaps);
- return createMutableSurfaceImpl(deviceReq, createNewDevice, chosenCaps, requestedCaps, chooser, width, height, dummySurfaceLifecycleHook);
+ GLCapabilitiesImmutable chosenCaps, GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height) {
+ chosenCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(chosenCaps);
+ return createMutableSurfaceImpl(deviceReq, createNewDevice, chosenCaps, requestedCaps, chooser, new X11DummyUpstreamSurfaceHook(width, height));
}
- private static final ProxySurface.UpstreamSurfaceHook dummySurfaceLifecycleHook = new ProxySurface.UpstreamSurfaceHook() {
- @Override
- public final void create(ProxySurface s) {
- if( 0 == s.getSurfaceHandle() ) {
- final X11GLXGraphicsConfiguration cfg = (X11GLXGraphicsConfiguration) s.getGraphicsConfiguration();
- final X11GraphicsScreen screen = (X11GraphicsScreen) cfg.getScreen();
- final X11GraphicsDevice device = (X11GraphicsDevice) screen.getDevice();
- if(0 == device.getHandle()) {
- device.open();
- s.setImplBitfield(ProxySurface.OWN_DEVICE);
- }
- final long windowHandle = X11Lib.CreateDummyWindow(device.getHandle(), screen.getIndex(), cfg.getXVisualID(), s.getWidth(), s.getHeight());
- if(0 == windowHandle) {
- throw new GLException("Creating dummy window failed w/ "+cfg+", "+s.getWidth()+"x"+s.getHeight());
- }
- s.setSurfaceHandle(windowHandle);
- if(DEBUG) {
- System.err.println("X11GLXDrawableFactory.dummySurfaceLifecycleHook.create: "+s);
- }
- }
- }
- @Override
- public final void destroy(ProxySurface s) {
- if(0 != s.getSurfaceHandle()) {
- final X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration) s.getGraphicsConfiguration();
- final X11GraphicsDevice device = (X11GraphicsDevice) config.getScreen().getDevice();
- X11Lib.DestroyDummyWindow(device.getHandle(), s.getSurfaceHandle());
- s.setSurfaceHandle(0);
- if( 0 != ( ProxySurface.OWN_DEVICE & s.getImplBitfield() ) ) {
- device.close();
- }
- if(DEBUG) {
- System.err.println("X11GLXDrawableFactory.dummySurfaceLifecycleHook.destroy: "+s);
- }
- }
- }
- @Override
- public final int getWidth(ProxySurface s) {
- return s.initialWidth;
- }
- @Override
- public final int getHeight(ProxySurface s) {
- return s.initialHeight;
- }
- @Override
- public String toString() {
- return "X11SurfaceLifecycleHook[]";
- }
- };
-
@Override
protected final ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice deviceReq, int screenIdx, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstream) {
- final X11GraphicsDevice device = new X11GraphicsDevice(X11Util.openDisplay(deviceReq.getConnection()), deviceReq.getUnitID(), NativeWindowFactory.getNullToolkitLock(), true);
+ final X11GraphicsDevice device = new X11GraphicsDevice(X11Util.openDisplay(deviceReq.getConnection()), deviceReq.getUnitID(), true /* owner */);
final X11GraphicsScreen screen = new X11GraphicsScreen(device, screenIdx);
final int xvisualID = X11Lib.GetVisualIDFromWindow(device.getHandle(), windowHandle);
if(VisualIDHolder.VID_UNDEFINED == xvisualID) {
@@ -594,7 +535,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
if(DEBUG) {
System.err.println("X11GLXDrawableFactory.createProxySurfaceImpl 0x"+Long.toHexString(windowHandle)+": "+cfg);
}
- return new WrappedSurface(cfg, windowHandle, 0, 0, upstream);
+ return new WrappedSurface(cfg, windowHandle, upstream, true);
}
@Override
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java
index b458fff..12ce223 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java
@@ -33,10 +33,8 @@
package jogamp.opengl.x11.glx;
-import java.util.ArrayList;
-import java.util.List;
+import java.nio.IntBuffer;
-import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.CapabilitiesImmutable;
import javax.media.nativewindow.GraphicsConfigurationFactory;
import javax.media.nativewindow.VisualIDHolder;
@@ -45,7 +43,6 @@ import javax.media.opengl.GL;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesChooser;
import javax.media.opengl.GLCapabilitiesImmutable;
-import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
@@ -56,8 +53,10 @@ import jogamp.nativewindow.x11.XRenderPictFormat;
import jogamp.nativewindow.x11.XVisualInfo;
import jogamp.opengl.GLGraphicsConfigurationUtil;
+import com.jogamp.common.nio.Buffers;
import com.jogamp.common.nio.PointerBuffer;
import com.jogamp.nativewindow.x11.X11GraphicsConfiguration;
+import com.jogamp.nativewindow.x11.X11GraphicsDevice;
import com.jogamp.nativewindow.x11.X11GraphicsScreen;
public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implements Cloneable {
@@ -70,28 +69,6 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
this.chooser=chooser;
}
- static X11GLXGraphicsConfiguration create(GLProfile glp, X11GraphicsScreen x11Screen, int fbcfgID) {
- final AbstractGraphicsDevice device = x11Screen.getDevice();
- final long display = device.getHandle();
- if(0==display) {
- throw new GLException("Display null of "+x11Screen);
- }
- final int screen = x11Screen.getIndex();
- final long fbcfg = glXFBConfigID2FBConfig(display, screen, fbcfgID);
- if(0==fbcfg) {
- throw new GLException("FBConfig null of "+toHexString(fbcfgID));
- }
- if(null==glp) {
- glp = GLProfile.getDefault(x11Screen.getDevice());
- }
- final X11GLXDrawableFactory factory = (X11GLXDrawableFactory) GLDrawableFactory.getDesktopFactory();
- final X11GLCapabilities caps = GLXFBConfig2GLCapabilities(glp, device, fbcfg, true, true, true, factory.isGLXMultisampleAvailable(device));
- if(null==caps) {
- throw new GLException("GLCapabilities null of "+toHexString(fbcfg));
- }
- return new X11GLXGraphicsConfiguration(x11Screen, caps, caps, new DefaultGLCapabilitiesChooser());
- }
-
public Object clone() {
return super.clone();
}
@@ -126,11 +103,31 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
}
}
- static int[] GLCapabilities2AttribList(GLCapabilitiesImmutable caps,
- boolean forFBAttr,
- boolean isMultisampleAvailable,
- long display,
- int screen)
+ static X11GLXGraphicsConfiguration create(GLProfile glp, X11GraphicsScreen x11Screen, int fbcfgID) {
+ final X11GraphicsDevice device = (X11GraphicsDevice) x11Screen.getDevice();
+ final long display = device.getHandle();
+ if(0==display) {
+ throw new GLException("Display null of "+x11Screen);
+ }
+ final int screen = x11Screen.getIndex();
+ final long fbcfg = glXFBConfigID2FBConfig(display, screen, fbcfgID);
+ if(0==fbcfg) {
+ throw new GLException("FBConfig null of "+toHexString(fbcfgID));
+ }
+ if(null==glp) {
+ glp = GLProfile.getDefault(x11Screen.getDevice());
+ }
+ final X11GLXDrawableFactory factory = (X11GLXDrawableFactory) GLDrawableFactory.getDesktopFactory();
+ final X11GLCapabilities caps = GLXFBConfig2GLCapabilities(device, glp, fbcfg, GLGraphicsConfigurationUtil.ALL_BITS, factory.isGLXMultisampleAvailable(device));
+ if(null==caps) {
+ throw new GLException("GLCapabilities null of "+toHexString(fbcfg));
+ }
+ return new X11GLXGraphicsConfiguration(x11Screen, caps, caps, new DefaultGLCapabilitiesChooser());
+ }
+
+ static IntBuffer GLCapabilities2AttribList(GLCapabilitiesImmutable caps,
+ boolean forFBAttr, boolean isMultisampleAvailable,
+ long display, int screen)
{
int colorDepth = (caps.getRedBits() +
caps.getGreenBits() +
@@ -138,84 +135,95 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
if (colorDepth < 15) {
throw new GLException("Bit depths < 15 (i.e., non-true-color) not supported");
}
- int[] res = new int[MAX_ATTRIBS];
+ final IntBuffer res = Buffers.newDirectIntBuffer(MAX_ATTRIBS);
int idx = 0;
if (forFBAttr) {
- res[idx++] = GLX.GLX_DRAWABLE_TYPE;
- res[idx++] = caps.isOnscreen() ? ( GLX.GLX_WINDOW_BIT ) : ( caps.isPBuffer() ? GLX.GLX_PBUFFER_BIT : GLX.GLX_PIXMAP_BIT ) ;
- }
-
- if (forFBAttr) {
- res[idx++] = GLX.GLX_RENDER_TYPE;
- res[idx++] = GLX.GLX_RGBA_BIT;
+ res.put(idx++, GLX.GLX_DRAWABLE_TYPE);
+
+ final int surfaceType;
+ if( caps.isOnscreen() ) {
+ surfaceType = GLX.GLX_WINDOW_BIT;
+ } else if( caps.isFBO() ) {
+ surfaceType = GLX.GLX_WINDOW_BIT; // native replacement!
+ } else if( caps.isPBuffer() ) {
+ surfaceType = GLX.GLX_PBUFFER_BIT;
+ } else if( caps.isBitmap() ) {
+ surfaceType = GLX.GLX_PIXMAP_BIT;
+ } else {
+ throw new GLException("no surface type set in caps: "+caps);
+ }
+ res.put(idx++, surfaceType);
+
+ res.put(idx++, GLX.GLX_RENDER_TYPE);
+ res.put(idx++, GLX.GLX_RGBA_BIT);
} else {
- res[idx++] = GLX.GLX_RGBA;
+ res.put(idx++, GLX.GLX_RGBA);
}
// FIXME: Still a bug is Mesa: PBUFFER && GLX_STEREO==GL_FALSE ?
if (forFBAttr) {
- res[idx++] = GLX.GLX_DOUBLEBUFFER;
- res[idx++] = caps.getDoubleBuffered()?GL.GL_TRUE:GL.GL_FALSE;
- res[idx++] = GLX.GLX_STEREO;
- res[idx++] = caps.getStereo()?GL.GL_TRUE:GL.GL_FALSE;
- res[idx++] = GLX.GLX_TRANSPARENT_TYPE;
- res[idx++] = GLX.GLX_NONE;
+ res.put(idx++, GLX.GLX_DOUBLEBUFFER);
+ res.put(idx++, caps.getDoubleBuffered()?GL.GL_TRUE:GL.GL_FALSE);
+ res.put(idx++, GLX.GLX_STEREO);
+ res.put(idx++, caps.getStereo()?GL.GL_TRUE:GL.GL_FALSE);
+ res.put(idx++, GLX.GLX_TRANSPARENT_TYPE);
+ res.put(idx++, GLX.GLX_NONE);
/**
- res[idx++] = caps.isBackgroundOpaque()?GLX.GLX_NONE:GLX.GLX_TRANSPARENT_RGB;
+ res.put(idx++, caps.isBackgroundOpaque()?GLX.GLX_NONE:GLX.GLX_TRANSPARENT_RGB;
if(!caps.isBackgroundOpaque()) {
- res[idx++] = GLX.GLX_TRANSPARENT_RED_VALUE;
- res[idx++] = caps.getTransparentRedValue()>=0?caps.getTransparentRedValue():(int)GLX.GLX_DONT_CARE;
- res[idx++] = GLX.GLX_TRANSPARENT_GREEN_VALUE;
- res[idx++] = caps.getTransparentGreenValue()>=0?caps.getTransparentGreenValue():(int)GLX.GLX_DONT_CARE;
- res[idx++] = GLX.GLX_TRANSPARENT_BLUE_VALUE;
- res[idx++] = caps.getTransparentBlueValue()>=0?caps.getTransparentBlueValue():(int)GLX.GLX_DONT_CARE;
- res[idx++] = GLX.GLX_TRANSPARENT_ALPHA_VALUE;
- res[idx++] = caps.getTransparentAlphaValue()>=0?caps.getTransparentAlphaValue():(int)GLX.GLX_DONT_CARE;
+ res.put(idx++, GLX.GLX_TRANSPARENT_RED_VALUE);
+ res.put(idx++, caps.getTransparentRedValue()>=0?caps.getTransparentRedValue():(int)GLX.GLX_DONT_CARE);
+ res.put(idx++, GLX.GLX_TRANSPARENT_GREEN_VALUE);
+ res.put(idx++, caps.getTransparentGreenValue()>=0?caps.getTransparentGreenValue():(int)GLX.GLX_DONT_CARE);
+ res.put(idx++, GLX.GLX_TRANSPARENT_BLUE_VALUE);
+ res.put(idx++, caps.getTransparentBlueValue()>=0?caps.getTransparentBlueValue():(int)GLX.GLX_DONT_CARE);
+ res.put(idx++, GLX.GLX_TRANSPARENT_ALPHA_VALUE);
+ res.put(idx++, caps.getTransparentAlphaValue()>=0?caps.getTransparentAlphaValue():(int)GLX.GLX_DONT_CARE);
} */
} else {
if (caps.getDoubleBuffered()) {
- res[idx++] = GLX.GLX_DOUBLEBUFFER;
+ res.put(idx++, GLX.GLX_DOUBLEBUFFER);
}
if (caps.getStereo()) {
- res[idx++] = GLX.GLX_STEREO;
+ res.put(idx++, GLX.GLX_STEREO);
}
}
- res[idx++] = GLX.GLX_RED_SIZE;
- res[idx++] = caps.getRedBits();
- res[idx++] = GLX.GLX_GREEN_SIZE;
- res[idx++] = caps.getGreenBits();
- res[idx++] = GLX.GLX_BLUE_SIZE;
- res[idx++] = caps.getBlueBits();
+ res.put(idx++, GLX.GLX_RED_SIZE);
+ res.put(idx++, caps.getRedBits());
+ res.put(idx++, GLX.GLX_GREEN_SIZE);
+ res.put(idx++, caps.getGreenBits());
+ res.put(idx++, GLX.GLX_BLUE_SIZE);
+ res.put(idx++, caps.getBlueBits());
if(caps.getAlphaBits()>0) {
- res[idx++] = GLX.GLX_ALPHA_SIZE;
- res[idx++] = caps.getAlphaBits();
+ res.put(idx++, GLX.GLX_ALPHA_SIZE);
+ res.put(idx++, caps.getAlphaBits());
}
if (caps.getStencilBits() > 0) {
- res[idx++] = GLX.GLX_STENCIL_SIZE;
- res[idx++] = caps.getStencilBits();
+ res.put(idx++, GLX.GLX_STENCIL_SIZE);
+ res.put(idx++, caps.getStencilBits());
}
- res[idx++] = GLX.GLX_DEPTH_SIZE;
- res[idx++] = caps.getDepthBits();
+ res.put(idx++, GLX.GLX_DEPTH_SIZE);
+ res.put(idx++, caps.getDepthBits());
if (caps.getAccumRedBits() > 0 ||
caps.getAccumGreenBits() > 0 ||
caps.getAccumBlueBits() > 0 ||
caps.getAccumAlphaBits() > 0) {
- res[idx++] = GLX.GLX_ACCUM_RED_SIZE;
- res[idx++] = caps.getAccumRedBits();
- res[idx++] = GLX.GLX_ACCUM_GREEN_SIZE;
- res[idx++] = caps.getAccumGreenBits();
- res[idx++] = GLX.GLX_ACCUM_BLUE_SIZE;
- res[idx++] = caps.getAccumBlueBits();
- res[idx++] = GLX.GLX_ACCUM_ALPHA_SIZE;
- res[idx++] = caps.getAccumAlphaBits();
+ res.put(idx++, GLX.GLX_ACCUM_RED_SIZE);
+ res.put(idx++, caps.getAccumRedBits());
+ res.put(idx++, GLX.GLX_ACCUM_GREEN_SIZE);
+ res.put(idx++, caps.getAccumGreenBits());
+ res.put(idx++, GLX.GLX_ACCUM_BLUE_SIZE);
+ res.put(idx++, caps.getAccumBlueBits());
+ res.put(idx++, GLX.GLX_ACCUM_ALPHA_SIZE);
+ res.put(idx++, caps.getAccumAlphaBits());
}
if (isMultisampleAvailable && caps.getSampleBuffers()) {
- res[idx++] = GLX.GLX_SAMPLE_BUFFERS;
- res[idx++] = GL.GL_TRUE;
- res[idx++] = GLX.GLX_SAMPLES;
- res[idx++] = caps.getNumSamples();
+ res.put(idx++, GLX.GLX_SAMPLE_BUFFERS);
+ res.put(idx++, GL.GL_TRUE);
+ res.put(idx++, GLX.GLX_SAMPLES);
+ res.put(idx++, caps.getNumSamples());
}
if (caps.isPBuffer()) {
if (caps.getPbufferFloatingPointBuffers()) {
@@ -224,11 +232,11 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
glXExtensions.indexOf("GLX_NV_float_buffer") < 0) {
throw new GLException("Floating-point pbuffers on X11 currently require NVidia hardware: "+glXExtensions);
}
- res[idx++] = GLXExt.GLX_FLOAT_COMPONENTS_NV;
- res[idx++] = GL.GL_TRUE;
+ res.put(idx++, GLXExt.GLX_FLOAT_COMPONENTS_NV);
+ res.put(idx++, GL.GL_TRUE);
}
}
- res[idx++] = 0;
+ res.put(idx++, 0);
return res;
}
@@ -240,21 +248,22 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
}
static boolean GLXFBConfigValid(long display, long fbcfg) {
- int[] tmp = new int[1];
- if(GLX.GLX_BAD_ATTRIBUTE == GLX.glXGetFBConfigAttrib(display, fbcfg, GLX.GLX_RENDER_TYPE, tmp, 0)) {
+ final IntBuffer tmp = Buffers.newDirectIntBuffer(1);
+ if(GLX.GLX_BAD_ATTRIBUTE == GLX.glXGetFBConfigAttrib(display, fbcfg, GLX.GLX_RENDER_TYPE, tmp)) {
return false;
}
return true;
}
- static int FBCfgDrawableTypeBits(final AbstractGraphicsDevice device, GLProfile glp, final long fbcfg) {
+ static int FBCfgDrawableTypeBits(final X11GraphicsDevice device, final long fbcfg) {
int val = 0;
- int[] tmp = new int[1];
- int fbtype = glXGetFBConfig(device.getHandle(), fbcfg, GLX.GLX_DRAWABLE_TYPE, tmp, 0);
+ final IntBuffer tmp = Buffers.newDirectIntBuffer(1);
+ int fbtype = glXGetFBConfig(device.getHandle(), fbcfg, GLX.GLX_DRAWABLE_TYPE, tmp);
if ( 0 != ( fbtype & GLX.GLX_WINDOW_BIT ) ) {
- val |= GLGraphicsConfigurationUtil.WINDOW_BIT;
+ val |= GLGraphicsConfigurationUtil.WINDOW_BIT |
+ GLGraphicsConfigurationUtil.FBO_BIT;
}
if ( 0 != ( fbtype & GLX.GLX_PIXMAP_BIT ) ) {
val |= GLGraphicsConfigurationUtil.BITMAP_BIT;
@@ -262,25 +271,9 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
if ( 0 != ( fbtype & GLX.GLX_PBUFFER_BIT ) ) {
val |= GLGraphicsConfigurationUtil.PBUFFER_BIT;
}
- if ( GLContext.isFBOAvailable(device, glp) ) {
- val |= GLGraphicsConfigurationUtil.FBO_BIT;
- }
return val;
}
- static X11GLCapabilities GLXFBConfig2GLCapabilities(GLProfile glp, AbstractGraphicsDevice device, long fbcfg,
- boolean relaxed, boolean onscreen, boolean usePBuffer,
- boolean isMultisampleAvailable) {
- ArrayList<GLCapabilitiesImmutable> bucket = new ArrayList<GLCapabilitiesImmutable>();
- final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer, false);
- if( GLXFBConfig2GLCapabilities(bucket, glp, device, fbcfg, winattrmask, isMultisampleAvailable) ) {
- return (X11GLCapabilities) bucket.get(0);
- } else if ( relaxed && GLXFBConfig2GLCapabilities(bucket, glp, device, fbcfg, GLGraphicsConfigurationUtil.ALL_BITS, isMultisampleAvailable) ) {
- return (X11GLCapabilities) bucket.get(0);
- }
- return null;
- }
-
static XRenderDirectFormat XVisual2XRenderMask(long dpy, long visual) {
XRenderPictFormat renderPictFmt = X11Lib.XRenderFindVisualFormat(dpy, visual);
if(null == renderPictFmt) {
@@ -289,10 +282,9 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
return renderPictFmt.getDirect();
}
- static boolean GLXFBConfig2GLCapabilities(List<GLCapabilitiesImmutable> capsBucket,
- GLProfile glp, AbstractGraphicsDevice device, long fbcfg,
- int winattrmask, boolean isMultisampleAvailable) {
- final int allDrawableTypeBits = FBCfgDrawableTypeBits(device, glp, fbcfg);
+ static X11GLCapabilities GLXFBConfig2GLCapabilities(X11GraphicsDevice device, GLProfile glp, long fbcfg,
+ int winattrmask, boolean isMultisampleAvailable) {
+ final int allDrawableTypeBits = FBCfgDrawableTypeBits(device, fbcfg);
int drawableTypeBits = winattrmask & allDrawableTypeBits;
final long display = device.getHandle();
@@ -303,25 +295,25 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
System.err.println("X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities: Null XVisualInfo for FBConfigID 0x" + Integer.toHexString(fbcfgid));
}
// onscreen must have an XVisualInfo
- drawableTypeBits = drawableTypeBits & ~GLGraphicsConfigurationUtil.WINDOW_BIT;
+ drawableTypeBits &= ~(GLGraphicsConfigurationUtil.WINDOW_BIT | GLGraphicsConfigurationUtil.FBO_BIT);
}
if( 0 == drawableTypeBits ) {
- return false;
+ return null;
}
- int[] tmp = new int[1];
- if(GLX.GLX_BAD_ATTRIBUTE == GLX.glXGetFBConfigAttrib(display, fbcfg, GLX.GLX_RENDER_TYPE, tmp, 0)) {
- return false;
+ final IntBuffer tmp = Buffers.newDirectIntBuffer(1);
+ if(GLX.GLX_BAD_ATTRIBUTE == GLX.glXGetFBConfigAttrib(display, fbcfg, GLX.GLX_RENDER_TYPE, tmp)) {
+ return null;
}
- if( 0 == ( GLX.GLX_RGBA_BIT & tmp[0] ) ) {
- return false; // no RGBA -> color index not supported
+ if( 0 == ( GLX.GLX_RGBA_BIT & tmp.get(0) ) ) {
+ return null; // no RGBA -> color index not supported
}
- GLCapabilities res = new X11GLCapabilities(visualInfo, fbcfg, fbcfgid, glp);
+ final X11GLCapabilities res = new X11GLCapabilities(visualInfo, fbcfg, fbcfgid, glp);
if (isMultisampleAvailable) {
- res.setSampleBuffers(glXGetFBConfig(display, fbcfg, GLX.GLX_SAMPLE_BUFFERS, tmp, 0) != 0);
- res.setNumSamples (glXGetFBConfig(display, fbcfg, GLX.GLX_SAMPLES, tmp, 0));
+ res.setSampleBuffers(glXGetFBConfig(display, fbcfg, GLX.GLX_SAMPLE_BUFFERS, tmp) != 0);
+ res.setNumSamples (glXGetFBConfig(display, fbcfg, GLX.GLX_SAMPLES, tmp));
}
final XRenderDirectFormat xrmask = ( null != visualInfo ) ?
XVisual2XRenderMask( display, visualInfo.getVisual() ) :
@@ -335,25 +327,25 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
res.setTransparentAlphaValue(alphaMask);
}
// ALPHA shall be set at last - due to it's auto setting by the above (!opaque / samples)
- res.setDoubleBuffered(glXGetFBConfig(display, fbcfg, GLX.GLX_DOUBLEBUFFER, tmp, 0) != 0);
- res.setStereo (glXGetFBConfig(display, fbcfg, GLX.GLX_STEREO, tmp, 0) != 0);
- res.setHardwareAccelerated(glXGetFBConfig(display, fbcfg, GLX.GLX_CONFIG_CAVEAT, tmp, 0) != GLX.GLX_SLOW_CONFIG);
- res.setRedBits (glXGetFBConfig(display, fbcfg, GLX.GLX_RED_SIZE, tmp, 0));
- res.setGreenBits (glXGetFBConfig(display, fbcfg, GLX.GLX_GREEN_SIZE, tmp, 0));
- res.setBlueBits (glXGetFBConfig(display, fbcfg, GLX.GLX_BLUE_SIZE, tmp, 0));
- res.setAlphaBits (glXGetFBConfig(display, fbcfg, GLX.GLX_ALPHA_SIZE, tmp, 0));
- res.setAccumRedBits (glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_RED_SIZE, tmp, 0));
- res.setAccumGreenBits(glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_GREEN_SIZE, tmp, 0));
- res.setAccumBlueBits (glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_BLUE_SIZE, tmp, 0));
- res.setAccumAlphaBits(glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_ALPHA_SIZE, tmp, 0));
- res.setDepthBits (glXGetFBConfig(display, fbcfg, GLX.GLX_DEPTH_SIZE, tmp, 0));
- res.setStencilBits (glXGetFBConfig(display, fbcfg, GLX.GLX_STENCIL_SIZE, tmp, 0));
+ res.setDoubleBuffered(glXGetFBConfig(display, fbcfg, GLX.GLX_DOUBLEBUFFER, tmp) != 0);
+ res.setStereo (glXGetFBConfig(display, fbcfg, GLX.GLX_STEREO, tmp) != 0);
+ res.setHardwareAccelerated(glXGetFBConfig(display, fbcfg, GLX.GLX_CONFIG_CAVEAT, tmp) != GLX.GLX_SLOW_CONFIG);
+ res.setRedBits (glXGetFBConfig(display, fbcfg, GLX.GLX_RED_SIZE, tmp));
+ res.setGreenBits (glXGetFBConfig(display, fbcfg, GLX.GLX_GREEN_SIZE, tmp));
+ res.setBlueBits (glXGetFBConfig(display, fbcfg, GLX.GLX_BLUE_SIZE, tmp));
+ res.setAlphaBits (glXGetFBConfig(display, fbcfg, GLX.GLX_ALPHA_SIZE, tmp));
+ res.setAccumRedBits (glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_RED_SIZE, tmp));
+ res.setAccumGreenBits(glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_GREEN_SIZE, tmp));
+ res.setAccumBlueBits (glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_BLUE_SIZE, tmp));
+ res.setAccumAlphaBits(glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_ALPHA_SIZE, tmp));
+ res.setDepthBits (glXGetFBConfig(display, fbcfg, GLX.GLX_DEPTH_SIZE, tmp));
+ res.setStencilBits (glXGetFBConfig(display, fbcfg, GLX.GLX_STENCIL_SIZE, tmp));
try {
- res.setPbufferFloatingPointBuffers(glXGetFBConfig(display, fbcfg, GLXExt.GLX_FLOAT_COMPONENTS_NV, tmp, 0) != GL.GL_FALSE);
+ res.setPbufferFloatingPointBuffers(glXGetFBConfig(display, fbcfg, GLXExt.GLX_FLOAT_COMPONENTS_NV, tmp) != GL.GL_FALSE);
} catch (Exception e) {}
- return GLGraphicsConfigurationUtil.addGLCapabilitiesPermutations(capsBucket, res, drawableTypeBits );
+ return (X11GLCapabilities) GLGraphicsConfigurationUtil.fixWinAttribBitsAndHwAccel(device, drawableTypeBits, res);
}
private static String glXGetFBConfigErrorCode(int err) {
@@ -364,26 +356,27 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
}
}
- static int glXGetFBConfig(long display, long cfg, int attrib, int[] tmp, int tmp_offset) {
+ static int glXGetFBConfig(long display, long cfg, int attrib, IntBuffer tmp) {
if (display == 0) {
throw new GLException("No display connection");
}
- int res = GLX.glXGetFBConfigAttrib(display, cfg, attrib, tmp, tmp_offset);
+ int res = GLX.glXGetFBConfigAttrib(display, cfg, attrib, tmp);
if (res != 0) {
throw new GLException("glXGetFBConfig("+toHexString(attrib)+") failed: error code " + glXGetFBConfigErrorCode(res));
}
- return tmp[tmp_offset];
+ return tmp.get(tmp.position());
}
static int glXFBConfig2FBConfigID(long display, long cfg) {
- int[] tmpID = new int[1];
- return glXGetFBConfig(display, cfg, GLX.GLX_FBCONFIG_ID, tmpID, 0);
+ final IntBuffer tmpID = Buffers.newDirectIntBuffer(1);
+ return glXGetFBConfig(display, cfg, GLX.GLX_FBCONFIG_ID, tmpID);
}
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.glXChooseFBConfig(display, screen, attribs, 0, count, 0);
+ final IntBuffer attribs = Buffers.newDirectIntBuffer(new int[] { GLX.GLX_FBCONFIG_ID, id, 0 });
+ final IntBuffer count = Buffers.newDirectIntBuffer(1);
+ count.put(0, -1);
+ PointerBuffer fbcfgsL = GLX.glXChooseFBConfig(display, screen, attribs, count);
if (fbcfgsL == null || fbcfgsL.limit()<1) {
return 0;
}
@@ -408,43 +401,46 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
return res;
}
- static boolean XVisualInfo2GLCapabilities(List<GLCapabilitiesImmutable> capsBucket,
- GLProfile glp, long display, XVisualInfo info,
- final int winattrmask, boolean isMultisampleEnabled) {
- final int allDrawableTypeBits = GLGraphicsConfigurationUtil.WINDOW_BIT | GLGraphicsConfigurationUtil.BITMAP_BIT ;
+ static X11GLCapabilities XVisualInfo2GLCapabilities(final X11GraphicsDevice device, GLProfile glp, XVisualInfo info,
+ final int winattrmask, boolean isMultisampleEnabled) {
+ final int allDrawableTypeBits = GLGraphicsConfigurationUtil.WINDOW_BIT |
+ GLGraphicsConfigurationUtil.BITMAP_BIT |
+ GLGraphicsConfigurationUtil.FBO_BIT ;
+
final int drawableTypeBits = winattrmask & allDrawableTypeBits;
if( 0 == drawableTypeBits ) {
- return false;
+ return null;
}
- int[] tmp = new int[1];
- int val = glXGetConfig(display, info, GLX.GLX_USE_GL, tmp, 0);
+ final long display = device.getHandle();
+ final IntBuffer tmp = Buffers.newDirectIntBuffer(1);
+ int val = glXGetConfig(display, info, GLX.GLX_USE_GL, tmp);
if (val == 0) {
if(DEBUG) {
System.err.println("Visual ("+toHexString(info.getVisualid())+") does not support OpenGL");
}
- return false;
+ return null;
}
- val = glXGetConfig(display, info, GLX.GLX_RGBA, tmp, 0);
+ val = glXGetConfig(display, info, GLX.GLX_RGBA, tmp);
if (val == 0) {
if(DEBUG) {
System.err.println("Visual ("+toHexString(info.getVisualid())+") does not support RGBA");
}
- return false;
+ return null;
}
GLCapabilities res = new X11GLCapabilities(info, glp);
- res.setDoubleBuffered(glXGetConfig(display, info, GLX.GLX_DOUBLEBUFFER, tmp, 0) != 0);
- res.setStereo (glXGetConfig(display, info, GLX.GLX_STEREO, tmp, 0) != 0);
+ res.setDoubleBuffered(glXGetConfig(display, info, GLX.GLX_DOUBLEBUFFER, tmp) != 0);
+ res.setStereo (glXGetConfig(display, info, GLX.GLX_STEREO, tmp) != 0);
// Note: use of hardware acceleration is determined by
// glXCreateContext, not by the XVisualInfo. Optimistically claim
// that all GLCapabilities have the capability to be hardware
// accelerated.
if (isMultisampleEnabled) {
- res.setSampleBuffers(glXGetConfig(display, info, GLX.GLX_SAMPLE_BUFFERS, tmp, 0) != 0);
- res.setNumSamples (glXGetConfig(display, info, GLX.GLX_SAMPLES, tmp, 0));
+ res.setSampleBuffers(glXGetConfig(display, info, GLX.GLX_SAMPLE_BUFFERS, tmp) != 0);
+ res.setNumSamples (glXGetConfig(display, info, GLX.GLX_SAMPLES, tmp));
}
final XRenderDirectFormat xrmask = ( null != info ) ?
XVisual2XRenderMask( display, info.getVisual() ) :
@@ -459,18 +455,18 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
}
// ALPHA shall be set at last - due to it's auto setting by the above (!opaque / samples)
res.setHardwareAccelerated(true);
- res.setDepthBits (glXGetConfig(display, info, GLX.GLX_DEPTH_SIZE, tmp, 0));
- res.setStencilBits (glXGetConfig(display, info, GLX.GLX_STENCIL_SIZE, tmp, 0));
- res.setRedBits (glXGetConfig(display, info, GLX.GLX_RED_SIZE, tmp, 0));
- res.setGreenBits (glXGetConfig(display, info, GLX.GLX_GREEN_SIZE, tmp, 0));
- res.setBlueBits (glXGetConfig(display, info, GLX.GLX_BLUE_SIZE, tmp, 0));
- res.setAlphaBits (glXGetConfig(display, info, GLX.GLX_ALPHA_SIZE, tmp, 0));
- res.setAccumRedBits (glXGetConfig(display, info, GLX.GLX_ACCUM_RED_SIZE, tmp, 0));
- res.setAccumGreenBits(glXGetConfig(display, info, GLX.GLX_ACCUM_GREEN_SIZE, tmp, 0));
- res.setAccumBlueBits (glXGetConfig(display, info, GLX.GLX_ACCUM_BLUE_SIZE, tmp, 0));
- res.setAccumAlphaBits(glXGetConfig(display, info, GLX.GLX_ACCUM_ALPHA_SIZE, tmp, 0));
-
- return GLGraphicsConfigurationUtil.addGLCapabilitiesPermutations(capsBucket, res, drawableTypeBits);
+ res.setDepthBits (glXGetConfig(display, info, GLX.GLX_DEPTH_SIZE, tmp));
+ res.setStencilBits (glXGetConfig(display, info, GLX.GLX_STENCIL_SIZE, tmp));
+ res.setRedBits (glXGetConfig(display, info, GLX.GLX_RED_SIZE, tmp));
+ res.setGreenBits (glXGetConfig(display, info, GLX.GLX_GREEN_SIZE, tmp));
+ res.setBlueBits (glXGetConfig(display, info, GLX.GLX_BLUE_SIZE, tmp));
+ res.setAlphaBits (glXGetConfig(display, info, GLX.GLX_ALPHA_SIZE, tmp));
+ res.setAccumRedBits (glXGetConfig(display, info, GLX.GLX_ACCUM_RED_SIZE, tmp));
+ res.setAccumGreenBits(glXGetConfig(display, info, GLX.GLX_ACCUM_GREEN_SIZE, tmp));
+ res.setAccumBlueBits (glXGetConfig(display, info, GLX.GLX_ACCUM_BLUE_SIZE, tmp));
+ res.setAccumAlphaBits(glXGetConfig(display, info, GLX.GLX_ACCUM_ALPHA_SIZE, tmp));
+
+ return (X11GLCapabilities) GLGraphicsConfigurationUtil.fixWinAttribBitsAndHwAccel(device, drawableTypeBits, res);
}
private static String glXGetConfigErrorCode(int err) {
@@ -483,15 +479,15 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
}
}
- static int glXGetConfig(long display, XVisualInfo info, int attrib, int[] tmp, int tmp_offset) {
+ static int glXGetConfig(long display, XVisualInfo info, int attrib, IntBuffer tmp) {
if (display == 0) {
throw new GLException("No display connection");
}
- int res = GLX.glXGetConfig(display, info, attrib, tmp, tmp_offset);
+ int res = GLX.glXGetConfig(display, info, attrib, tmp);
if (res != 0) {
throw new GLException("glXGetConfig("+toHexString(attrib)+") failed: error code " + glXGetConfigErrorCode(res));
}
- return tmp[tmp_offset];
+ return tmp.get(tmp.position());
}
public String toString() {
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java
index 234b06b..e62dcad 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java
@@ -45,11 +45,11 @@ import javax.media.opengl.DefaultGLCapabilitiesChooser;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesChooser;
import javax.media.opengl.GLCapabilitiesImmutable;
-import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
+import com.jogamp.common.nio.Buffers;
import com.jogamp.common.nio.PointerBuffer;
import com.jogamp.nativewindow.x11.X11GraphicsDevice;
import com.jogamp.nativewindow.x11.X11GraphicsScreen;
@@ -59,6 +59,7 @@ import jogamp.nativewindow.x11.XVisualInfo;
import jogamp.opengl.GLGraphicsConfigurationFactory;
import jogamp.opengl.GLGraphicsConfigurationUtil;
+import java.nio.IntBuffer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -128,18 +129,22 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
throw new GLException("Shared resource for device n/a: "+device);
}
final X11GraphicsScreen sharedScreen = (X11GraphicsScreen) sharedResource.getScreen();
- final boolean isMultisampleAvailable = factory.isGLXMultisampleAvailable(sharedScreen.getDevice());
- final X11GLXDrawable sharedDrawable = (X11GLXDrawable) sharedResource.getDrawable();
- final GLCapabilitiesImmutable capsChosen = sharedDrawable.getChosenGLCapabilities();
- final GLProfile glp = capsChosen.getGLProfile();
+ final X11GraphicsDevice sharedDevice = (X11GraphicsDevice) sharedScreen.getDevice();
+ final boolean isMultisampleAvailable = sharedResource.isGLXMultisampleAvailable();
+ final GLProfile glp = GLProfile.getDefault(device);
List<GLCapabilitiesImmutable> availableCaps = null;
-
- if( sharedResource.isGLXVersionGreaterEqualOneThree() ) {
- availableCaps = getAvailableGLCapabilitiesFBConfig(sharedScreen, glp, isMultisampleAvailable);
- }
- if( null == availableCaps || availableCaps.isEmpty() ) {
- availableCaps = getAvailableGLCapabilitiesXVisual(sharedScreen, glp, isMultisampleAvailable);
+
+ sharedDevice.lock();
+ try {
+ if( sharedResource.isGLXVersionGreaterEqualOneThree() ) {
+ availableCaps = getAvailableGLCapabilitiesFBConfig(sharedScreen, glp, isMultisampleAvailable);
+ }
+ if( null == availableCaps || availableCaps.isEmpty() ) {
+ availableCaps = getAvailableGLCapabilitiesXVisual(sharedScreen, glp, isMultisampleAvailable);
+ }
+ } finally {
+ sharedDevice.unlock();
}
if( null != availableCaps && availableCaps.size() > 1 ) {
Collections.sort(availableCaps, XVisualIDComparator);
@@ -152,33 +157,35 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
// Utilizing FBConfig
//
- AbstractGraphicsDevice absDevice = x11Screen.getDevice();
- long display = absDevice.getHandle();
+ final X11GraphicsDevice absDevice = (X11GraphicsDevice) x11Screen.getDevice();
+ final long display = absDevice.getHandle();
- int screen = x11Screen.getIndex();
- int[] count = { -1 };
- ArrayList<GLCapabilitiesImmutable> availableCaps = new ArrayList<GLCapabilitiesImmutable>();
+ final int screen = x11Screen.getIndex();
+ final IntBuffer count = Buffers.newDirectIntBuffer(1);
+ count.put(0, -1);
+ final ArrayList<GLCapabilitiesImmutable> availableCaps = new ArrayList<GLCapabilitiesImmutable>();
- fbcfgsL = GLX.glXChooseFBConfig(display, screen, null, 0, count, 0);
+ fbcfgsL = GLX.glXChooseFBConfig(display, screen, null, count);
if (fbcfgsL == null || fbcfgsL.limit()<=0) {
if(DEBUG) {
- System.err.println("X11GLXGraphicsConfiguration.getAvailableGLCapabilitiesFBConfig: Failed glXChooseFBConfig ("+x11Screen+"): "+fbcfgsL+", "+count[0]);
+ System.err.println("X11GLXGraphicsConfiguration.getAvailableGLCapabilitiesFBConfig: Failed glXChooseFBConfig ("+x11Screen+"): "+fbcfgsL+", "+count.get(0));
}
return null;
}
for (int i = 0; i < fbcfgsL.limit(); i++) {
- if( !X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(availableCaps, glProfile, absDevice, fbcfgsL.get(i), GLGraphicsConfigurationUtil.ALL_BITS, isMultisampleAvailable) ) {
- if(DEBUG) {
- System.err.println("X11GLXGraphicsConfiguration.getAvailableGLCapabilitiesFBConfig: FBConfig invalid (2): ("+x11Screen+"): fbcfg: "+toHexString(fbcfgsL.get(i)));
- }
+ final GLCapabilitiesImmutable caps = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(absDevice, glProfile, fbcfgsL.get(i), GLGraphicsConfigurationUtil.ALL_BITS, isMultisampleAvailable);
+ if(null != caps) {
+ availableCaps.add(caps);
+ } else if(DEBUG) {
+ System.err.println("X11GLXGraphicsConfiguration.getAvailableGLCapabilitiesFBConfig: FBConfig invalid (2): ("+x11Screen+"): fbcfg: "+toHexString(fbcfgsL.get(i)));
}
}
return availableCaps;
}
static List<GLCapabilitiesImmutable> getAvailableGLCapabilitiesXVisual(X11GraphicsScreen x11Screen, GLProfile glProfile, boolean isMultisampleAvailable) {
- AbstractGraphicsDevice absDevice = x11Screen.getDevice();
- long display = absDevice.getHandle();
+ final X11GraphicsDevice absDevice = (X11GraphicsDevice) x11Screen.getDevice();
+ final long display = absDevice.getHandle();
int screen = x11Screen.getIndex();
@@ -191,10 +198,11 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
}
ArrayList<GLCapabilitiesImmutable> availableCaps = new ArrayList<GLCapabilitiesImmutable>();
for (int i = 0; i < infos.length; i++) {
- if( !X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(availableCaps, glProfile, display, infos[i], GLGraphicsConfigurationUtil.ALL_BITS, isMultisampleAvailable) ) {
- if(DEBUG) {
- System.err.println("X11GLXGraphicsConfiguration.getAvailableGLCapabilitiesXVisual: XVisual invalid: ("+x11Screen+"): fbcfg: "+toHexString(infos[i].getVisualid()));
- }
+ final GLCapabilitiesImmutable caps = X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(absDevice, glProfile, infos[i], GLGraphicsConfigurationUtil.ALL_BITS, isMultisampleAvailable);
+ if(null != caps) {
+ availableCaps.add(caps);
+ } if(DEBUG) {
+ System.err.println("X11GLXGraphicsConfiguration.getAvailableGLCapabilitiesXVisual: XVisual invalid: ("+x11Screen+"): fbcfg: "+toHexString(infos[i].getVisualid()));
}
}
return availableCaps;
@@ -208,25 +216,29 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
if (x11Screen == null) {
throw new IllegalArgumentException("AbstractGraphicsScreen is null");
}
-
if (capsChosen == null) {
capsChosen = new GLCapabilities(null);
}
X11GraphicsDevice x11Device = (X11GraphicsDevice) x11Screen.getDevice();
X11GLXDrawableFactory factory = (X11GLXDrawableFactory) GLDrawableFactory.getDesktopFactory();
+
+ capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( capsChosen, factory, x11Device);
+ final boolean usePBuffer = !capsChosen.isOnscreen() && capsChosen.isPBuffer();
- capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( capsChosen, GLContext.isFBOAvailable(x11Device, capsChosen.getGLProfile()), factory.canCreateGLPbuffer(x11Device) );
- boolean usePBuffer = capsChosen.isPBuffer();
-
X11GLXGraphicsConfiguration res = null;
- if( factory.isGLXVersionGreaterEqualOneThree(x11Device) ) {
- res = chooseGraphicsConfigurationFBConfig(capsChosen, capsReq, chooser, x11Screen, xvisualID);
- }
- if(null==res) {
- if(usePBuffer) {
- throw new GLException("Error: Couldn't create X11GLXGraphicsConfiguration based on FBConfig for visualID "+toHexString(xvisualID)+", "+capsChosen);
+ x11Device.lock();
+ try {
+ if( factory.isGLXVersionGreaterEqualOneThree(x11Device) ) {
+ res = chooseGraphicsConfigurationFBConfig(capsChosen, capsReq, chooser, x11Screen, xvisualID);
}
- res = chooseGraphicsConfigurationXVisual(capsChosen, capsReq, chooser, x11Screen, xvisualID);
+ if(null==res) {
+ if(usePBuffer) {
+ throw new GLException("Error: Couldn't create X11GLXGraphicsConfiguration based on FBConfig for visualID "+toHexString(xvisualID)+", "+capsChosen);
+ }
+ res = chooseGraphicsConfigurationXVisual(capsChosen, capsReq, chooser, x11Screen, xvisualID);
+ }
+ } finally {
+ x11Device.unlock();
}
if(null==res) {
throw new GLException("Error: Couldn't create X11GLXGraphicsConfiguration based on FBConfig and XVisual for visualID "+toHexString(xvisualID)+", "+x11Screen+", "+capsChosen);
@@ -238,8 +250,8 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
}
static X11GLXGraphicsConfiguration fetchGraphicsConfigurationFBConfig(X11GraphicsScreen x11Screen, int fbID, GLProfile glp) {
- final AbstractGraphicsDevice absDevice = x11Screen.getDevice();
- final long display = absDevice.getHandle();
+ final X11GraphicsDevice x11Device = (X11GraphicsDevice) x11Screen.getDevice();
+ final long display = x11Device.getHandle();
final int screen = x11Screen.getIndex();
final long fbcfg = X11GLXGraphicsConfiguration.glXFBConfigID2FBConfig(display, screen, fbID);
@@ -251,7 +263,7 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
}
final X11GLXDrawableFactory factory = (X11GLXDrawableFactory) GLDrawableFactory.getDesktopFactory();
- final X11GLCapabilities caps = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glp, absDevice, fbcfg, true, true, true, factory.isGLXMultisampleAvailable(absDevice));
+ final X11GLCapabilities caps = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(x11Device, glp, fbcfg, GLGraphicsConfigurationUtil.ALL_BITS, factory.isGLXMultisampleAvailable(x11Device));
return new X11GLXGraphicsConfiguration(x11Screen, caps, caps, new DefaultGLCapabilitiesChooser());
}
@@ -262,33 +274,32 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
int recommendedIndex = -1;
PointerBuffer fbcfgsL = null;
GLProfile glProfile = capsChosen.getGLProfile();
- boolean onscreen = capsChosen.isOnscreen();
- boolean usePBuffer = capsChosen.isPBuffer();
- boolean useFBO = capsChosen.isFBO();
// Utilizing FBConfig
//
- AbstractGraphicsDevice absDevice = x11Screen.getDevice();
- long display = absDevice.getHandle();
+ X11GraphicsDevice x11Device = (X11GraphicsDevice) x11Screen.getDevice();
+ long display = x11Device.getHandle();
int screen = x11Screen.getIndex();
final X11GLXDrawableFactory factory = (X11GLXDrawableFactory) GLDrawableFactory.getDesktopFactory();
- final boolean isMultisampleAvailable = factory.isGLXMultisampleAvailable(absDevice);
- int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capsChosen, true, isMultisampleAvailable, display, screen);
- int[] count = { -1 };
+ final boolean isMultisampleAvailable = factory.isGLXMultisampleAvailable(x11Device);
+ final IntBuffer attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capsChosen, true, isMultisampleAvailable, display, screen);
+ final IntBuffer count = Buffers.newDirectIntBuffer(1);
+ count.put(0, -1);
List<GLCapabilitiesImmutable> availableCaps = new ArrayList<GLCapabilitiesImmutable>();
- final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer, useFBO);
+ final int winattrmask = GLGraphicsConfigurationUtil.getExclusiveWinAttributeBits(capsChosen);
// 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice,
// skipped if xvisualID is given
if( VisualIDHolder.VID_UNDEFINED == xvisualID ) {
- fbcfgsL = GLX.glXChooseFBConfig(display, screen, attribs, 0, count, 0);
+ fbcfgsL = GLX.glXChooseFBConfig(display, screen, attribs, count);
}
if (fbcfgsL != null && fbcfgsL.limit()>0) {
for (int i = 0; i < fbcfgsL.limit(); i++) {
- if( !X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(availableCaps, glProfile, absDevice, fbcfgsL.get(i), winattrmask, isMultisampleAvailable) ) {
- if(DEBUG) {
- System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: FBConfig invalid (1): ("+x11Screen+","+capsChosen+"): fbcfg: "+toHexString(fbcfgsL.get(i)));
- }
+ final GLCapabilitiesImmutable caps = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(x11Device, glProfile, fbcfgsL.get(i), winattrmask, isMultisampleAvailable);
+ if( null != caps ) {
+ availableCaps.add(caps);
+ } else if(DEBUG) {
+ System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: FBConfig invalid (1): ("+x11Screen+","+capsChosen+"): fbcfg: "+toHexString(fbcfgsL.get(i)));
}
}
if(availableCaps.size() > 0) {
@@ -309,19 +320,20 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
// reset ..
recommendedIndex = -1;
- fbcfgsL = GLX.glXChooseFBConfig(display, screen, null, 0, count, 0);
+ fbcfgsL = GLX.glXChooseFBConfig(display, screen, null, count);
if (fbcfgsL == null || fbcfgsL.limit()<=0) {
if(DEBUG) {
- System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed glXChooseFBConfig ("+x11Screen+","+capsChosen+"): "+fbcfgsL+", "+count[0]);
+ System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed glXChooseFBConfig ("+x11Screen+","+capsChosen+"): "+fbcfgsL+", "+count.get(0));
}
return null;
}
for (int i = 0; i < fbcfgsL.limit(); i++) {
- if( !X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(availableCaps, glProfile, absDevice, fbcfgsL.get(i), winattrmask, isMultisampleAvailable) ) {
- if(DEBUG) {
- System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: FBConfig invalid (2): ("+x11Screen+"): fbcfg: "+toHexString(fbcfgsL.get(i)));
- }
+ final GLCapabilitiesImmutable caps = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(x11Device, glProfile, fbcfgsL.get(i), winattrmask, isMultisampleAvailable);
+ if( null != caps ) {
+ availableCaps.add(caps);
+ } else if(DEBUG) {
+ System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: FBConfig invalid (2): ("+x11Screen+"): fbcfg: "+toHexString(fbcfgsL.get(i)));
}
}
}
@@ -374,23 +386,23 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
}
GLProfile glProfile = capsChosen.getGLProfile();
- final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(capsChosen.isOnscreen(), false /* pbuffer */, false);
+ final int winattrmask = GLGraphicsConfigurationUtil.getExclusiveWinAttributeBits(capsChosen.isOnscreen(), capsChosen.isFBO(), false /* pbuffer */, capsChosen.isBitmap());
List<GLCapabilitiesImmutable> availableCaps = new ArrayList<GLCapabilitiesImmutable>();
int recommendedIndex = -1;
- AbstractGraphicsDevice absDevice = x11Screen.getDevice();
+ X11GraphicsDevice absDevice = (X11GraphicsDevice) x11Screen.getDevice();
long display = absDevice.getHandle();
int screen = x11Screen.getIndex();
final X11GLXDrawableFactory factory = (X11GLXDrawableFactory) GLDrawableFactory.getDesktopFactory();
final boolean isMultisampleAvailable = factory.isGLXMultisampleAvailable(absDevice);
- int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capsChosen, false, isMultisampleAvailable, display, screen);
+ final IntBuffer attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capsChosen, false, isMultisampleAvailable, display, screen);
XVisualInfo recommendedVis = null;
// 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice
// skipped if xvisualID is given
if( VisualIDHolder.VID_UNDEFINED == xvisualID ) {
- recommendedVis = GLX.glXChooseVisual(display, screen, attribs, 0);
+ recommendedVis = GLX.glXChooseVisual(display, screen, attribs);
if (DEBUG) {
System.err.print("glXChooseVisual recommended ");
if (recommendedVis == null) {
@@ -411,15 +423,15 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
}
for (int i = 0; i < infos.length; i++) {
- if( !X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(availableCaps, glProfile, display, infos[i], winattrmask, isMultisampleAvailable) ) {
- if(DEBUG) {
- System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationXVisual: XVisual invalid: ("+x11Screen+"): fbcfg: "+toHexString(infos[i].getVisualid()));
- }
- } else {
+ final GLCapabilitiesImmutable caps = X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(absDevice, glProfile, infos[i], winattrmask, isMultisampleAvailable);
+ if( null != caps ) {
+ availableCaps.add(caps);
// Attempt to find the visual chosenIndex by glXChooseVisual, if not translucent
if (capsChosen.isBackgroundOpaque() && recommendedVis != null && recommendedVis.getVisualid() == infos[i].getVisualid()) {
recommendedIndex = availableCaps.size() - 1;
}
+ } else if(DEBUG) {
+ System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationXVisual: XVisual invalid: ("+x11Screen+"): fbcfg: "+toHexString(infos[i].getVisualid()));
}
}
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11OnscreenGLXDrawable.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11OnscreenGLXDrawable.java
index 3632993..c15065c 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11OnscreenGLXDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11OnscreenGLXDrawable.java
@@ -91,7 +91,7 @@ public class X11OnscreenGLXDrawable extends X11GLXDrawable {
if(0!=glXWindow) {
GLX.glXDestroyWindow(dpy, glXWindow);
}
- glXWindow = GLX.glXCreateWindow(dpy, config.getFBConfig(), getNativeSurface().getSurfaceHandle(), null, 0);
+ glXWindow = GLX.glXCreateWindow(dpy, config.getFBConfig(), getNativeSurface().getSurfaceHandle(), null);
if (DEBUG) {
System.err.println("X11OnscreenGLXDrawable.setRealized(true): glXWindow: "+toHexString(getNativeSurface().getSurfaceHandle())+" -> "+toHexString(glXWindow));
}
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXDrawable.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXDrawable.java
index e1fe2f2..28db2ad 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXDrawable.java
@@ -40,6 +40,8 @@
package jogamp.opengl.x11.glx;
+import java.nio.IntBuffer;
+
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.AbstractGraphicsScreen;
import javax.media.nativewindow.NativeSurface;
@@ -50,6 +52,8 @@ import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
import javax.media.opengl.GLPbuffer;
+import com.jogamp.common.nio.Buffers;
+
public class X11PbufferGLXDrawable extends X11GLXDrawable {
protected X11PbufferGLXDrawable(GLDrawableFactory factory, NativeSurface target) {
/* GLCapabilities caps,
@@ -81,10 +85,11 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable {
}
private void createPbuffer() {
- X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration) getNativeSurface().getGraphicsConfiguration();
- AbstractGraphicsScreen aScreen = config.getScreen();
- AbstractGraphicsDevice aDevice = aScreen.getDevice();
- long display = aDevice.getHandle();
+ final MutableSurface ms = (MutableSurface) getNativeSurface();
+ final X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration) ms.getGraphicsConfiguration();
+ final AbstractGraphicsScreen aScreen = config.getScreen();
+ final AbstractGraphicsDevice aDevice = aScreen.getDevice();
+ final long display = aDevice.getHandle();
if (DEBUG) {
System.out.println("Pbuffer config: " + config);
@@ -94,8 +99,6 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable {
throw new GLException("Null display");
}
- NativeSurface ns = getNativeSurface();
-
GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable)config.getChosenCapabilities();
if (chosenCaps.getPbufferRenderToTexture()) {
@@ -108,24 +111,24 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable {
// Create the p-buffer.
int niattribs = 0;
- int[] iattributes = new int[7];
+ IntBuffer iattributes = Buffers.newDirectIntBuffer(7);
- iattributes[niattribs++] = GLX.GLX_PBUFFER_WIDTH;
- iattributes[niattribs++] = ns.getWidth();
- iattributes[niattribs++] = GLX.GLX_PBUFFER_HEIGHT;
- iattributes[niattribs++] = ns.getHeight();
- iattributes[niattribs++] = GLX.GLX_LARGEST_PBUFFER; // exact
- iattributes[niattribs++] = 0;
- iattributes[niattribs++] = 0;
+ iattributes.put(niattribs++, GLX.GLX_PBUFFER_WIDTH);
+ iattributes.put(niattribs++, ms.getWidth());
+ iattributes.put(niattribs++, GLX.GLX_PBUFFER_HEIGHT);
+ iattributes.put(niattribs++, ms.getHeight());
+ iattributes.put(niattribs++, GLX.GLX_LARGEST_PBUFFER); // exact
+ iattributes.put(niattribs++, 0);
+ iattributes.put(niattribs++, 0);
- long pbuffer = GLX.glXCreatePbuffer(display, config.getFBConfig(), iattributes, 0);
+ long pbuffer = GLX.glXCreatePbuffer(display, config.getFBConfig(), iattributes);
if (pbuffer == 0) {
// FIXME: query X error code for detail error message
throw new GLException("pbuffer creation error: glXCreatePbuffer() failed");
}
// Set up instance variables
- ((MutableSurface)ns).setSurfaceHandle(pbuffer);
+ ms.setSurfaceHandle(pbuffer);
if (DEBUG) {
System.err.println("Created pbuffer " + this);
diff --git a/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m b/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m
new file mode 100644
index 0000000..6ebf400
--- /dev/null
+++ b/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m
@@ -0,0 +1,840 @@
+#import "MacOSXWindowSystemInterface.h"
+#import <QuartzCore/QuartzCore.h>
+#import <pthread.h>
+#include "timespec.h"
+
+#import <OpenGL/glext.h>
+
+/**
+ * Partial include of gl3.h - which we can only expect and use
+ * in case of a GL3 core context at runtime.
+ * Otherwise we would need to have 2 modules, one including GL2
+ * and one inclusing GL3 headers.
+ */
+#ifndef GL_ARB_vertex_array_object
+#define GL_VERTEX_ARRAY_BINDING 0x85B5
+extern void glBindVertexArray (GLuint array);
+extern void glDeleteVertexArrays (GLsizei n, const GLuint *arrays);
+extern void glGenVertexArrays (GLsizei n, GLuint *arrays);
+extern GLboolean glIsVertexArray (GLuint array);
+#endif
+
+//
+// CADisplayLink only available on iOS >= 3.1, sad, since it's convenient.
+// Use CVDisplayLink otherwise.
+//
+// #define HAS_CADisplayLink 1
+//
+
+// lock/sync debug output
+//
+// #define DBG_SYNC 1
+//
+#ifdef DBG_SYNC
+ // #define SYNC_PRINT(...) NSLog(@ ## __VA_ARGS__)
+ #define SYNC_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr)
+#else
+ #define SYNC_PRINT(...)
+#endif
+
+// fps debug output
+//
+// #define DBG_PERF 1
+
+/**
+ * Capture setView(NULL), which produces a 'invalid drawable' message
+ *
+ * Also track lifecycle via DBG_PRINT messages, if VERBOSE is enabled!
+ */
+ at interface MyNSOpenGLContext: NSOpenGLContext
+{
+}
+- (id)initWithFormat:(NSOpenGLPixelFormat *)format shareContext:(NSOpenGLContext *)share;
+- (void)setView:(NSView *)view;
+- (void)update;
+- (void)dealloc;
+
+ at end
+
+ at implementation MyNSOpenGLContext
+
+- (id)initWithFormat:(NSOpenGLPixelFormat *)format shareContext:(NSOpenGLContext *)share
+{
+ DBG_PRINT("MyNSOpenGLContext.initWithFormat.0: format %p, share %p\n", format, share);
+ MyNSOpenGLContext * o = [super initWithFormat:format shareContext:share];
+ DBG_PRINT("MyNSOpenGLContext.initWithFormat.X: new %p\n", o);
+ return o;
+}
+
+- (void)setView:(NSView *)view
+{
+ DBG_PRINT("MyNSOpenGLContext.setView: this.0 %p, view %p\n", self, view);
+ if(NULL != view) {
+ [super setView:view];
+ }
+ DBG_PRINT("MyNSOpenGLContext.setView.X\n");
+}
+
+- (void)update
+{
+ DBG_PRINT("MyNSOpenGLContext.update: this.0 %p, view %p\n", self, [self view]);
+ [super update];
+ DBG_PRINT("MyNSOpenGLContext.update.X\n");
+}
+
+- (void)dealloc
+{
+ DBG_PRINT("MyNSOpenGLContext.dealloc: this.0 %p\n", self);
+ [super dealloc];
+ DBG_PRINT("MyNSOpenGLContext.dealloc.X: %p\n", self);
+}
+
+ at end
+
+ at interface MyNSOpenGLLayer: NSOpenGLLayer
+{
+ at private
+ GLfloat gl_texCoords[8];
+
+ at protected
+ NSOpenGLContext* parentCtx;
+ GLuint gl3ShaderProgramName;
+ GLuint vboBufVert;
+ GLuint vboBufTexCoord;
+ GLint vertAttrLoc;
+ GLint texCoordAttrLoc;
+ NSOpenGLPixelFormat* parentPixelFmt;
+ int texWidth;
+ int texHeight;
+ int newTexWidth;
+ int newTexHeight;
+ volatile NSOpenGLPixelBuffer* pbuffer;
+ volatile GLuint textureID;
+ volatile NSOpenGLPixelBuffer* newPBuffer;
+#ifdef HAS_CADisplayLink
+ CADisplayLink* displayLink;
+#else
+ CVDisplayLinkRef displayLink;
+#endif
+ int tc;
+ struct timespec tStart;
+ at public
+ struct timespec lastWaitTime;
+ GLint swapInterval;
+ GLint swapIntervalCounter;
+ pthread_mutex_t renderLock;
+ pthread_cond_t renderSignal;
+ volatile Bool shallDraw;
+}
+
+- (id) setupWithContext: (NSOpenGLContext*) parentCtx
+ gl3ShaderProgramName: (GLuint) gl3ShaderProgramName
+ pixelFormat: (NSOpenGLPixelFormat*) pfmt
+ pbuffer: (NSOpenGLPixelBuffer*) p
+ texIDArg: (GLuint) texID
+ opaque: (Bool) opaque
+ texWidth: (int) texWidth
+ texHeight: (int) texHeight;
+
+- (Bool) validateTexSizeWithNewSize;
+- (Bool) validateTexSize: (int) _texWidth texHeight: (int) _texHeight;
+- (void) setTextureID: (int) _texID;
+
+- (Bool) isSamePBuffer: (NSOpenGLPixelBuffer*) p;
+- (void) setNewPBuffer: (NSOpenGLPixelBuffer*)p;
+- (void) applyNewPBuffer;
+
+- (NSOpenGLPixelFormat *)openGLPixelFormatForDisplayMask:(uint32_t)mask;
+- (NSOpenGLContext *)openGLContextForPixelFormat:(NSOpenGLPixelFormat *)pixelFormat;
+- (void)disableAnimation;
+- (void)pauseAnimation:(Bool)pause;
+- (void)deallocPBuffer;
+- (void)releaseLayer;
+- (void)dealloc;
+- (void)setSwapInterval:(int)interval;
+- (void)tick;
+- (void)waitUntilRenderSignal: (long) to_micros;
+- (Bool)isGLSourceValid;
+
+ at end
+
+#ifndef HAS_CADisplayLink
+
+static CVReturn renderMyNSOpenGLLayer(CVDisplayLinkRef displayLink,
+ const CVTimeStamp *inNow,
+ const CVTimeStamp *inOutputTime,
+ CVOptionFlags flagsIn,
+ CVOptionFlags *flagsOut,
+ void *displayLinkContext)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ MyNSOpenGLLayer* l = (MyNSOpenGLLayer*)displayLinkContext;
+ pthread_mutex_lock(&l->renderLock);
+ if( 0 < l->swapInterval ) {
+ l->swapIntervalCounter++;
+ if( l->swapIntervalCounter >= l->swapInterval ) {
+ SYNC_PRINT("<S %d/%d>", (int)l->swapIntervalCounter, l->swapInterval);
+ l->swapIntervalCounter = 0;
+ pthread_cond_signal(&l->renderSignal); // wake up vsync
+ }
+ }
+ pthread_mutex_unlock(&l->renderLock);
+ [pool release];
+ return kCVReturnSuccess;
+}
+
+#endif
+
+static const GLfloat gl_verts[] = {
+ -1.0, -1.0,
+ -1.0, 1.0,
+ 1.0, 1.0,
+ 1.0, -1.0
+};
+
+ at implementation MyNSOpenGLLayer
+
+- (id) setupWithContext: (NSOpenGLContext*) _parentCtx
+ gl3ShaderProgramName: (GLuint) _gl3ShaderProgramName
+ pixelFormat: (NSOpenGLPixelFormat*) _parentPixelFmt
+ pbuffer: (NSOpenGLPixelBuffer*) p
+ texIDArg: (GLuint) texID
+ opaque: (Bool) opaque
+ texWidth: (int) _texWidth
+ texHeight: (int) _texHeight;
+{
+ pthread_mutexattr_t renderLockAttr;
+ pthread_mutexattr_init(&renderLockAttr);
+ pthread_mutexattr_settype(&renderLockAttr, PTHREAD_MUTEX_RECURSIVE);
+ pthread_mutex_init(&renderLock, &renderLockAttr); // recursive
+ pthread_cond_init(&renderSignal, NULL); // no attribute
+
+ {
+ int i;
+ for(i=0; i<8; i++) {
+ gl_texCoords[i] = 0.0f;
+ }
+ }
+ parentCtx = _parentCtx;
+ gl3ShaderProgramName = _gl3ShaderProgramName;
+ vboBufVert = 0;
+ vboBufTexCoord = 0;
+ vertAttrLoc = 0;
+ texCoordAttrLoc = 0;
+ parentPixelFmt = _parentPixelFmt;
+ swapInterval = 1; // defaults to on (as w/ new GL profiles)
+ swapIntervalCounter = 0;
+ timespec_now(&lastWaitTime);
+ shallDraw = NO;
+ newTexWidth = _texWidth;
+ newTexHeight = _texHeight;
+ [self validateTexSizeWithNewSize];
+ [self setTextureID: texID];
+
+ newPBuffer = NULL;
+ pbuffer = p;
+ if(NULL != pbuffer) {
+ [pbuffer retain];
+ }
+
+ {
+ // no animations for add/remove/swap sublayers etc
+ // doesn't work: [self removeAnimationForKey: kCAOnOrderIn, kCAOnOrderOut, kCATransition]
+ [self removeAllAnimations];
+ }
+
+ // instantiate a deactivated displayLink
+#ifdef HAS_CADisplayLink
+ displayLink = [[CVDisplayLink displayLinkWithTarget:self selector:@selector(setNeedsDisplay)] retain];
+#else
+ CVReturn cvres;
+ {
+ int allDisplaysMask = 0;
+ int virtualScreen, accelerated, displayMask;
+ for (virtualScreen = 0; virtualScreen < [parentPixelFmt numberOfVirtualScreens]; virtualScreen++) {
+ [parentPixelFmt getValues:&displayMask forAttribute:NSOpenGLPFAScreenMask forVirtualScreen:virtualScreen];
+ [parentPixelFmt getValues:&accelerated forAttribute:NSOpenGLPFAAccelerated forVirtualScreen:virtualScreen];
+ if (accelerated) {
+ allDisplaysMask |= displayMask;
+ }
+ }
+ cvres = CVDisplayLinkCreateWithOpenGLDisplayMask(allDisplaysMask, &displayLink);
+ if(kCVReturnSuccess != cvres) {
+ DBG_PRINT("MyNSOpenGLLayer::init %p, CVDisplayLinkCreateWithOpenGLDisplayMask %X failed: %d\n", self, allDisplaysMask, cvres);
+ displayLink = NULL;
+ }
+ }
+ if(NULL != displayLink) {
+ cvres = CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(displayLink, [parentCtx CGLContextObj], [parentPixelFmt CGLPixelFormatObj]);
+ if(kCVReturnSuccess != cvres) {
+ DBG_PRINT("MyNSOpenGLLayer::init %p, CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext failed: %d\n", self, cvres);
+ displayLink = NULL;
+ }
+ }
+ if(NULL != displayLink) {
+ cvres = CVDisplayLinkSetOutputCallback(displayLink, renderMyNSOpenGLLayer, self);
+ if(kCVReturnSuccess != cvres) {
+ DBG_PRINT("MyNSOpenGLLayer::init %p, CVDisplayLinkSetOutputCallback failed: %d\n", self, cvres);
+ displayLink = NULL;
+ }
+ }
+#endif
+ [self pauseAnimation: YES];
+
+ [self removeAllAnimations];
+ [self setAutoresizingMask: (kCALayerWidthSizable|kCALayerHeightSizable)];
+ [self setNeedsDisplayOnBoundsChange: YES];
+
+ [self setOpaque: opaque ? YES : NO];
+
+#ifdef VERBOSE_ON
+ CGRect lRect = [self bounds];
+ if(NULL != pbuffer) {
+ DBG_PRINT("MyNSOpenGLLayer::init (pbuffer) %p, ctx %p, pfmt %p, pbuffer %p, opaque %d, pbuffer %dx%d -> tex %dx%d, bounds: %lf/%lf %lfx%lf (refcnt %d)\n",
+ self, parentCtx, parentPixelFmt, pbuffer, opaque, [pbuffer pixelsWide], [pbuffer pixelsHigh], texWidth, texHeight,
+ lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height, (int)[self retainCount]);
+ } else {
+ DBG_PRINT("MyNSOpenGLLayer::init (texture) %p, ctx %p, pfmt %p, opaque %d, tex[id %d, %dx%d], bounds: %lf/%lf %lfx%lf (refcnt %d)\n",
+ self, parentCtx, parentPixelFmt, opaque, (int)textureID, texWidth, texHeight,
+ lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height, (int)[self retainCount]);
+ }
+#endif
+ return self;
+}
+
+- (Bool) validateTexSizeWithNewSize
+{
+ return [self validateTexSize: newTexWidth texHeight: newTexHeight];
+}
+
+- (Bool) validateTexSize: (int) _texWidth texHeight: (int) _texHeight
+{
+ if(_texHeight != texHeight || _texWidth != texWidth) {
+ texWidth = _texWidth;
+ texHeight = _texHeight;
+ CGRect lRect = [self bounds];
+ lRect.origin.x = 0;
+ lRect.origin.y = 0;
+ lRect.size.width = texWidth;
+ lRect.size.height = texHeight;
+ [self setFrame: lRect];
+
+ GLfloat texCoordWidth, texCoordHeight;
+ if(NULL != pbuffer) {
+ GLenum textureTarget = [pbuffer textureTarget] ;
+ GLsizei pwidth = [pbuffer pixelsWide];
+ GLsizei pheight = [pbuffer pixelsHigh];
+ if( GL_TEXTURE_2D == textureTarget ) {
+ texCoordWidth = (GLfloat)pwidth /(GLfloat)texWidth ;
+ texCoordHeight = (GLfloat)pheight/(GLfloat)texHeight ;
+ } else {
+ texCoordWidth = pwidth;
+ texCoordHeight = pheight;
+ }
+ } else {
+ texCoordWidth = (GLfloat)1.0f;
+ texCoordHeight = (GLfloat)1.0f;
+ }
+ gl_texCoords[3] = texCoordHeight;
+ gl_texCoords[5] = texCoordHeight;
+ gl_texCoords[4] = texCoordWidth;
+ gl_texCoords[6] = texCoordWidth;
+ return YES;
+ } else {
+ return NO;
+ }
+}
+
+- (void) setTextureID: (int) _texID
+{
+ textureID = _texID;
+}
+
+- (Bool) isSamePBuffer: (NSOpenGLPixelBuffer*) p
+{
+ return pbuffer == p || newPBuffer == p;
+}
+
+- (void)setNewPBuffer: (NSOpenGLPixelBuffer*)p
+{
+ SYNC_PRINT("<NP-S %p -> %p>", pbuffer, p);
+ newPBuffer = p;
+ [newPBuffer retain];
+}
+
+- (void) applyNewPBuffer
+{
+ if( NULL != newPBuffer ) { // volatile OK
+ SYNC_PRINT("<NP-A %p -> %p>", pbuffer, newPBuffer);
+
+ if( 0 != textureID ) {
+ glDeleteTextures(1, (GLuint *)&textureID);
+ [self setTextureID: 0];
+ }
+ [pbuffer release];
+
+ pbuffer = newPBuffer;
+ newPBuffer = NULL;
+ }
+}
+
+- (void)deallocPBuffer
+{
+ if(NULL != pbuffer) {
+ NSOpenGLContext* context = [self openGLContext];
+ if(NULL!=context) {
+ [context makeCurrentContext];
+
+ DBG_PRINT("MyNSOpenGLLayer::deallocPBuffer (with ctx) %p (refcnt %d) - context %p, pbuffer %p, texID %d\n", self, (int)[self retainCount], context, pbuffer, (int)textureID);
+
+ if( 0 != textureID ) {
+ glDeleteTextures(1, (GLuint *)&textureID);
+ [self setTextureID: 0];
+ }
+ if(NULL != pbuffer) {
+ [pbuffer release];
+ pbuffer = NULL;
+ }
+ if(NULL != newPBuffer) {
+ [newPBuffer release];
+ newPBuffer = NULL;
+ }
+
+ [context clearDrawable];
+ } else {
+ DBG_PRINT("MyNSOpenGLLayer::deallocPBuffer (w/o ctx) %p (refcnt %d) - context %p, pbuffer %p, texID %d\n", self, (int)[self retainCount], context, pbuffer, (int)textureID);
+ }
+ }
+}
+
+- (NSOpenGLPixelFormat *)openGLPixelFormatForDisplayMask:(uint32_t)mask
+{
+ DBG_PRINT("MyNSOpenGLLayer::openGLPixelFormatForDisplayMask: %p (refcnt %d) - parent-pfmt %p -> new-pfmt %p\n",
+ self, (int)[self retainCount], parentPixelFmt, parentPixelFmt);
+ return parentPixelFmt;
+}
+
+- (NSOpenGLContext *)openGLContextForPixelFormat:(NSOpenGLPixelFormat *)pixelFormat
+{
+ DBG_PRINT("MyNSOpenGLLayer::openGLContextForPixelFormat.0: %p (refcnt %d) - pfmt %p, parent %p\n",
+ self, (int)[self retainCount], pixelFormat, parentCtx);
+ NSOpenGLContext * nctx = [[MyNSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:parentCtx];
+ DBG_PRINT("MyNSOpenGLLayer::openGLContextForPixelFormat.X: new-ctx %p\n", nctx);
+ return nctx;
+}
+
+- (void)disableAnimation
+{
+ DBG_PRINT("MyNSOpenGLLayer::disableAnimation: %p (refcnt %d) - displayLink %p\n", self, (int)[self retainCount], displayLink);
+ pthread_mutex_lock(&renderLock);
+ [self setAsynchronous: NO];
+ if(NULL != displayLink) {
+#ifdef HAS_CADisplayLink
+ [displayLink setPaused: YES];
+ [displayLink release];
+#else
+ CVDisplayLinkStop(displayLink);
+ CVDisplayLinkRelease(displayLink);
+#endif
+ displayLink = NULL;
+ }
+ pthread_mutex_unlock(&renderLock);
+}
+
+- (void)releaseLayer
+{
+ DBG_PRINT("MyNSOpenGLLayer::releaseLayer.0: %p (refcnt %d)\n", self, (int)[self retainCount]);
+ pthread_mutex_lock(&renderLock);
+ [self disableAnimation];
+ [self deallocPBuffer];
+ [[self openGLContext] release];
+ [self release];
+ DBG_PRINT("MyNSOpenGLLayer::releaseLayer.X: %p (refcnt %d)\n", self, (int)[self retainCount]);
+ pthread_mutex_unlock(&renderLock);
+}
+
+- (void)dealloc
+{
+ DBG_PRINT("MyNSOpenGLLayer::dealloc.0 %p (refcnt %d)\n", self, (int)[self retainCount]);
+ // NSLog(@"MyNSOpenGLLayer::dealloc: %@",[NSThread callStackSymbols]);
+
+ pthread_mutex_lock(&renderLock);
+ [self disableAnimation];
+ [self deallocPBuffer];
+ pthread_mutex_unlock(&renderLock);
+ pthread_cond_destroy(&renderSignal);
+ pthread_mutex_destroy(&renderLock);
+ [super dealloc];
+ DBG_PRINT("MyNSOpenGLLayer::dealloc.X %p\n", self);
+}
+
+- (Bool)isGLSourceValid
+{
+ return NULL != pbuffer || NULL != newPBuffer || 0 != textureID ;
+}
+
+- (void)resizeWithOldSuperlayerSize:(CGSize)size
+ {
+ CGRect lRectS = [[self superlayer] bounds];
+
+ DBG_PRINT("MyNSOpenGLLayer::resizeWithOldSuperlayerSize: %p, texSize %dx%d, bounds: %lfx%lf -> %lfx%lf (refcnt %d)\n",
+ self, texWidth, texHeight, size.width, size.height, lRectS.size.width, lRectS.size.height, (int)[self retainCount]);
+
+ newTexWidth = lRectS.size.width;
+ newTexHeight = lRectS.size.height;
+ shallDraw = [self isGLSourceValid];
+ SYNC_PRINT("<SZ %dx%d>", newTexWidth, newTexHeight);
+
+ [super resizeWithOldSuperlayerSize: size];
+}
+
+- (BOOL)canDrawInOpenGLContext:(NSOpenGLContext *)context pixelFormat:(NSOpenGLPixelFormat *)pixelFormat
+ forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp
+{
+ SYNC_PRINT("<? %d>", (int)shallDraw);
+ return shallDraw;
+}
+
+- (void)drawInOpenGLContext:(NSOpenGLContext *)context pixelFormat:(NSOpenGLPixelFormat *)pixelFormat
+ forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp
+{
+ pthread_mutex_unlock(&renderLock);
+ SYNC_PRINT("<* ");
+ // NSLog(@"MyNSOpenGLLayer::DRAW: %@",[NSThread callStackSymbols]);
+
+ if( shallDraw && ( NULL != pbuffer || NULL != newPBuffer || 0 != textureID ) ) {
+ [context makeCurrentContext];
+
+ if( NULL != newPBuffer ) { // volatile OK
+ [self applyNewPBuffer];
+ }
+
+ GLenum textureTarget;
+
+ Bool texSizeChanged = [self validateTexSizeWithNewSize];
+
+ if( NULL != pbuffer ) {
+ if( texSizeChanged && 0 != textureID ) {
+ glDeleteTextures(1, (GLuint *)&textureID);
+ [self setTextureID: 0];
+ }
+ textureTarget = [pbuffer textureTarget];
+ if( 0 != gl3ShaderProgramName ) {
+ glUseProgram(gl3ShaderProgramName);
+ glActiveTexture(GL_TEXTURE0);
+ }
+ if( 0 == textureID ) {
+ glGenTextures(1, (GLuint *)&textureID);
+ glBindTexture(textureTarget, textureID);
+ glTexParameteri(textureTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(textureTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ } else {
+ glBindTexture(textureTarget, textureID);
+ }
+ [context setTextureImageToPixelBuffer: (NSOpenGLPixelBuffer*) pbuffer colorBuffer: GL_FRONT];
+ } else {
+ if( 0 != gl3ShaderProgramName ) {
+ glUseProgram(gl3ShaderProgramName);
+ glActiveTexture(GL_TEXTURE0);
+ }
+ textureTarget = GL_TEXTURE_2D;
+ glBindTexture(textureTarget, textureID);
+ }
+ SYNC_PRINT(" %d gl3Prog %d/%d*>", (int)textureID, (int)gl3ShaderProgramName, (int)glIsProgram (gl3ShaderProgramName));
+
+ if( 0 == vboBufVert ) { // Once: Init Data and Bind to Pointer
+ if( 0 != gl3ShaderProgramName ) {
+ // Install default VAO as required by GL 3.2 core!
+ GLuint vaoBuf = 0;
+ glGenVertexArrays(1, &vaoBuf);
+ glBindVertexArray(vaoBuf);
+
+ // Set texture-unit 0
+ GLint texUnitLoc = glGetUniformLocation (gl3ShaderProgramName, "mgl_Texture0");
+ glUniform1i (texUnitLoc, 0);
+ }
+ glGenBuffers( 1, &vboBufVert );
+ glBindBuffer( GL_ARRAY_BUFFER, vboBufVert );
+ glBufferData( GL_ARRAY_BUFFER, 4 * 2 * sizeof(GLfloat), gl_verts, GL_STATIC_DRAW);
+ if( 0 != gl3ShaderProgramName ) {
+ vertAttrLoc = glGetAttribLocation( gl3ShaderProgramName, "mgl_Vertex" );
+ glVertexAttribPointer( vertAttrLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL );
+ } else {
+ glVertexPointer(2, GL_FLOAT, 0, NULL);
+ }
+
+ glGenBuffers( 1, &vboBufTexCoord );
+ glBindBuffer( GL_ARRAY_BUFFER, vboBufTexCoord );
+ glBufferData( GL_ARRAY_BUFFER, 4 * 2 * sizeof(GLfloat), gl_texCoords, GL_STATIC_DRAW);
+ if( 0 != gl3ShaderProgramName ) {
+ texCoordAttrLoc = glGetAttribLocation( gl3ShaderProgramName, "mgl_MultiTexCoord" );
+ glVertexAttribPointer( texCoordAttrLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL );
+ } else {
+ glTexCoordPointer(2, GL_FLOAT, 0, NULL);
+ }
+ }
+ if( texSizeChanged ) {
+ glBindBuffer( GL_ARRAY_BUFFER, vboBufTexCoord );
+ glBufferSubData( GL_ARRAY_BUFFER, 0, 4 * 2 * sizeof(GLfloat), gl_texCoords);
+ if( 0 != gl3ShaderProgramName ) {
+ glVertexAttribPointer( texCoordAttrLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL );
+ } else {
+ glTexCoordPointer(2, GL_FLOAT, 0, NULL);
+ }
+ }
+ if( 0 != gl3ShaderProgramName ) {
+ glEnableVertexAttribArray( vertAttrLoc );
+ glEnableVertexAttribArray( texCoordAttrLoc );
+ } else {
+ glEnable(textureTarget);
+
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ }
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ if( 0 != gl3ShaderProgramName ) {
+ glDisableVertexAttribArray( vertAttrLoc );
+ glDisableVertexAttribArray( texCoordAttrLoc );
+ glUseProgram(0);
+ } else {
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+
+ glDisable(textureTarget);
+ }
+
+ glBindTexture(textureTarget, 0);
+
+ [context clearDrawable];
+
+ [super drawInOpenGLContext: context pixelFormat: pixelFormat forLayerTime: timeInterval displayTime: timeStamp];
+
+ } else {
+ // glClear(GL_COLOR_BUFFER_BIT);
+ // glBlitFramebuffer(0, 0, texWidth, texHeight,
+ // 0, 0, texWidth, texHeight,
+ // GL_COLOR_BUFFER_BIT, GL_NEAREST);
+ SYNC_PRINT(" 0*>");
+ }
+
+ #ifdef DBG_PERF
+ [self tick];
+ #endif
+ shallDraw = NO;
+
+ if( 0 >= swapInterval ) {
+ pthread_cond_signal(&renderSignal); // wake up !vsync
+ SYNC_PRINT("<s>");
+ }
+ SYNC_PRINT("<$>\n");
+ pthread_mutex_unlock(&renderLock);
+}
+
+- (void)pauseAnimation:(Bool)pause
+{
+ DBG_PRINT("MyNSOpenGLLayer::pauseAnimation: %d\n", (int)pause);
+ [self setAsynchronous: NO];
+ if(pause) {
+ if(NULL != displayLink) {
+ #ifdef HAS_CADisplayLink
+ [displayLink setPaused: YES];
+ #else
+ CVDisplayLinkStop(displayLink);
+ #endif
+ }
+ } else {
+ if(NULL != displayLink) {
+ #ifdef HAS_CADisplayLink
+ [displayLink setPaused: NO];
+ [displayLink setFrameInterval: swapInterval];
+ #else
+ CVDisplayLinkStart(displayLink);
+ #endif
+ }
+ }
+ tc = 0;
+ timespec_now(&tStart);
+}
+
+- (void)setSwapInterval:(int)interval
+{
+ /**
+ * v-sync doesn't works w/ NSOpenGLLayer's context .. well :(
+ * Using CVDisplayLink .. see setSwapInterval() below.
+ *
+ GLint si;
+ [context getValues: &si forParameter: NSOpenGLCPSwapInterval];
+ if(si != swapInterval) {
+ DBG_PRINT("MyNSOpenGLLayer::drawInOpenGLContext %p setSwapInterval: %d -> %d\n", self, si, swapInterval);
+ [context setValues: &swapInterval forParameter: NSOpenGLCPSwapInterval];
+ }
+ */
+
+ pthread_mutex_lock(&renderLock);
+ DBG_PRINT("MyNSOpenGLLayer::setSwapInterval.0: %d - displayLink %p\n", interval, displayLink);
+ swapInterval = interval;
+ swapIntervalCounter = 0;
+ pthread_mutex_unlock(&renderLock);
+
+ if(0 < swapInterval) {
+ [self pauseAnimation: NO];
+ } else {
+ [self pauseAnimation: YES];
+ }
+ DBG_PRINT("MyNSOpenGLLayer::setSwapInterval.X: %d\n", interval);
+}
+
+-(void)tick
+{
+ tc++;
+ if(tc%60==0) {
+ struct timespec t1, td;
+ timespec_now(&t1);
+ timespec_subtract(&td, &t1, &tStart);
+ long td_ms = timespec_milliseconds(&td);
+ fprintf(stderr, "NSOpenGLLayer: %ld ms / %d frames, %ld ms / frame, %f fps\n",
+ td_ms, tc, td_ms/tc, (tc * 1000.0) / (float)td_ms );
+ fflush(NULL);
+ }
+}
+
+- (void)waitUntilRenderSignal: (long) to_micros
+{
+ BOOL ready = NO;
+ int wr = 0;
+ pthread_mutex_lock(&renderLock);
+ SYNC_PRINT("{W %ld us", to_micros);
+ do {
+ if(0 >= swapInterval) {
+ ready = YES;
+ }
+ if(NO == ready) {
+ #ifdef DBG_SYNC
+ struct timespec t0, t1, td, td2;
+ timespec_now(&t0);
+ #endif
+ if(0 < to_micros) {
+ struct timespec to_abs = lastWaitTime;
+ timespec_addmicros(&to_abs, to_micros);
+ #ifdef DBG_SYNC
+ timespec_subtract(&td, &to_abs, &t0);
+ fprintf(stderr, ", (%ld) / ", timespec_milliseconds(&td));
+ #endif
+ wr = pthread_cond_timedwait(&renderSignal, &renderLock, &to_abs);
+ #ifdef DBG_SYNC
+ timespec_now(&t1);
+ timespec_subtract(&td, &t1, &t0);
+ timespec_subtract(&td2, &t1, &lastWaitTime);
+ fprintf(stderr, "(%ld) / (%ld) ms", timespec_milliseconds(&td), timespec_milliseconds(&td2));
+ #endif
+ } else {
+ pthread_cond_wait (&renderSignal, &renderLock);
+ #ifdef DBG_SYNC
+ timespec_now(&t1);
+ timespec_subtract(&td, &t1, &t0);
+ timespec_subtract(&td2, &t1, &lastWaitTime);
+ fprintf(stderr, "(%ld) / (%ld) ms", timespec_milliseconds(&td), timespec_milliseconds(&td2));
+ #endif
+ }
+ ready = YES;
+ }
+ } while (NO == ready && 0 == wr) ;
+ SYNC_PRINT("-%d-%d-%d}", shallDraw, wr, ready);
+ timespec_now(&lastWaitTime);
+ pthread_mutex_unlock(&renderLock);
+}
+
+ at end
+
+NSOpenGLLayer* createNSOpenGLLayer(NSOpenGLContext* ctx, int gl3ShaderProgramName, NSOpenGLPixelFormat* fmt, NSOpenGLPixelBuffer* p, uint32_t texID, Bool opaque, int texWidth, int texHeight) {
+ // This simply crashes after dealloc() has been called .. ie. ref-count -> 0 too early ?
+ // However using alloc/init, actual dealloc happens at JAWT destruction, hence too later IMHO.
+ // return [[MyNSOpenGLLayer layer] setupWithContext:ctx pixelFormat: fmt pbuffer: p texIDArg: (GLuint)texID
+ // opaque: opaque texWidth: texWidth texHeight: texHeight];
+
+ return [[[MyNSOpenGLLayer alloc] init] setupWithContext:ctx gl3ShaderProgramName: (GLuint)gl3ShaderProgramName pixelFormat: fmt pbuffer: p texIDArg: (GLuint)texID
+ opaque: opaque texWidth: texWidth texHeight: texHeight];
+}
+
+void setNSOpenGLLayerSwapInterval(NSOpenGLLayer* layer, int interval) {
+ MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ [l setSwapInterval: interval];
+ [pool release];
+}
+
+void waitUntilNSOpenGLLayerIsReady(NSOpenGLLayer* layer, long to_micros) {
+ MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ [l waitUntilRenderSignal: to_micros];
+ [pool release];
+}
+
+void setNSOpenGLLayerNeedsDisplayFBO(NSOpenGLLayer* layer, uint32_t texID) {
+ MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ Bool shallDraw;
+
+ // volatile OK
+ [l setTextureID: texID];
+ shallDraw = [l isGLSourceValid];
+ l->shallDraw = shallDraw;
+
+ SYNC_PRINT("<! T %d>", (int)shallDraw);
+ if(shallDraw) {
+ if ( [NSThread isMainThread] == YES ) {
+ [l setNeedsDisplay];
+ } else {
+ // don't wait - using doublebuffering
+ [l performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:NO];
+ }
+ }
+ // DBG_PRINT("MyNSOpenGLLayer::setNSOpenGLLayerNeedsDisplay %p\n", l);
+ [pool release];
+}
+
+void setNSOpenGLLayerNeedsDisplayPBuffer(NSOpenGLLayer* layer, NSOpenGLPixelBuffer* p) {
+ MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ Bool shallDraw;
+
+ if( NO == [l isSamePBuffer: p] ) {
+ [l setNewPBuffer: p];
+ }
+
+ // volatile OK
+ shallDraw = [l isGLSourceValid];
+ l->shallDraw = shallDraw;
+
+ SYNC_PRINT("<! T %d>", (int)shallDraw);
+ if(shallDraw) {
+ if ( [NSThread isMainThread] == YES ) {
+ [l setNeedsDisplay];
+ } else {
+ // don't wait - using doublebuffering
+ [l performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:NO];
+ }
+ }
+ // DBG_PRINT("MyNSOpenGLLayer::setNSOpenGLLayerNeedsDisplay %p\n", l);
+ [pool release];
+}
+
+void releaseNSOpenGLLayer(NSOpenGLLayer* layer) {
+ MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ DBG_PRINT("MyNSOpenGLLayer::releaseNSOpenGLLayer.0: %p\n", l);
+
+ if ( [NSThread isMainThread] == YES ) {
+ [l releaseLayer];
+ } else {
+ [l performSelectorOnMainThread:@selector(releaseLayer) withObject:nil waitUntilDone:NO];
+ }
+
+ DBG_PRINT("MyNSOpenGLLayer::releaseNSOpenGLLayer.X: %p\n", l);
+ [pool release];
+}
+
diff --git a/src/jogl/native/macosx/MacOSXWindowSystemInterface-pbuffer.m b/src/jogl/native/macosx/MacOSXWindowSystemInterface-pbuffer.m
deleted file mode 100644
index b81b43e..0000000
--- a/src/jogl/native/macosx/MacOSXWindowSystemInterface-pbuffer.m
+++ /dev/null
@@ -1,494 +0,0 @@
-#import "MacOSXWindowSystemInterface.h"
-#import <QuartzCore/QuartzCore.h>
-#import <pthread.h>
-#include "timespec.h"
-
-//
-// CADisplayLink only available on iOS >= 3.1, sad, since it's convenient.
-// Use CVDisplayLink otherwise.
-//
-// #define HAS_CADisplayLink 1
-//
-
-// lock/sync debug output
-//
-// #define DBG_SYNC 1
-//
-#ifdef DBG_SYNC
- // #define SYNC_PRINT(...) NSLog(@ ## __VA_ARGS__)
- #define SYNC_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr)
-#else
- #define SYNC_PRINT(...)
-#endif
-
-// fps debug output
-//
-// #define DBG_PERF 1
-
- at interface MyNSOpenGLLayer: NSOpenGLLayer
-{
- at protected
- NSOpenGLPixelBuffer* pbuffer;
- int texWidth;
- int texHeight;
- GLuint textureID;
-#ifdef HAS_CADisplayLink
- CADisplayLink* displayLink;
-#else
- CVDisplayLinkRef displayLink;
-#endif
- int tc;
- struct timespec t0;
- at public
- struct timespec lastWaitTime;
- GLint swapInterval;
- GLint swapIntervalCounter;
- pthread_mutex_t renderLock;
- pthread_cond_t renderSignal;
- BOOL shallDraw;
-}
-
-- (id) setupWithContext: (NSOpenGLContext*) ctx
- pixelFormat: (NSOpenGLPixelFormat*) pfmt
- pbuffer: (NSOpenGLPixelBuffer*) p
- opaque: (Bool) opaque
- texWidth: (int) texWidth
- texHeight: (int) texHeight;
-
-- (void)deallocTex;
-- (void)disableAnimation;
-- (void)releaseLayer;
-- (void)dealloc;
-- (int)getSwapInterval;
-- (void)setSwapInterval:(int)interval;
-- (void)tick;
-
- at end
-
-#ifndef HAS_CADisplayLink
-
-static CVReturn renderMyNSOpenGLLayer(CVDisplayLinkRef displayLink,
- const CVTimeStamp *inNow,
- const CVTimeStamp *inOutputTime,
- CVOptionFlags flagsIn,
- CVOptionFlags *flagsOut,
- void *displayLinkContext)
-{
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- MyNSOpenGLLayer* l = (MyNSOpenGLLayer*)displayLinkContext;
- pthread_mutex_lock(&l->renderLock);
- #ifdef DBG_PERF
- [l tick];
- #endif
- if(0 < l->swapInterval) {
- l->swapIntervalCounter++;
- if(l->swapIntervalCounter>=l->swapInterval) {
- l->swapIntervalCounter = 0;
- pthread_cond_signal(&l->renderSignal);
- SYNC_PRINT("S");
- }
- }
- pthread_mutex_unlock(&l->renderLock);
- [pool release];
- return kCVReturnSuccess;
-}
-
-#endif
-
- at implementation MyNSOpenGLLayer
-
-- (id) setupWithContext: (NSOpenGLContext*) _ctx
- pixelFormat: (NSOpenGLPixelFormat*) _fmt
- pbuffer: (NSOpenGLPixelBuffer*) p
- opaque: (Bool) opaque
- texWidth: (int) _texWidth
- texHeight: (int) _texHeight;
-{
- pthread_mutexattr_t renderLockAttr;
- pthread_mutexattr_init(&renderLockAttr);
- pthread_mutexattr_settype(&renderLockAttr, PTHREAD_MUTEX_RECURSIVE);
- pthread_mutex_init(&renderLock, &renderLockAttr); // recursive
- pthread_cond_init(&renderSignal, NULL); // no attribute
-
- textureID = 0;
- swapInterval = 1; // defaults to on (as w/ new GL profiles)
- swapIntervalCounter = 0;
- timespec_now(&lastWaitTime);
- shallDraw = NO;
- texWidth = _texWidth;
- texHeight = _texHeight;
- pbuffer = p;
- [pbuffer retain];
-
- {
- CGRect lRect = CGRectMake(0, 0, texWidth, texHeight);
- [self setFrame:lRect];
-
- // no animations for add/remove/swap sublayers etc
- // doesn't work: [self removeAnimationForKey: kCAOnOrderIn, kCAOnOrderOut, kCATransition]
- [self removeAllAnimations];
- }
-
- // instantiate a deactivated displayLink
-#ifdef HAS_CADisplayLink
- displayLink = [[CVDisplayLink displayLinkWithTarget:self selector:@selector(setNeedsDisplay)] retain];
- [displayLink setPaused: YES];
-#else
- CVReturn cvres;
- {
- int allDisplaysMask = 0;
- int virtualScreen, accelerated, displayMask;
- for (virtualScreen = 0; virtualScreen < [_fmt numberOfVirtualScreens]; virtualScreen++) {
- [_fmt getValues:&displayMask forAttribute:NSOpenGLPFAScreenMask forVirtualScreen:virtualScreen];
- [_fmt getValues:&accelerated forAttribute:NSOpenGLPFAAccelerated forVirtualScreen:virtualScreen];
- if (accelerated) {
- allDisplaysMask |= displayMask;
- }
- }
- cvres = CVDisplayLinkCreateWithOpenGLDisplayMask(allDisplaysMask, &displayLink);
- if(kCVReturnSuccess != cvres) {
- DBG_PRINT("MyNSOpenGLLayer::init %p, CVDisplayLinkCreateWithOpenGLDisplayMask %X failed: %d\n", self, allDisplaysMask, cvres);
- displayLink = NULL;
- }
- }
- if(NULL != displayLink) {
- cvres = CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(displayLink, [_ctx CGLContextObj], [_fmt CGLPixelFormatObj]);
- if(kCVReturnSuccess != cvres) {
- DBG_PRINT("MyNSOpenGLLayer::init %p, CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext failed: %d\n", self, cvres);
- displayLink = NULL;
- }
- }
- if(NULL != displayLink) {
- cvres = CVDisplayLinkSetOutputCallback(displayLink, renderMyNSOpenGLLayer, self);
- if(kCVReturnSuccess != cvres) {
- DBG_PRINT("MyNSOpenGLLayer::init %p, CVDisplayLinkSetOutputCallback failed: %d\n", self, cvres);
- displayLink = NULL;
- }
- }
- if(NULL != displayLink) {
- CVDisplayLinkStop(displayLink);
- }
-#endif
- [self setAsynchronous: YES];
-
- [self setNeedsDisplayOnBoundsChange: YES];
-
- [self setOpaque: opaque ? YES : NO];
-
- CGRect lRect = [self frame];
- DBG_PRINT("MyNSOpenGLLayer::init %p, ctx %p, pfmt %p, pbuffer %p, opaque %d, pbuffer %dx%d -> tex %dx%d, frame: %lf/%lf %lfx%lf (refcnt %d)\n",
- self, _ctx, _fmt, pbuffer, opaque, [pbuffer pixelsWide], [pbuffer pixelsHigh], texWidth, texHeight,
- lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height, (int)[self retainCount]);
- return self;
-}
-
-- (void)disableAnimation
-{
- DBG_PRINT("MyNSOpenGLLayer::disableAnimation: %p (refcnt %d) - displayLink %p\n", self, (int)[self retainCount], displayLink);
- pthread_mutex_lock(&renderLock);
- [self setAsynchronous: NO];
- if(NULL != displayLink) {
-#ifdef HAS_CADisplayLink
- [displayLink setPaused: YES];
- [displayLink release];
-#else
- CVDisplayLinkStop(displayLink);
- CVDisplayLinkRelease(displayLink);
-#endif
- displayLink = NULL;
- }
- pthread_mutex_unlock(&renderLock);
-}
-
-- (void)deallocTex
-{
- pthread_mutex_lock(&renderLock);
- NSOpenGLContext* context = [self openGLContext];
- DBG_PRINT("MyNSOpenGLLayer::deallocTex %p (refcnt %d) - context %p, pbuffer %p\n", self, (int)[self retainCount], context, pbuffer);
- if(NULL != pbuffer) {
- if(NULL!=context) {
- [context makeCurrentContext];
- if(0 != textureID) {
- glDeleteTextures(1, &textureID);
- textureID = 0;
- }
- [context clearDrawable];
- }
- [pbuffer release];
- pbuffer = NULL;
- }
- pthread_mutex_unlock(&renderLock);
-}
-
-- (void)releaseLayer
-{
- DBG_PRINT("MyNSOpenGLLayer::releaseLayer.0: %p (refcnt %d)\n", self, (int)[self retainCount]);
- pthread_mutex_lock(&renderLock);
- [self disableAnimation];
- [self deallocTex];
- [self release];
- DBG_PRINT("MyNSOpenGLLayer::releaseLayer.X: %p (refcnt %d)\n", self, (int)[self retainCount]);
- pthread_mutex_unlock(&renderLock);
-}
-
-- (void)dealloc
-{
- DBG_PRINT("MyNSOpenGLLayer::dealloc.0 %p (refcnt %d)\n", self, (int)[self retainCount]);
- // NSLog(@"MyNSOpenGLLayer::dealloc: %@",[NSThread callStackSymbols]);
-
- [self disableAnimation];
- [self deallocTex];
- pthread_cond_destroy(&renderSignal);
- pthread_mutex_destroy(&renderLock);
- [super dealloc];
- DBG_PRINT("MyNSOpenGLLayer::dealloc.X %p\n", self);
-}
-
-- (BOOL)canDrawInOpenGLContext:(NSOpenGLContext *)context pixelFormat:(NSOpenGLPixelFormat *)pixelFormat
- forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp
-{
- // assume both methods 'canDrawInOpenGLContext' and 'drawInOpenGLContext'
- // are called from the same thread subsequently
- pthread_mutex_lock(&renderLock);
- Bool res = NULL != pbuffer && YES == shallDraw;
- if(!res) {
- SYNC_PRINT("0");
- pthread_mutex_unlock(&renderLock);
- } else {
- SYNC_PRINT("1");
- }
- return res;
-}
-
-- (void)drawInOpenGLContext:(NSOpenGLContext *)context pixelFormat:(NSOpenGLPixelFormat *)pixelFormat
- forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp
-{
- [context makeCurrentContext];
-
- GLenum textureTarget = [pbuffer textureTarget];
- GLfloat texCoordWidth, texCoordHeight;
- {
- GLsizei pwidth = [pbuffer pixelsWide];
- GLsizei pheight = [pbuffer pixelsHigh];
- texCoordWidth = textureTarget == GL_TEXTURE_2D ? (GLfloat)pwidth /(GLfloat)texWidth : pwidth;
- texCoordHeight = textureTarget == GL_TEXTURE_2D ? (GLfloat)pheight/(GLfloat)texHeight : pheight;
- }
- Bool texCreated = 0 == textureID;
-
- if(texCreated) {
- glGenTextures(1, &textureID);
-
- CGRect lRect = [self frame];
- DBG_PRINT("MyNSOpenGLLayer::drawInOpenGLContext %p, pbuffer %p %dx%d -> tex %dx%d [%fx%f] id 0x%X target 0x%X, frame: %lf/%lf %lfx%lf (refcnt %d)\n",
- self, pbuffer, [pbuffer pixelsWide], [pbuffer pixelsHigh], texWidth, texHeight, texCoordWidth, texCoordHeight, textureID, textureTarget,
- lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height, (int)[self retainCount]);
- }
-
- glBindTexture(textureTarget, textureID);
-
- /**
- if(texCreated) {
- // proper tex size setup
- glTexImage2D(textureTarget, 0, GL_RGB, texWidth, texHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
- } */
-
- [context setTextureImageToPixelBuffer: pbuffer colorBuffer: GL_FRONT];
-
- glTexParameteri(textureTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(textureTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
- glEnable(textureTarget);
-
- static GLfloat verts[] = {
- -1.0, -1.0,
- -1.0, 1.0,
- 1.0, 1.0,
- 1.0, -1.0
- };
-
- GLfloat tex[] = {
- 0.0, 0.0,
- 0.0, texCoordHeight,
- texCoordWidth, texCoordHeight,
- texCoordWidth, 0.0
- };
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glVertexPointer(2, GL_FLOAT, 0, verts);
- glTexCoordPointer(2, GL_FLOAT, 0, tex);
-
- glDrawArrays(GL_QUADS, 0, 4);
-
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-
- glDisable(textureTarget);
- glBindTexture(textureTarget, 0);
-
- [super drawInOpenGLContext: context pixelFormat: pixelFormat forLayerTime: timeInterval displayTime: timeStamp];
- shallDraw = NO;
- if(0 >= swapInterval) {
- pthread_cond_signal(&renderSignal); // just to wake up
- SYNC_PRINT("s");
- }
- SYNC_PRINT("$");
- pthread_mutex_unlock(&renderLock);
-}
-
-- (int)getSwapInterval
-{
- return swapInterval;
-}
-
-- (void)setSwapInterval:(int)interval
-{
- /**
- * v-sync doesn't works w/ NSOpenGLLayer's context .. well :(
- * Using CVDisplayLink .. see setSwapInterval() below.
- *
- GLint si;
- [context getValues: &si forParameter: NSOpenGLCPSwapInterval];
- if(si != swapInterval) {
- DBG_PRINT("MyNSOpenGLLayer::drawInOpenGLContext %p setSwapInterval: %d -> %d\n", self, si, swapInterval);
- [context setValues: &swapInterval forParameter: NSOpenGLCPSwapInterval];
- }
- } */
-
- pthread_mutex_lock(&renderLock);
- DBG_PRINT("MyNSOpenGLLayer::setSwapInterval.0: %d - displayLink %p\n", interval, displayLink);
- swapInterval = interval;
- swapIntervalCounter = 0;
- pthread_mutex_unlock(&renderLock);
-
- if(NULL!=displayLink) {
- if(0 < swapInterval) {
- tc = 0;
- timespec_now(&t0);
-
- [self setAsynchronous: NO];
- #ifdef HAS_CADisplayLink
- [displayLink setPaused: NO];
- [displayLink setFrameInterval: interval];
- #else
- DBG_PRINT("MyNSOpenGLLayer::setSwapInterval.1.b.1\n");
- CVDisplayLinkStart(displayLink);
- DBG_PRINT("MyNSOpenGLLayer::setSwapInterval.1.b.X\n");
- #endif
- } else {
- #ifdef HAS_CADisplayLink
- [displayLink setPaused: YES];
- #else
- DBG_PRINT("MyNSOpenGLLayer::setSwapInterval.0.b.1\n");
- CVDisplayLinkStop(displayLink);
- DBG_PRINT("MyNSOpenGLLayer::setSwapInterval.0.b.X\n");
- #endif
- [self setAsynchronous: YES];
- }
- }
- DBG_PRINT("MyNSOpenGLLayer::setSwapInterval.X: %d\n", interval);
-}
-
--(void)tick
-{
- tc++;
- if(tc%60==0) {
- struct timespec t1, td;
- timespec_now(&t1);
- timespec_subtract(&td, &t1, &t0);
- long td_ms = timespec_milliseconds(&td);
- fprintf(stderr, "NSOpenGLLayer: %ld ms / %d frames, %ld ms / frame, %f fps\n",
- td_ms, tc, td_ms/tc, (tc * 1000.0) / (float)td_ms );
- fflush(NULL);
- }
-}
-
- at end
-
-NSOpenGLLayer* createNSOpenGLLayer(NSOpenGLContext* ctx, NSOpenGLPixelFormat* fmt, NSOpenGLPixelBuffer* p, Bool opaque, int texWidth, int texHeight) {
- // This simply crashes after dealloc() has been called .. ie. ref-count -> 0 too early ?
- // However using alloc/init, actual dealloc happens at JAWT destruction, hence too later IMHO.
- // return [[MyNSOpenGLLayer layer] setupWithContext:ctx pixelFormat: fmt pbuffer: p opaque: opaque texWidth: texWidth texHeight: texHeight];
-
- return [[[MyNSOpenGLLayer alloc] init] setupWithContext:ctx pixelFormat: fmt pbuffer: p opaque: opaque texWidth: texWidth texHeight: texHeight];
-}
-
-void setNSOpenGLLayerSwapInterval(NSOpenGLLayer* layer, int interval) {
- MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
- [l setSwapInterval: interval];
-}
-
-void waitUntilNSOpenGLLayerIsReady(NSOpenGLLayer* layer, long to_micros) {
- MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
- BOOL ready = NO;
- int wr = 0;
- pthread_mutex_lock(&l->renderLock);
- SYNC_PRINT("{");
- do {
- if([l getSwapInterval] <= 0) {
- ready = !l->shallDraw;
- }
- if(NO == ready) {
- if(0 < to_micros) {
- #ifdef DBG_SYNC
- struct timespec t0, t1, td, td2;
- timespec_now(&t0);
- #endif
- struct timespec to_abs = l->lastWaitTime;
- timespec_addmicros(&to_abs, to_micros);
- #ifdef DBG_SYNC
- timespec_subtract(&td, &to_abs, &t0);
- fprintf(stderr, "(%ld) / ", timespec_milliseconds(&td));
- #endif
- wr = pthread_cond_timedwait(&l->renderSignal, &l->renderLock, &to_abs);
- #ifdef DBG_SYNC
- timespec_now(&t1);
- timespec_subtract(&td, &t1, &t0);
- timespec_subtract(&td2, &t1, &l->lastWaitTime);
- fprintf(stderr, "(%ld) / (%ld) ms", timespec_milliseconds(&td), timespec_milliseconds(&td2));
- #endif
- } else {
- pthread_cond_wait (&l->renderSignal, &l->renderLock);
- }
- ready = !l->shallDraw;
- }
- } while (NO == ready && 0 == wr) ;
- SYNC_PRINT("-%d}", ready);
- timespec_now(&l->lastWaitTime);
- pthread_mutex_unlock(&l->renderLock);
-}
-
-void setNSOpenGLLayerNeedsDisplay(NSOpenGLLayer* layer) {
- MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- pthread_mutex_lock(&l->renderLock);
- l->shallDraw = YES;
- if ( [NSThread isMainThread] == YES ) {
- [l setNeedsDisplay];
- } else {
- // can't wait, otherwise we may deadlock AWT
- [l performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:NO];
- }
- SYNC_PRINT(".");
- pthread_mutex_unlock(&l->renderLock);
- // DBG_PRINT("MyNSOpenGLLayer::setNSOpenGLLayerNeedsDisplay %p\n", l);
- [pool release];
-}
-
-void releaseNSOpenGLLayer(NSOpenGLLayer* layer) {
- MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- DBG_PRINT("MyNSOpenGLLayer::releaseNSOpenGLLayer.0: %p\n", l);
-
- if ( [NSThread isMainThread] == YES ) {
- [l releaseLayer];
- } else {
- [l performSelectorOnMainThread:@selector(releaseLayer) withObject:nil waitUntilDone:NO];
- }
-
- DBG_PRINT("MyNSOpenGLLayer::releaseNSOpenGLLayer.X: %p\n", l);
- [pool release];
-}
-
diff --git a/src/jogl/native/macosx/MacOSXWindowSystemInterface.m b/src/jogl/native/macosx/MacOSXWindowSystemInterface.m
index f774f8f..48807ee 100644
--- a/src/jogl/native/macosx/MacOSXWindowSystemInterface.m
+++ b/src/jogl/native/macosx/MacOSXWindowSystemInterface.m
@@ -446,7 +446,7 @@ NSOpenGLPixelFormat* createPixelFormat(int* iattrs, int niattrs, int* ivalues) {
NSOpenGLPixelFormat* fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
// if(fmt == nil) { fallback to a [NSOpenGLView defaultPixelFormat] crashed (SIGSEGV) on 10.6.7/NV }
- DBG_PRINT("createPixelFormat.X: pfmt %p\n", fmt);
+ DBG_PRINT("\ncreatePixelFormat.X: pfmt %p\n", fmt);
[pool release];
return fmt;
@@ -503,7 +503,7 @@ NSView* getNSView(NSOpenGLContext* ctx) {
NSOpenGLContext* createContext(NSOpenGLContext* share,
NSView* view,
- Bool allowIncompleteView,
+ Bool incompleteView,
NSOpenGLPixelFormat* fmt,
Bool opaque,
int* viewNotReady)
@@ -512,13 +512,13 @@ NSOpenGLContext* createContext(NSOpenGLContext* share,
getRendererInfo();
- DBG_PRINT("createContext.0: share %p, view %p, allowIncompleteView %d, pixfmt %p, opaque %d\n",
- share, view, (int)allowIncompleteView, fmt, opaque);
+ DBG_PRINT("createContext.0: share %p, view %p, incompleteView %d, pixfmt %p, opaque %d\n",
+ share, view, (int)incompleteView, fmt, opaque);
if (view != nil) {
Bool viewReady = true;
- if(!allowIncompleteView) {
+ if(!incompleteView) {
if ([view lockFocusIfCanDraw] == NO) {
DBG_PRINT("createContext.1 [view lockFocusIfCanDraw] failed\n");
viewReady = false;
@@ -527,7 +527,7 @@ NSOpenGLContext* createContext(NSOpenGLContext* share,
if(viewReady) {
NSRect frame = [view frame];
if ((frame.size.width == 0) || (frame.size.height == 0)) {
- if(!allowIncompleteView) {
+ if(!incompleteView) {
[view unlockFocus];
}
DBG_PRINT("createContext.2 view.frame size %dx%d\n", (int)frame.size.width, (int)frame.size.height);
@@ -557,8 +557,10 @@ NSOpenGLContext* createContext(NSOpenGLContext* share,
GLint zeroOpacity = 0;
[ctx setValues:&zeroOpacity forParameter:NSOpenGLCPSurfaceOpacity];
}
- [ctx setView:view];
- if(!allowIncompleteView) {
+ if(!incompleteView) {
+ DBG_PRINT("createContext.3.0: setView\n");
+ [ctx setView:view];
+ DBG_PRINT("createContext.3.X: setView\n");
[view unlockFocus];
}
}
@@ -628,7 +630,12 @@ void setContextOpacity(NSOpenGLContext* ctx, int opacity) {
void updateContext(NSOpenGLContext* ctx) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- [ctx update];
+ NSView *nsView = [ctx view];
+ if(NULL != nsView) {
+ DBG_PRINT("updateContext.0: ctx %p, ctx.view %p\n", ctx, nsView);
+ [ctx update];
+ DBG_PRINT("updateContext.X\n");
+ }
[pool release];
}
@@ -638,7 +645,10 @@ void copyContext(NSOpenGLContext* dest, NSOpenGLContext* src, int mask) {
void* updateContextRegister(NSOpenGLContext* ctx, NSView* view) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+
+ DBG_PRINT("updateContextRegister.0: ctx %p, view %p\n", ctx, view);
ContextUpdater *contextUpdater = [[ContextUpdater alloc] initWithContext: ctx view: view];
+ DBG_PRINT("updateContextRegister.X: ctxupd %p\n", contextUpdater);
[pool release];
return contextUpdater;
}
@@ -658,44 +668,62 @@ void updateContextUnregister(void* updater) {
ContextUpdater *contextUpdater = (ContextUpdater *)updater;
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ DBG_PRINT("updateContextUnregister.0: ctxupd %p\n", contextUpdater);
[contextUpdater release];
+ DBG_PRINT("updateContextUnregister.X\n");
[pool release];
}
NSOpenGLPixelBuffer* createPBuffer(int renderTarget, int internalFormat, int width, int height) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ DBG_PRINT("createPBuffer.0: renderTarget 0x%x, ifmt 0x%x, %dx%d: \n", renderTarget, internalFormat, width, height);
NSOpenGLPixelBuffer* pBuffer = [[NSOpenGLPixelBuffer alloc]
initWithTextureTarget:renderTarget
textureInternalFormat:internalFormat
textureMaxMipMapLevel:0
pixelsWide:width
pixelsHigh:height];
+ DBG_PRINT("createPBuffer.X: res %p\n", pBuffer);
[pool release];
return pBuffer;
}
Bool destroyPBuffer(NSOpenGLPixelBuffer* pBuffer) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ DBG_PRINT("destroyPBuffer.0: pbuffer %p\n", pBuffer);
[pBuffer release];
+ DBG_PRINT("destroyPBuffer.X\n");
[pool release];
return true;
}
void setContextPBuffer(NSOpenGLContext* ctx, NSOpenGLPixelBuffer* pBuffer) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ DBG_PRINT("setContextPBuffer.0: ctx %p, pbuffer %p\n", ctx, pBuffer);
[ctx setPixelBuffer: pBuffer
cubeMapFace: 0
mipMapLevel: 0
currentVirtualScreen: [ctx currentVirtualScreen]];
+ DBG_PRINT("setContextPBuffer.X\n");
[pool release];
}
void setContextTextureImageToPBuffer(NSOpenGLContext* ctx, NSOpenGLPixelBuffer* pBuffer, GLenum colorBuffer) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ DBG_PRINT("setContextTextureImageToPBuffer.0: ctx %p, pbuffer %p, colorBuffer 0x%x\n", ctx, pBuffer, (int)colorBuffer);
[ctx setTextureImageToPixelBuffer: pBuffer colorBuffer: colorBuffer];
+ DBG_PRINT("setContextTextureImageToPBuffer.X\n");
[pool release];
}
+Bool isNSOpenGLPixelBuffer(uint64_t object) {
+ NSObject *nsObj = (NSObject*) (intptr_t) object;
+ DBG_PRINT("isNSOpenGLPixelBuffer.0: obj %p\n", object);
+ Bool res = [nsObj isMemberOfClass:[NSOpenGLPixelBuffer class]];
+ DBG_PRINT("isNSOpenGLPixelBuffer.X: res %d\n", (int)res);
+ return res;
+}
+
#include <mach-o/dyld.h>
Bool imagesInitialized = false;
static char libGLStr[] = "/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib";
@@ -746,38 +774,3 @@ void resetGammaRamp() {
CGDisplayRestoreColorSyncSettings();
}
-/***
- * The following static functions are copied out of NEWT's OSX impl. <src/newt/native/MacWindow.m>
- * May need to push code to NativeWindow, to remove duplication.
- */
-static NSScreen * NewtScreen_getNSScreenByIndex(int screen_idx) {
- NSArray *screens = [NSScreen screens];
- if(screen_idx<0) screen_idx=0;
- if(screen_idx>=[screens count]) screen_idx=0;
- return (NSScreen *) [screens objectAtIndex: screen_idx];
-}
-static CGDirectDisplayID NewtScreen_getCGDirectDisplayIDByNSScreen(NSScreen *screen) {
- // Mind: typedef uint32_t CGDirectDisplayID; - however, we assume it's 64bit on 64bit ?!
- NSDictionary * dict = [screen deviceDescription];
- NSNumber * val = (NSNumber *) [dict objectForKey: @"NSScreenNumber"];
- // [NSNumber integerValue] returns NSInteger which is 32 or 64 bit native size
- return (CGDirectDisplayID) [val integerValue];
-}
-static long GetDictionaryLong(CFDictionaryRef theDict, const void* key)
-{
- long value = 0;
- CFNumberRef numRef;
- numRef = (CFNumberRef)CFDictionaryGetValue(theDict, key);
- if (numRef != NULL)
- CFNumberGetValue(numRef, kCFNumberLongType, &value);
- return value;
-}
-#define CGDDGetModeRefreshRate(mode) GetDictionaryLong((mode), kCGDisplayRefreshRate)
-
-int getScreenRefreshRate(int scrn_idx) {
- NSScreen *screen = NewtScreen_getNSScreenByIndex(scrn_idx);
- CGDirectDisplayID display = NewtScreen_getCGDirectDisplayIDByNSScreen(screen);
- CFDictionaryRef mode = CGDisplayCurrentMode(display);
- return CGDDGetModeRefreshRate(mode);
-}
-
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/DelegatedUpstreamSurfaceHookMutableSize.java b/src/nativewindow/classes/com/jogamp/nativewindow/DelegatedUpstreamSurfaceHookMutableSize.java
new file mode 100644
index 0000000..22c95f3
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/DelegatedUpstreamSurfaceHookMutableSize.java
@@ -0,0 +1,39 @@
+package com.jogamp.nativewindow;
+
+import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
+
+public class DelegatedUpstreamSurfaceHookMutableSize extends UpstreamSurfaceHookMutableSize {
+ final UpstreamSurfaceHook upstream;
+
+ /**
+ * @param upstream optional upstream UpstreamSurfaceHook used for {@link #create(ProxySurface)} and {@link #destroy(ProxySurface)}.
+ * @param width initial width
+ * @param height initial height
+ */
+ public DelegatedUpstreamSurfaceHookMutableSize(UpstreamSurfaceHook upstream, int width, int height) {
+ super(width, height);
+ this.upstream = upstream;
+ }
+
+ @Override
+ public final void create(ProxySurface s) {
+ if(null != upstream) {
+ upstream.create(s);
+ }
+ }
+
+ @Override
+ public final void destroy(ProxySurface s) {
+ if(null != upstream) {
+ upstream.destroy(s);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName()+"[ "+ width + "x" + height + ", " + upstream + "]";
+ }
+
+}
+
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/DelegatedUpstreamSurfaceHookWithSurfaceSize.java b/src/nativewindow/classes/com/jogamp/nativewindow/DelegatedUpstreamSurfaceHookWithSurfaceSize.java
new file mode 100644
index 0000000..85e2458
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/DelegatedUpstreamSurfaceHookWithSurfaceSize.java
@@ -0,0 +1,54 @@
+package com.jogamp.nativewindow;
+
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
+
+public class DelegatedUpstreamSurfaceHookWithSurfaceSize implements UpstreamSurfaceHook {
+ final UpstreamSurfaceHook upstream;
+ final NativeSurface surface;
+
+ /**
+ * @param upstream optional upstream UpstreamSurfaceHook used for {@link #create(ProxySurface)} and {@link #destroy(ProxySurface)}.
+ * @param surface mandatory {@link NativeSurface} used for {@link #getWidth(ProxySurface)} and {@link #getHeight(ProxySurface)}
+ */
+ public DelegatedUpstreamSurfaceHookWithSurfaceSize(UpstreamSurfaceHook upstream, NativeSurface surface) {
+ this.upstream = upstream;
+ this.surface = surface;
+ if(null == surface) {
+ throw new IllegalArgumentException("given surface is null");
+ }
+ }
+
+ @Override
+ public final void create(ProxySurface s) {
+ if(null != upstream) {
+ upstream.create(s);
+ }
+ }
+
+ @Override
+ public final void destroy(ProxySurface s) {
+ if(null != upstream) {
+ upstream.destroy(s);
+ }
+ }
+
+ @Override
+ public final int getWidth(ProxySurface s) {
+ return surface.getWidth();
+ }
+
+ @Override
+ public final int getHeight(ProxySurface s) {
+ return surface.getHeight();
+ }
+
+ @Override
+ public String toString() {
+ final String us_s = null != surface ? ( surface.getClass().getName() + ": 0x" + Long.toHexString(surface.getSurfaceHandle()) + " " +surface.getWidth() + "x" + surface.getHeight() ) : "nil";
+ return getClass().getSimpleName()+"["+upstream+", "+us_s+"]";
+ }
+
+}
+
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/UpstreamSurfaceHookMutableSize.java b/src/nativewindow/classes/com/jogamp/nativewindow/UpstreamSurfaceHookMutableSize.java
new file mode 100644
index 0000000..29c540a
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/UpstreamSurfaceHookMutableSize.java
@@ -0,0 +1,45 @@
+package com.jogamp.nativewindow;
+
+import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
+
+public class UpstreamSurfaceHookMutableSize implements UpstreamSurfaceHook.MutableSize {
+ int width, height;
+
+ /**
+ * @param width initial width
+ * @param height initial height
+ */
+ public UpstreamSurfaceHookMutableSize(int width, int height) {
+ this.width = width;
+ this.height = height;
+ }
+
+ @Override
+ public final void setSize(int width, int height) {
+ this.width = width;
+ this.height = height;
+ }
+
+ @Override
+ public final int getWidth(ProxySurface s) {
+ return width;
+ }
+
+ @Override
+ public final int getHeight(ProxySurface s) {
+ return height;
+ }
+ @Override
+ public void create(ProxySurface s) { /* nop */ }
+
+ @Override
+ public void destroy(ProxySurface s) { /* nop */ }
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName()+"[ "+ width + "x" + height + "]";
+ }
+
+}
+
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java b/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java
index d4b927c..a62d08c 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java
@@ -39,12 +39,14 @@ package com.jogamp.nativewindow.awt;
import com.jogamp.common.util.locks.LockFactory;
import com.jogamp.common.util.locks.RecursiveLock;
+import com.jogamp.nativewindow.MutableGraphicsConfiguration;
import java.awt.Component;
import java.awt.Container;
import java.applet.Applet;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.CapabilitiesImmutable;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.NativeWindow;
import javax.media.nativewindow.NativeWindowException;
@@ -110,21 +112,6 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
this.offscreenSurfaceLayer = 0;
}
- @Override
- public void setShallUseOffscreenLayer(boolean v) {
- shallUseOffscreenLayer = v;
- }
-
- @Override
- public final boolean getShallUseOffscreenLayer() {
- return shallUseOffscreenLayer;
- }
-
- @Override
- public final boolean isOffscreenLayerSurfaceEnabled() {
- return isOffscreenLayerSurface;
- }
-
protected synchronized void invalidate() {
invalidateNative();
jawt = null;
@@ -136,26 +123,29 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
}
protected abstract void invalidateNative();
- protected final void updateBounds(JAWT_Rectangle jawtBounds) {
- if(DEBUG) {
- final Rectangle jb = new Rectangle(jawtBounds.getX(), jawtBounds.getY(), jawtBounds.getWidth(), jawtBounds.getHeight());
- if(!bounds.equals(jb)) {
+ protected final boolean updateBounds(JAWT_Rectangle jawtBounds) {
+ final Rectangle jb = new Rectangle(jawtBounds.getX(), jawtBounds.getY(), jawtBounds.getWidth(), jawtBounds.getHeight());
+ final boolean changed = !bounds.equals(jb);
+
+ if(changed) {
+ if(DEBUG) {
System.err.println("JAWTWindow.updateBounds: "+bounds+" -> "+jb);
Thread.dumpStack();
}
+ bounds.setX(jawtBounds.getX());
+ bounds.setY(jawtBounds.getY());
+ bounds.setWidth(jawtBounds.getWidth());
+ bounds.setHeight(jawtBounds.getHeight());
+
+ if(component instanceof Container) {
+ java.awt.Insets contInsets = ((Container)component).getInsets();
+ insets.setLeftWidth(contInsets.left);
+ insets.setRightWidth(contInsets.right);
+ insets.setTopHeight(contInsets.top);
+ insets.setBottomHeight(contInsets.bottom);
+ }
}
- bounds.setX(jawtBounds.getX());
- bounds.setY(jawtBounds.getY());
- bounds.setWidth(jawtBounds.getWidth());
- bounds.setHeight(jawtBounds.getHeight());
-
- if(component instanceof Container) {
- java.awt.Insets contInsets = ((Container)component).getInsets();
- insets.setLeftWidth(contInsets.left);
- insets.setRightWidth(contInsets.right);
- insets.setTopHeight(contInsets.top);
- insets.setBottomHeight(contInsets.bottom);
- }
+ return changed;
}
/** @return the JAWT_DrawingSurfaceInfo's (JAWT_Rectangle) bounds, updated with lock */
@@ -181,9 +171,29 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
return jawt;
}
- /**
- * {@inheritDoc}
- */
+ //
+ // OffscreenLayerOption
+ //
+
+ @Override
+ public void setShallUseOffscreenLayer(boolean v) {
+ shallUseOffscreenLayer = v;
+ }
+
+ @Override
+ public final boolean getShallUseOffscreenLayer() {
+ return shallUseOffscreenLayer;
+ }
+
+ @Override
+ public final boolean isOffscreenLayerSurfaceEnabled() {
+ return isOffscreenLayerSurface;
+ }
+
+ //
+ // OffscreenLayerSurface
+ //
+
@Override
public final void attachSurfaceLayer(final long layerHandle) throws NativeWindowException {
if( !isOffscreenLayerSurfaceEnabled() ) {
@@ -205,9 +215,6 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
}
protected abstract void attachSurfaceLayerImpl(final long layerHandle);
- /**
- * {@inheritDoc}
- */
@Override
public final void detachSurfaceLayer() throws NativeWindowException {
if( !isOffscreenLayerSurfaceEnabled() ) {
@@ -232,11 +239,21 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
}
protected abstract void detachSurfaceLayerImpl(final long layerHandle);
+ protected final long getAttachedSurfaceLayer() {
+ return offscreenSurfaceLayer;
+ }
+
@Override
public final boolean isSurfaceLayerAttached() {
return 0 != offscreenSurfaceLayer;
}
+ @Override
+ public final void setChosenCapabilities(CapabilitiesImmutable caps) {
+ ((MutableGraphicsConfiguration)getGraphicsConfiguration()).setChosenCapabilities(caps);
+ getPrivateGraphicsConfiguration().setChosenCapabilities(caps);
+ }
+
//
// SurfaceUpdateListener
//
@@ -381,7 +398,7 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
public final AbstractGraphicsConfiguration getGraphicsConfiguration() {
return config.getNativeGraphicsConfiguration();
}
-
+
@Override
public final long getDisplayHandle() {
return getGraphicsConfiguration().getScreen().getDevice().getHandle();
@@ -393,13 +410,13 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
}
@Override
- public int getWidth() {
+ public final int getWidth() {
return component.getWidth();
}
@Override
- public int getHeight() {
- return component.getHeight();
+ public final int getHeight() {
+ return component.getHeight();
}
//
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java b/src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java
index 389949e..b824350 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java
@@ -37,7 +37,7 @@ import javax.media.nativewindow.*;
/** Encapsulates a graphics device on EGL platforms.
*/
public class EGLGraphicsDevice extends DefaultGraphicsDevice implements Cloneable {
- final long nativeDisplayID;
+ final long[] nativeDisplayID = new long[1];
final EGLDisplayLifecycleCallback eglLifecycleCallback;
/**
@@ -51,9 +51,10 @@ public class EGLGraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
/**
* Implementation should issue an <code>EGL.eglGetDisplay(nativeDisplayID)</code>
* inclusive <code>EGL.eglInitialize(eglDisplayHandle, ..)</code> call.
- * @param eglDisplayHandle
+ * @param nativeDisplayID in/out array of size 1, passing the requested nativeVisualID, may return a different revised nativeVisualID handle
+ * @return the initialized EGL display ID, or <code>0</code> if not successful
*/
- public long eglGetAndInitDisplay(long nativeDisplayID);
+ public long eglGetAndInitDisplay(long[] nativeDisplayID);
/**
* Implementation should issue an <code>EGL.eglTerminate(eglDisplayHandle)</code> call.
@@ -66,19 +67,19 @@ public class EGLGraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
* Note that this is not an open connection, ie no native display handle exist.
* This constructor exist to setup a default device connection/unit.<br>
*/
- public EGLGraphicsDevice(String connection, int unitID) {
- super(NativeWindowFactory.TYPE_EGL, connection, unitID);
- this.nativeDisplayID = 0 ; // EGL.EGL_DEFAULT_DISPLAY
+ public EGLGraphicsDevice() {
+ super(NativeWindowFactory.TYPE_EGL, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
+ this.nativeDisplayID[0] = 0 ; // EGL.EGL_DEFAULT_DISPLAY
this.eglLifecycleCallback = null;
}
public EGLGraphicsDevice(long nativeDisplayID, long eglDisplay, String connection, int unitID, EGLDisplayLifecycleCallback eglLifecycleCallback) {
super(NativeWindowFactory.TYPE_EGL, connection, unitID, eglDisplay);
- this.nativeDisplayID = nativeDisplayID;
+ this.nativeDisplayID[0] = nativeDisplayID;
this.eglLifecycleCallback = eglLifecycleCallback;
}
- public long getNativeDisplayID() { return nativeDisplayID; }
+ public long getNativeDisplayID() { return nativeDisplayID[0]; }
@Override
public Object clone() {
@@ -113,7 +114,7 @@ public class EGLGraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
@Override
public String toString() {
- return "EGLGraphicsDevice[type EGL, connection "+getConnection()+", unitID "+getUnitID()+", handle 0x"+Long.toHexString(getHandle())+", nativeDisplayID 0x"+Long.toHexString(nativeDisplayID)+"]";
+ return "EGLGraphicsDevice[type EGL, connection "+getConnection()+", unitID "+getUnitID()+", handle 0x"+Long.toHexString(getHandle())+", nativeDisplayID 0x"+Long.toHexString(nativeDisplayID[0])+", eglLifecycleCallback "+(null != eglLifecycleCallback)+"]";
}
}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java b/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java
index ba07d97..7be747f 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java
@@ -83,7 +83,9 @@ public class SWTAccessor {
static {
Field f = null;
- if(NativeWindowFactory.TYPE_MACOSX != NativeWindowFactory.getNativeWindowType(false) ) {
+ final String nwt = NativeWindowFactory.getNativeWindowType(false);
+
+ if(NativeWindowFactory.TYPE_MACOSX != nwt ) {
try {
f = Control.class.getField(str_handle);
} catch (Exception ex) {
@@ -124,7 +126,7 @@ public class SWTAccessor {
Class<?> c=null;
Method m1=null, m2=null, m3=null, m4=null, m5=null;
Class<?> handleType = swt_uses_long_handles ? long.class : int.class ;
- if( NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(false) ) {
+ if( NativeWindowFactory.TYPE_X11 == nwt ) {
try {
c = ReflectionUtil.getClass(str_OS_gtk_class, false, SWTAccessor.class.getClassLoader());
m1 = c.getDeclaredMethod(str_gtk_widget_realize, handleType);
@@ -208,35 +210,38 @@ public class SWTAccessor {
if( null != OS_gtk_class ) {
long widgedHandle = callStaticMethodL2L(OS_GTK_WIDGET_WINDOW, handle);
long displayHandle = callStaticMethodL2L(OS_gdk_x11_drawable_get_xdisplay, widgedHandle);
- return new X11GraphicsDevice(displayHandle, AbstractGraphicsDevice.DEFAULT_UNIT, false);
+ return new X11GraphicsDevice(displayHandle, AbstractGraphicsDevice.DEFAULT_UNIT, false /* owner */);
}
- if( NativeWindowFactory.TYPE_WINDOWS == NativeWindowFactory.getNativeWindowType(false) ) {
+ final String nwt = NativeWindowFactory.getNativeWindowType(false);
+ if( NativeWindowFactory.TYPE_WINDOWS == nwt ) {
return new WindowsGraphicsDevice(AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
}
- if( NativeWindowFactory.TYPE_MACOSX == NativeWindowFactory.getNativeWindowType(false) ) {
+ if( NativeWindowFactory.TYPE_MACOSX == nwt ) {
return new MacOSXGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT);
}
- throw new UnsupportedOperationException("n/a for this windowing system: "+NativeWindowFactory.getNativeWindowType(false));
+ throw new UnsupportedOperationException("n/a for this windowing system: "+nwt);
}
public static AbstractGraphicsScreen getScreen(AbstractGraphicsDevice device, int screen) {
if( null != OS_gtk_class ) {
return new X11GraphicsScreen((X11GraphicsDevice)device, screen);
- }
- if( NativeWindowFactory.TYPE_WINDOWS == NativeWindowFactory.getNativeWindowType(false) ||
- NativeWindowFactory.TYPE_MACOSX == NativeWindowFactory.getNativeWindowType(false) ) {
+ }
+ final String nwt = NativeWindowFactory.getNativeWindowType(false);
+ if( NativeWindowFactory.TYPE_WINDOWS == nwt ||
+ NativeWindowFactory.TYPE_MACOSX == nwt ) {
return new DefaultGraphicsScreen(device, screen);
}
- throw new UnsupportedOperationException("n/a for this windowing system: "+NativeWindowFactory.getNativeWindowType(false));
+ throw new UnsupportedOperationException("n/a for this windowing system: "+nwt);
}
public static int getNativeVisualID(AbstractGraphicsDevice device, long windowHandle) {
if( null != OS_gtk_class ) {
return X11Lib.GetVisualIDFromWindow(device.getHandle(), windowHandle);
}
- if( NativeWindowFactory.TYPE_WINDOWS == NativeWindowFactory.getNativeWindowType(false) ||
- NativeWindowFactory.TYPE_MACOSX == NativeWindowFactory.getNativeWindowType(false) ) {
+ final String nwt = NativeWindowFactory.getNativeWindowType(false);
+ if( NativeWindowFactory.TYPE_WINDOWS == nwt ||
+ NativeWindowFactory.TYPE_MACOSX == nwt ) {
return VisualIDHolder.VID_UNDEFINED;
}
- throw new UnsupportedOperationException("n/a for this windowing system: "+NativeWindowFactory.getNativeWindowType(false));
+ throw new UnsupportedOperationException("n/a for this windowing system: "+nwt);
}
public static long getWindowHandle(Control swtControl) {
@@ -245,11 +250,12 @@ public class SWTAccessor {
long widgedHandle = callStaticMethodL2L(OS_GTK_WIDGET_WINDOW, handle);
return callStaticMethodL2L(OS_gdk_x11_drawable_get_xid, widgedHandle);
}
- if( NativeWindowFactory.TYPE_WINDOWS == NativeWindowFactory.getNativeWindowType(false) ||
- NativeWindowFactory.TYPE_MACOSX == NativeWindowFactory.getNativeWindowType(false) ) {
+ final String nwt = NativeWindowFactory.getNativeWindowType(false);
+ if( NativeWindowFactory.TYPE_WINDOWS == nwt ||
+ NativeWindowFactory.TYPE_MACOSX == nwt ) {
return handle;
}
- throw new UnsupportedOperationException("n/a for this windowing system: "+NativeWindowFactory.getNativeWindowType(false));
+ throw new UnsupportedOperationException("n/a for this windowing system: "+nwt);
}
public static long newGC(final Control swtControl, final GCData gcData) {
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java b/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java
index 5e4d6f4..0f28ca6 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java
@@ -46,6 +46,7 @@ import javax.media.nativewindow.ToolkitLock;
public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneable {
final boolean handleOwner;
+ final boolean isXineramaEnabled;
/** Constructs a new X11GraphicsDevice corresponding to the given connection and default
* {@link javax.media.nativewindow.ToolkitLock} via {@link NativeWindowFactory#getDefaultToolkitLock(String)}.<br>
@@ -56,10 +57,11 @@ public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
public X11GraphicsDevice(String connection, int unitID) {
super(NativeWindowFactory.TYPE_X11, connection, unitID);
handleOwner = false;
+ isXineramaEnabled = false;
}
/** Constructs a new X11GraphicsDevice corresponding to the given native display handle and default
- * {@link javax.media.nativewindow.ToolkitLock} via {@link NativeWindowFactory#createDefaultToolkitLock(String, long)}.
+ * {@link javax.media.nativewindow.ToolkitLock} via {@link NativeWindowFactory#getDefaultToolkitLock(String, long)}.
* @see DefaultGraphicsDevice#DefaultGraphicsDevice(String, String, int, long)
*/
public X11GraphicsDevice(long display, int unitID, boolean owner) {
@@ -69,11 +71,12 @@ public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
throw new NativeWindowException("null display");
}
handleOwner = owner;
+ isXineramaEnabled = X11Util.XineramaIsEnabled(this);
}
/**
* @param display the Display connection
- * @param locker custom {@link javax.media.nativewindow.ToolkitLock}, eg to force null locking in NEWT
+ * @param locker custom {@link javax.media.nativewindow.ToolkitLock}, eg to force null locking w/ private connection
* @see DefaultGraphicsDevice#DefaultGraphicsDevice(String, String, int, long, ToolkitLock)
*/
public X11GraphicsDevice(long display, int unitID, ToolkitLock locker, boolean owner) {
@@ -82,13 +85,42 @@ public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
throw new NativeWindowException("null display");
}
handleOwner = owner;
+ isXineramaEnabled = X11Util.XineramaIsEnabled(this);
}
+
+ private static int getDefaultScreenImpl(long dpy) {
+ return X11Lib.DefaultScreen(dpy);
+ }
+
+ /**
+ * Returns the default screen number as referenced by the display connection, i.e. 'somewhere:0.1' -> 1
+ * <p>
+ * Implementation uses the XLib macro <code>DefaultScreen(display)</code>.
+ * </p>
+ */
+ public int getDefaultScreen() {
+ final long display = getHandle();
+ if(0==display) {
+ throw new NativeWindowException("null display");
+ }
+ final int ds = getDefaultScreenImpl(display);
+ if(DEBUG) {
+ System.err.println(Thread.currentThread().getName() + " - X11GraphicsDevice.getDefaultDisplay() of "+this+": "+ds+", count "+X11Lib.ScreenCount(display));
+ }
+ return ds;
+ }
+
public int getDefaultVisualID() {
- // It still could be an AWT hold handle ..
final long display = getHandle();
- final int scrnIdx = X11Lib.DefaultScreen(display);
- return X11Lib.DefaultVisualID(display, scrnIdx);
+ if(0==display) {
+ throw new NativeWindowException("null display");
+ }
+ return X11Lib.DefaultVisualID(display, getDefaultScreenImpl(display));
+ }
+
+ public final boolean isXineramaEnabled() {
+ return isXineramaEnabled;
}
@Override
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsScreen.java b/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsScreen.java
index 5f3c220..2ec6629 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsScreen.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsScreen.java
@@ -33,10 +33,12 @@
package com.jogamp.nativewindow.x11;
-import javax.media.nativewindow.*;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.DefaultGraphicsScreen;
+import javax.media.nativewindow.NativeWindowException;
import jogamp.nativewindow.x11.X11Lib;
-import jogamp.nativewindow.x11.X11Util;
/** Encapsulates a screen index on X11
platforms. Objects of this type are passed to {@link
@@ -48,7 +50,7 @@ public class X11GraphicsScreen extends DefaultGraphicsScreen implements Cloneabl
/** Constructs a new X11GraphicsScreen corresponding to the given native screen index. */
public X11GraphicsScreen(X11GraphicsDevice device, int screen) {
- super(device, fetchScreen(device, screen));
+ super(device, device.isXineramaEnabled() ? 0 : screen);
}
public static AbstractGraphicsScreen createScreenDevice(long display, int screenIdx, boolean owner) {
@@ -61,14 +63,6 @@ public class X11GraphicsScreen extends DefaultGraphicsScreen implements Cloneabl
return X11Lib.DefaultVisualID(getDevice().getHandle(), getIndex());
}
- private static int fetchScreen(X11GraphicsDevice device, int screen) {
- // It still could be an AWT hold handle ..
- if(X11Util.XineramaIsEnabled(device.getHandle())) {
- screen = 0; // Xinerama -> 1 screen
- }
- return screen;
- }
-
public Object clone() {
return super.clone();
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java
index 756e445..8ecd524 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java
@@ -102,17 +102,24 @@ public interface AbstractGraphicsDevice extends Cloneable {
public long getHandle();
/**
- * Optionally locking the device, utilizing eg {@link javax.media.nativewindow.ToolkitLock}.
+ * Optionally locking the device, utilizing eg {@link javax.media.nativewindow.ToolkitLock#lock()}.
* The lock implementation must be recursive.
*/
public void lock();
/**
- * Optionally unlocking the device, utilizing eg {@link javax.media.nativewindow.ToolkitLock}.
+ * Optionally unlocking the device, utilizing eg {@link javax.media.nativewindow.ToolkitLock#unlock()}.
* The lock implementation must be recursive.
+ *
+ * @throws RuntimeException in case the lock is not acquired by this thread.
*/
public void unlock();
+ /**
+ * @throws RuntimeException if current thread does not hold the lock
+ */
+ public void validateLocked() throws RuntimeException;
+
/**
* Optionally [re]opening the device if handle is <code>null</code>.
* <p>
@@ -131,7 +138,7 @@ public interface AbstractGraphicsDevice extends Cloneable {
/**
* Optionally closing the device if handle is not <code>null</code>.
* <p>
- * The default implementation is a <code>NOP</code>, just setting the handle to <code>null</code>.
+ * The default implementation {@link ToolkitLock#dispose() dispose} it's {@link ToolkitLock} and sets the handle to <code>null</code>.
* </p>
* <p>
* Example implementations like {@link com.jogamp.nativewindow.x11.X11GraphicsDevice}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/Capabilities.java b/src/nativewindow/classes/javax/media/nativewindow/Capabilities.java
index cb33aec..5795e8c 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/Capabilities.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/Capabilities.java
@@ -61,6 +61,9 @@ public class Capabilities implements CapabilitiesImmutable, Cloneable {
// Switch for on- or offscreen
private boolean onscreen = true;
+
+ // offscreen bitmap mode
+ private boolean isBitmap = false;
/** Creates a Capabilities object. All attributes are in a default
state.
@@ -71,7 +74,7 @@ public class Capabilities implements CapabilitiesImmutable, Cloneable {
public Object cloneMutable() {
return clone();
}
-
+
@Override
public Object clone() {
try {
@@ -81,10 +84,32 @@ public class Capabilities implements CapabilitiesImmutable, Cloneable {
}
}
+ /**
+ * Copies all {@link Capabilities} values
+ * from <code>source</code> into this instance.
+ * @return this instance
+ */
+ public Capabilities copyFrom(CapabilitiesImmutable other) {
+ redBits = other.getRedBits();
+ greenBits = other.getGreenBits();
+ blueBits = other.getBlueBits();
+ alphaBits = other.getAlphaBits();
+ backgroundOpaque = other.isBackgroundOpaque();
+ onscreen = other.isOnscreen();
+ isBitmap = other.isBitmap();
+ transparentValueRed = other.getTransparentRedValue();
+ transparentValueGreen = other.getTransparentGreenValue();
+ transparentValueBlue = other.getTransparentBlueValue();
+ transparentValueAlpha = other.getTransparentAlphaValue();
+ return this;
+ }
+
@Override
public int hashCode() {
// 31 * x == (x << 5) - x
int hash = 31 + this.redBits;
+ hash = ((hash << 5) - hash) + ( this.onscreen ? 1 : 0 );
+ hash = ((hash << 5) - hash) + ( this.isBitmap ? 1 : 0 );
hash = ((hash << 5) - hash) + this.greenBits;
hash = ((hash << 5) - hash) + this.blueBits;
hash = ((hash << 5) - hash) + this.alphaBits;
@@ -93,7 +118,6 @@ public class Capabilities implements CapabilitiesImmutable, Cloneable {
hash = ((hash << 5) - hash) + this.transparentValueGreen;
hash = ((hash << 5) - hash) + this.transparentValueBlue;
hash = ((hash << 5) - hash) + this.transparentValueAlpha;
- hash = ((hash << 5) - hash) + ( this.onscreen ? 1 : 0 );
return hash;
}
@@ -109,12 +133,13 @@ public class Capabilities implements CapabilitiesImmutable, Cloneable {
other.getBlueBits()==blueBits &&
other.getAlphaBits()==alphaBits &&
other.isBackgroundOpaque()==backgroundOpaque &&
- other.isOnscreen()==onscreen;
- if(!backgroundOpaque) {
- res = res && other.getTransparentRedValue()==transparentValueRed &&
- other.getTransparentGreenValue()==transparentValueGreen &&
- other.getTransparentBlueValue()==transparentValueBlue &&
- other.getTransparentAlphaValue()==transparentValueAlpha;
+ other.isOnscreen()==onscreen &&
+ other.isBitmap()==isBitmap;
+ if(res && !backgroundOpaque) {
+ res = other.getTransparentRedValue()==transparentValueRed &&
+ other.getTransparentGreenValue()==transparentValueGreen &&
+ other.getTransparentBlueValue()==transparentValueBlue &&
+ other.getTransparentAlphaValue()==transparentValueAlpha;
}
return res;
@@ -158,9 +183,6 @@ public class Capabilities implements CapabilitiesImmutable, Cloneable {
}
}
- /** Returns the number of bits requested for the color buffer's red
- component. On some systems only the color depth, which is the
- sum of the red, green, and blue bits, is considered. */
@Override
public final int getRedBits() {
return redBits;
@@ -173,9 +195,6 @@ public class Capabilities implements CapabilitiesImmutable, Cloneable {
this.redBits = redBits;
}
- /** Returns the number of bits requested for the color buffer's
- green component. On some systems only the color depth, which is
- the sum of the red, green, and blue bits, is considered. */
@Override
public final int getGreenBits() {
return greenBits;
@@ -188,9 +207,6 @@ public class Capabilities implements CapabilitiesImmutable, Cloneable {
this.greenBits = greenBits;
}
- /** Returns the number of bits requested for the color buffer's blue
- component. On some systems only the color depth, which is the
- sum of the red, green, and blue bits, is considered. */
@Override
public final int getBlueBits() {
return blueBits;
@@ -203,9 +219,6 @@ public class Capabilities implements CapabilitiesImmutable, Cloneable {
this.blueBits = blueBits;
}
- /** Returns the number of bits requested for the color buffer's
- alpha component. On some systems only the color depth, which is
- the sum of the red, green, and blue bits, is considered. */
@Override
public final int getAlphaBits() {
return alphaBits;
@@ -228,10 +241,7 @@ public class Capabilities implements CapabilitiesImmutable, Cloneable {
}
/**
- * Defaults to true, ie. opaque surface.
- * <p>
- * On supported platforms, setting opaque to false may result in a translucent surface. </p>
- *
+ * Sets whether the surface shall be opaque or translucent.
* <p>
* Platform implementations may need an alpha component in the surface (eg. Windows),
* or expect pre-multiplied alpha values (eg. X11/XRender).<br>
@@ -240,16 +250,9 @@ public class Capabilities implements CapabilitiesImmutable, Cloneable {
* Please note that in case alpha is required on the platform the
* clear color shall have an alpha lower than 1.0 to allow anything shining through.
* </p>
- *
* <p>
* Mind that translucency may cause a performance penalty
- * due to the composite work required by the window manager.</p>
- *
- * <p>
- * The platform implementation may utilize the transparency RGBA values.<br>
- * This is true for the original GLX transparency specification, which is no more used today.<br>
- * Actually these values are currently not used by any implementation,
- * so we may mark them deprecated soon, if this doesn't change.<br>
+ * due to the composite work required by the window manager.
* </p>
*/
public void setBackgroundOpaque(boolean opaque) {
@@ -259,56 +262,65 @@ public class Capabilities implements CapabilitiesImmutable, Cloneable {
}
}
- /** Indicates whether the background of this OpenGL context should
- be considered opaque. Defaults to true.
-
- @see #setBackgroundOpaque
- */
@Override
public final boolean isBackgroundOpaque() {
return backgroundOpaque;
}
- /** Sets whether the drawable surface supports onscreen.
- Defaults to true.
- */
+ /**
+ * Sets whether the surface shall be on- or offscreen.
+ * <p>
+ * Defaults to true.
+ * </p>
+ * <p>
+ * If requesting an offscreen surface without further selection of it's mode,
+ * e.g. FBO, Pbuffer or {@link #setBitmap(boolean) bitmap},
+ * the implementation will choose the best available offscreen mode.
+ * </p>
+ * @param onscreen
+ */
public void setOnscreen(boolean onscreen) {
this.onscreen=onscreen;
}
- /** Indicates whether the drawable surface is onscreen.
- Defaults to true.
- */
@Override
public final boolean isOnscreen() {
return onscreen;
}
- /** Gets the transparent red value for the frame buffer configuration.
- * This value is undefined if {@link #isBackgroundOpaque()} equals true.
- * @see #setTransparentRedValue
- */
+ /**
+ * Requesting offscreen bitmap mode.
+ * <p>
+ * If enabled this method also invokes {@link #setOnscreen(int) setOnscreen(false)}.
+ * </p>
+ * <p>
+ * Defaults to false.
+ * </p>
+ * <p>
+ * Requesting offscreen bitmap mode disables the offscreen auto selection.
+ * </p>
+ */
+ public void setBitmap(boolean enable) {
+ if(enable) {
+ setOnscreen(false);
+ }
+ isBitmap = enable;
+ }
+
+ @Override
+ public boolean isBitmap() {
+ return isBitmap;
+ }
+
@Override
public final int getTransparentRedValue() { return transparentValueRed; }
- /** Gets the transparent green value for the frame buffer configuration.
- * This value is undefined if {@link #isBackgroundOpaque()} equals true.
- * @see #setTransparentGreenValue
- */
@Override
public final int getTransparentGreenValue() { return transparentValueGreen; }
- /** Gets the transparent blue value for the frame buffer configuration.
- * This value is undefined if {@link #isBackgroundOpaque()} equals true.
- * @see #setTransparentBlueValue
- */
@Override
public final int getTransparentBlueValue() { return transparentValueBlue; }
- /** Gets the transparent alpha value for the frame buffer configuration.
- * This value is undefined if {@link #isBackgroundOpaque()} equals true.
- * @see #setTransparentAlphaValue
- */
@Override
public final int getTransparentAlphaValue() { return transparentValueAlpha; }
@@ -342,32 +354,58 @@ public class Capabilities implements CapabilitiesImmutable, Cloneable {
@Override
public StringBuilder toString(StringBuilder sink) {
+ return toString(sink, true);
+ }
+
+ /** Returns a textual representation of this Capabilities
+ object. */
+ @Override
+ public String toString() {
+ StringBuilder msg = new StringBuilder();
+ msg.append("Caps[");
+ toString(msg);
+ msg.append("]");
+ return msg.toString();
+ }
+
+ /** Return a textual representation of this object's on/off screen state. Use the given StringBuffer [optional]. */
+ protected StringBuilder onoffScreenToString(StringBuilder sink) {
if(null == sink) {
sink = new StringBuilder();
}
if(onscreen) {
sink.append("on-scr");
} else {
- sink.append("offscr");
+ sink.append("offscr[");
+ }
+ if(isBitmap) {
+ sink.append("bitmap");
+ } else if(onscreen) {
+ sink.append("."); // no additional off-screen modes besides on-screen
+ } else {
+ sink.append("auto-cfg"); // auto-config off-screen mode
+ }
+ sink.append("]");
+
+ return sink;
+ }
+
+ protected StringBuilder toString(StringBuilder sink, boolean withOnOffScreen) {
+ if(null == sink) {
+ sink = new StringBuilder();
}
- sink.append(", rgba 0x").append(toHexString(redBits)).append("/").append(toHexString(greenBits)).append("/").append(toHexString(blueBits)).append("/").append(toHexString(alphaBits));
+ sink.append("rgba 0x").append(toHexString(redBits)).append("/").append(toHexString(greenBits)).append("/").append(toHexString(blueBits)).append("/").append(toHexString(alphaBits));
if(backgroundOpaque) {
sink.append(", opaque");
} else {
sink.append(", trans-rgba 0x").append(toHexString(transparentValueRed)).append("/").append(toHexString(transparentValueGreen)).append("/").append(toHexString(transparentValueBlue)).append("/").append(toHexString(transparentValueAlpha));
}
+ if(withOnOffScreen) {
+ sink.append(", ");
+ onoffScreenToString(sink);
+ }
return sink;
}
+
protected final String toHexString(int val) { return Integer.toHexString(val); }
-
- /** Returns a textual representation of this Capabilities
- object. */
- @Override
- public String toString() {
- StringBuilder msg = new StringBuilder();
- msg.append("Caps[");
- toString(msg);
- msg.append("]");
- return msg.toString();
- }
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/CapabilitiesImmutable.java b/src/nativewindow/classes/javax/media/nativewindow/CapabilitiesImmutable.java
index b984a46..b801ab4 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/CapabilitiesImmutable.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/CapabilitiesImmutable.java
@@ -39,45 +39,66 @@ import com.jogamp.common.type.WriteCloneable;
public interface CapabilitiesImmutable extends VisualIDHolder, WriteCloneable, Comparable<CapabilitiesImmutable> {
/**
- * Returns the number of bits requested for the color buffer's red
+ * Returns the number of bits for the color buffer's red
* component. On some systems only the color depth, which is the sum of the
* red, green, and blue bits, is considered.
*/
int getRedBits();
/**
- * Returns the number of bits requested for the color buffer's green
+ * Returns the number of bits for the color buffer's green
* component. On some systems only the color depth, which is the sum of the
* red, green, and blue bits, is considered.
*/
int getGreenBits();
/**
- * Returns the number of bits requested for the color buffer's blue
+ * Returns the number of bits for the color buffer's blue
* component. On some systems only the color depth, which is the sum of the
* red, green, and blue bits, is considered.
*/
int getBlueBits();
/**
- * Returns the number of bits requested for the color buffer's alpha
+ * Returns the number of bits for the color buffer's alpha
* component. On some systems only the color depth, which is the sum of the
* red, green, and blue bits, is considered.
*/
int getAlphaBits();
/**
- * Indicates whether the background of this OpenGL context should be
- * considered opaque. Defaults to true.
+ * Returns whether an opaque or translucent surface is requested, supported or chosen.
+ * <p>
+ * Default is true, i.e. opaque.
+ * </p>
*/
boolean isBackgroundOpaque();
/**
- * Indicates whether the drawable surface is onscreen. Defaults to true.
+ * Returns whether an on- or offscreen surface is requested, available or chosen.
+ * <p>
+ * Default is true, i.e. onscreen.
+ * </p>
+ * <p>
+ * Mind that an capabilities intance w/ <i>available</i> semantics
+ * may show onscreen, but also the offscreen modes FBO, Pbuffer or {@link #setBitmap(boolean) bitmap}.
+ * This is valid, since one native configuration maybe used for either functionality.
+ * </p>
*/
boolean isOnscreen();
/**
+ * Returns whether bitmap offscreen mode is requested, available or chosen.
+ * <p>
+ * Default is false.
+ * </p>
+ * <p>
+ * For chosen capabilities, only the selected offscreen surface is set to <code>true</code>.
+ * </p>
+ */
+ boolean isBitmap();
+
+ /**
* Gets the transparent red value for the frame buffer configuration. This
* value is undefined if; equals true.
*/
diff --git a/src/nativewindow/classes/javax/media/nativewindow/DefaultCapabilitiesChooser.java b/src/nativewindow/classes/javax/media/nativewindow/DefaultCapabilitiesChooser.java
index 9d4b112..744c7e6 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/DefaultCapabilitiesChooser.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/DefaultCapabilitiesChooser.java
@@ -68,6 +68,9 @@ import jogamp.nativewindow.Debug;
public class DefaultCapabilitiesChooser implements CapabilitiesChooser {
private static final boolean DEBUG = Debug.isPropertyDefined("nativewindow.debug.CapabilitiesChooser", true);
+ private final static int NO_SCORE = -9999999;
+ private final static int COLOR_MISMATCH_PENALTY_SCALE = 36;
+
public int chooseCapabilities(final CapabilitiesImmutable desired,
final List<? extends CapabilitiesImmutable> available,
final int windowSystemRecommendedChoice) {
@@ -92,8 +95,6 @@ public class DefaultCapabilitiesChooser implements CapabilitiesChooser {
// Create score array
int[] scores = new int[availnum];
- int NO_SCORE = -9999999;
- int COLOR_MISMATCH_PENALTY_SCALE = 36;
for (int i = 0; i < availnum; i++) {
scores[i] = NO_SCORE;
}
@@ -103,6 +104,10 @@ public class DefaultCapabilitiesChooser implements CapabilitiesChooser {
if (cur == null) {
continue;
}
+ if (desired.isOnscreen() && !cur.isOnscreen()) {
+ continue; // requested onscreen, but n/a
+ }
+
int score = 0;
// Compute difference in color depth
score += (COLOR_MISMATCH_PENALTY_SCALE *
diff --git a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java
index 583fde0..9288652 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java
@@ -60,7 +60,7 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
/**
* Create an instance with the system default {@link ToolkitLock}.
- * gathered via {@link NativeWindowFactory#createDefaultToolkitLock(String, long)}.
+ * gathered via {@link NativeWindowFactory#getDefaultToolkitLock(String, long)}.
* @param type
* @param handle
*/
@@ -70,7 +70,7 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
this.unitID = unitID;
this.uniqueID = getUniqueID(type, connection, unitID);
this.handle = handle;
- this.toolkitLock = NativeWindowFactory.createDefaultToolkitLock(type, handle);
+ this.toolkitLock = NativeWindowFactory.getDefaultToolkitLock(type, handle);
}
/**
@@ -123,8 +123,10 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
}
/**
- * No lock is performed on the graphics device per default,
- * instead the aggregated recursive {@link ToolkitLock#lock()} is invoked.
+ * {@inheritDoc}
+ * <p>
+ * Locking is perfomed via delegation to {@link ToolkitLock#lock()}, {@link ToolkitLock#unlock()}.
+ * </p>
*
* @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long)
* @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long, javax.media.nativewindow.ToolkitLock)
@@ -134,9 +136,16 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
toolkitLock.lock();
}
+ @Override
+ public final void validateLocked() throws RuntimeException {
+ toolkitLock.validateLocked();
+ }
+
/**
- * No lock is performed on the graphics device per default,
- * instead the aggregated recursive {@link ToolkitLock#unlock()} is invoked.
+ * {@inheritDoc}
+ * <p>
+ * Locking is perfomed via delegation to {@link ToolkitLock#lock()}, {@link ToolkitLock#unlock()}.
+ * </p>
*
* @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long)
* @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long, javax.media.nativewindow.ToolkitLock)
@@ -153,6 +162,7 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
@Override
public boolean close() {
+ toolkitLock.dispose();
if(0 != handle) {
handle = 0;
return true;
@@ -162,7 +172,7 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
@Override
public String toString() {
- return getClass().getSimpleName()+"[type "+getType()+", connection "+getConnection()+", unitID "+getUnitID()+", handle 0x"+Long.toHexString(getHandle())+"]";
+ return getClass().getSimpleName()+"[type "+getType()+", connection "+getConnection()+", unitID "+getUnitID()+", handle 0x"+Long.toHexString(getHandle())+", "+toolkitLock+"]";
}
/**
diff --git a/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java b/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java
index c3fdc67..9694f24 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java
@@ -129,7 +129,7 @@ public abstract class GraphicsConfigurationFactory {
// well as X11GraphicsDevices in non-AWT situations)
registerFactory(defaultDeviceCapsType.deviceType, defaultDeviceCapsType.capsType, new DefaultGraphicsConfigurationFactoryImpl());
- if (NativeWindowFactory.TYPE_X11.equals(NativeWindowFactory.getNativeWindowType(true))) {
+ if (NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(true)) {
try {
ReflectionUtil.callStaticMethod("jogamp.nativewindow.x11.X11GraphicsConfigurationFactory",
"registerFactory", null, null, GraphicsConfigurationFactory.class.getClassLoader());
diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeSurface.java b/src/nativewindow/classes/javax/media/nativewindow/NativeSurface.java
index cec7d4e..27462ae 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/NativeSurface.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/NativeSurface.java
@@ -124,8 +124,11 @@ public interface NativeSurface extends SurfaceUpdatedListener {
/**
* Provide a mechanism to utilize custom (pre-) swap surface
* code. This method is called before the render toolkit (e.g. JOGL)
- * swaps the buffer/surface. The implementation may itself apply the swapping,
+ * swaps the buffer/surface if double buffering is enabled.
+ * <p>
+ * The implementation may itself apply the swapping,
* in which case true shall be returned.
+ * </p>
*
* @return true if this method completed swapping the surface,
* otherwise false, in which case eg the GLDrawable
diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
index 6faa989..179610b 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
@@ -33,7 +33,7 @@
package javax.media.nativewindow;
-import java.lang.reflect.Constructor;
+import java.io.File;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedAction;
@@ -43,6 +43,8 @@ import java.util.Map;
import jogamp.nativewindow.Debug;
import jogamp.nativewindow.NativeWindowFactoryImpl;
+import jogamp.nativewindow.ToolkitProperties;
+import jogamp.nativewindow.ResourceToolkitLock;
import com.jogamp.common.os.Platform;
import com.jogamp.common.util.ReflectionUtil;
@@ -56,57 +58,72 @@ import com.jogamp.common.util.ReflectionUtil;
public abstract class NativeWindowFactory {
protected static final boolean DEBUG;
- /** OpenKODE/EGL type, as retrieved with {@link #getNativeWindowType(boolean)}*/
- public static final String TYPE_EGL = "EGL";
+ /** OpenKODE/EGL type, as retrieved with {@link #getNativeWindowType(boolean)}. String is canonical via {@link String#intern()}.*/
+ public static final String TYPE_EGL = ".egl".intern();
- /** Microsoft Windows type, as retrieved with {@link #getNativeWindowType(boolean)} */
- public static final String TYPE_WINDOWS = "Windows";
+ /** Microsoft Windows type, as retrieved with {@link #getNativeWindowType(boolean)}. String is canonical via {@link String#intern()}. */
+ public static final String TYPE_WINDOWS = ".windows".intern();
- /** X11 type, as retrieved with {@link #getNativeWindowType(boolean)} */
- public static final String TYPE_X11 = "X11";
+ /** X11 type, as retrieved with {@link #getNativeWindowType(boolean)}. String is canonical via {@link String#intern()}. */
+ public static final String TYPE_X11 = ".x11".intern();
- /** Android/EGL type, as retrieved with {@link #getNativeWindowType(boolean)}*/
- public static final String TYPE_ANDROID = "ANDROID";
+ /** Broadcom VC IV/EGL type, as retrieved with {@link #getNativeWindowType(boolean)}. String is canonical via {@link String#intern()}. */
+ public static final String TYPE_BCM_VC_IV = ".bcm.vc.iv".intern();
- /** Mac OS X type, as retrieved with {@link #getNativeWindowType(boolean)} */
- public static final String TYPE_MACOSX = "MacOSX";
+ /** Android/EGL type, as retrieved with {@link #getNativeWindowType(boolean)}. String is canonical via {@link String#intern()}.*/
+ public static final String TYPE_ANDROID = ".android".intern();
- /** Generic AWT type, as retrieved with {@link #getNativeWindowType(boolean)} */
- public static final String TYPE_AWT = "AWT";
+ /** Mac OS X type, as retrieved with {@link #getNativeWindowType(boolean)}. String is canonical via {@link String#intern()}. */
+ public static final String TYPE_MACOSX = ".macosx".intern();
- /** Generic DEFAULT type, where platform implementation don't care, as retrieved with {@link #getNativeWindowType(boolean)} */
- public static final String TYPE_DEFAULT = "default";
+ /** Generic AWT type, as retrieved with {@link #getNativeWindowType(boolean)}. String is canonical via {@link String#intern()}. */
+ public static final String TYPE_AWT = ".awt".intern();
+ /** Generic DEFAULT type, where platform implementation don't care, as retrieved with {@link #getNativeWindowType(boolean)}. String is canonical via {@link String#intern()}. */
+ public static final String TYPE_DEFAULT = ".default".intern();
+
+ private static final String nativeWindowingTypePure; // canonical String via String.intern()
+ private static final String nativeWindowingTypeCustom; // canonical String via String.intern()
+
private static NativeWindowFactory defaultFactory;
private static Map<Class<?>, NativeWindowFactory> registeredFactories;
private static Class<?> nativeWindowClass;
- private static String nativeWindowingTypePure;
- private static String nativeWindowingTypeCustom;
private static boolean isAWTAvailable;
private static final String JAWTUtilClassName = "jogamp.nativewindow.jawt.JAWTUtil" ;
+ /** {@link jogamp.nativewindow.x11.X11Util} implements {@link ToolkitProperties}. */
private static final String X11UtilClassName = "jogamp.nativewindow.x11.X11Util";
+ /** {@link jogamp.nativewindow.macosx.OSXUtil} implements {@link ToolkitProperties}. */
private static final String OSXUtilClassName = "jogamp.nativewindow.macosx.OSXUtil";
+ /** {@link jogamp.nativewindow.windows.GDIUtil} implements {@link ToolkitProperties}. */
private static final String GDIClassName = "jogamp.nativewindow.windows.GDIUtil";
private static ToolkitLock jawtUtilJAWTToolkitLock;
- public static final String X11JAWTToolkitLockClassName = "jogamp.nativewindow.jawt.x11.X11JAWTToolkitLock" ;
- public static final String X11ToolkitLockClassName = "jogamp.nativewindow.x11.X11ToolkitLock" ;
-
- private static Class<?> x11JAWTToolkitLockClass;
- private static Constructor<?> x11JAWTToolkitLockConstructor;
- private static Class<?> x11ToolkitLockClass;
- private static Constructor<?> x11ToolkitLockConstructor;
- private static boolean isFirstUIActionOnProcess;
private static boolean requiresToolkitLock;
+ private static boolean desktopHasThreadingIssues;
+ private static volatile boolean isJVMShuttingDown = false;
+
/** Creates a new NativeWindowFactory instance. End users do not
need to call this method. */
protected NativeWindowFactory() {
}
+ private static final boolean guessBroadcomVCIV() {
+ return AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
+ private final File vcliblocation = new File(
+ "/opt/vc/lib/libbcm_host.so");
+ public Boolean run() {
+ if ( vcliblocation.isFile() ) {
+ return Boolean.TRUE;
+ }
+ return Boolean.FALSE;
+ }
+ } ).booleanValue();
+ }
+
private static String _getNativeWindowingType() {
switch(Platform.OS_TYPE) {
case ANDROID:
@@ -123,6 +140,9 @@ public abstract class NativeWindowFactory {
case SUNOS:
case HPUX:
default:
+ if( guessBroadcomVCIV() ) {
+ return TYPE_BCM_VC_IV;
+ }
return TYPE_X11;
}
}
@@ -134,73 +154,73 @@ public abstract class NativeWindowFactory {
System.err.println(Thread.currentThread().getName()+" - Info: NativeWindowFactory.<init>");
// Thread.dumpStack();
}
+
+ // Gather the windowing TK first
+ nativeWindowingTypePure = _getNativeWindowingType();
+ final String tmp = Debug.getProperty("nativewindow.ws.name", true);
+ if(null==tmp || tmp.length()==0) {
+ nativeWindowingTypeCustom = nativeWindowingTypePure;
+ } else {
+ nativeWindowingTypeCustom = tmp.intern(); // canonical representation
+ }
}
static boolean initialized = false;
- private static void initSingletonNativeImpl(final boolean firstUIActionOnProcess, final ClassLoader cl) {
- isFirstUIActionOnProcess = firstUIActionOnProcess;
-
+ private static void initSingletonNativeImpl(final ClassLoader cl) {
final String clazzName;
- if( TYPE_X11.equals(nativeWindowingTypePure) ) {
+ if( TYPE_X11 == nativeWindowingTypePure ) {
clazzName = X11UtilClassName;
- } else if( TYPE_WINDOWS.equals(nativeWindowingTypePure) ) {
+ } else if( TYPE_WINDOWS == nativeWindowingTypePure ) {
clazzName = GDIClassName;
- } else if( TYPE_MACOSX.equals(nativeWindowingTypePure) ) {
+ } else if( TYPE_MACOSX == nativeWindowingTypePure ) {
clazzName = OSXUtilClassName;
} else {
clazzName = null;
}
if( null != clazzName ) {
- ReflectionUtil.callStaticMethod(clazzName, "initSingleton",
- new Class[] { boolean.class },
- new Object[] { new Boolean(firstUIActionOnProcess) }, cl );
+ ReflectionUtil.callStaticMethod(clazzName, "initSingleton", null, null, cl );
- final Boolean res = (Boolean) ReflectionUtil.callStaticMethod(clazzName, "requiresToolkitLock", null, null, cl);
- requiresToolkitLock = res.booleanValue();
+ final Boolean res1 = (Boolean) ReflectionUtil.callStaticMethod(clazzName, "requiresToolkitLock", null, null, cl);
+ requiresToolkitLock = res1.booleanValue();
+ final Boolean res2 = (Boolean) ReflectionUtil.callStaticMethod(clazzName, "hasThreadingIssues", null, null, cl);
+ desktopHasThreadingIssues = res2.booleanValue();
} else {
requiresToolkitLock = false;
- }
+ desktopHasThreadingIssues = false;
+ }
}
+ private static void shutdownNativeImpl(final ClassLoader cl) {
+ final String clazzName;
+ if( TYPE_X11 == nativeWindowingTypePure ) {
+ clazzName = X11UtilClassName;
+ } else if( TYPE_WINDOWS == nativeWindowingTypePure ) {
+ clazzName = GDIClassName;
+ } else if( TYPE_MACOSX == nativeWindowingTypePure ) {
+ clazzName = OSXUtilClassName;
+ } else {
+ clazzName = null;
+ }
+ if( null != clazzName ) {
+ ReflectionUtil.callStaticMethod(clazzName, "shutdown", null, null, cl );
+ }
+ }
+
/**
* Static one time initialization of this factory.<br>
* This initialization method <b>must be called</b> once by the program or utilizing modules!
- * <p>
- * The parameter <code>firstUIActionOnProcess</code> has an impact on concurrent locking:
- * <ul>
- * <li> {@link #getDefaultToolkitLock() getDefaultToolkitLock() }</li>
- * <li> {@link #getDefaultToolkitLock(java.lang.String) getDefaultToolkitLock(type) }</li>
- * <li> {@link #createDefaultToolkitLock(java.lang.String, long) createDefaultToolkitLock(type, dpyHandle) }</li>
- * <li> {@link #createDefaultToolkitLockNoAWT(java.lang.String, long) createDefaultToolkitLockNoAWT(type, dpyHandle) }</li>
- * </ul>
- * </p>
- * @param firstUIActionOnProcess Should be <code>true</code> if called before the first UI action of the running program,
- * otherwise <code>false</code>.
*/
- public static synchronized void initSingleton(final boolean firstUIActionOnProcess) {
+ public static synchronized void initSingleton() {
if(!initialized) {
initialized = true;
if(DEBUG) {
- System.err.println(Thread.currentThread().getName()+" - NativeWindowFactory.initSingleton("+firstUIActionOnProcess+")");
+ System.err.println(Thread.currentThread().getName()+" - NativeWindowFactory.initSingleton()");
}
final ClassLoader cl = NativeWindowFactory.class.getClassLoader();
- // Gather the windowing OS first
- nativeWindowingTypePure = _getNativeWindowingType();
- String tmp = Debug.getProperty("nativewindow.ws.name", true);
- if(null==tmp || tmp.length()==0) {
- nativeWindowingTypeCustom = nativeWindowingTypePure;
- } else {
- nativeWindowingTypeCustom = tmp;
- }
-
- if(firstUIActionOnProcess) {
- // X11 initialization before possible AWT initialization
- initSingletonNativeImpl(true, cl);
- }
isAWTAvailable = false; // may be set to true below
if( Platform.AWT_AVAILABLE &&
@@ -248,10 +268,13 @@ public abstract class NativeWindowFactory {
}
}
}
- if(!firstUIActionOnProcess) {
- // X11 initialization after possible AWT initialization
- initSingletonNativeImpl(false, cl);
- }
+
+ // X11 initialization after possible AWT initialization
+ // This is performed post AWT initialization, allowing AWT to complete the same,
+ // which may have been triggered before NativeWindow initialization.
+ // This way behavior is more uniforms across configurations (Applet/RCP, applications, ..).
+ initSingletonNativeImpl(cl);
+
registeredFactories = Collections.synchronizedMap(new HashMap<Class<?>, NativeWindowFactory>());
// register our default factory -> NativeWindow
@@ -264,20 +287,9 @@ public abstract class NativeWindowFactory {
// register either our default factory or (if exist) the X11/AWT one -> AWT Component
registerFactory(ReflectionUtil.getClass(ReflectionUtil.AWTNames.ComponentClass, false, cl), factory);
}
-
- if( TYPE_X11 == nativeWindowingTypePure ) {
- // passing through RuntimeException if not exists intended
- x11ToolkitLockClass = ReflectionUtil.getClass(X11ToolkitLockClassName, false, cl);
- x11ToolkitLockConstructor = ReflectionUtil.getConstructor(x11ToolkitLockClass, new Class[] { long.class } );
- if( isAWTAvailable() ) {
- x11JAWTToolkitLockClass = ReflectionUtil.getClass(X11JAWTToolkitLockClassName, false, cl);
- x11JAWTToolkitLockConstructor = ReflectionUtil.getConstructor(x11JAWTToolkitLockClass, new Class[] { long.class } );
- }
- }
if(DEBUG) {
- System.err.println("NativeWindowFactory firstUIActionOnProcess "+firstUIActionOnProcess);
- System.err.println("NativeWindowFactory requiresToolkitLock "+requiresToolkitLock);
+ System.err.println("NativeWindowFactory requiresToolkitLock "+requiresToolkitLock+", desktopHasThreadingIssues "+desktopHasThreadingIssues);
System.err.println("NativeWindowFactory isAWTAvailable "+isAWTAvailable+", defaultFactory "+factory);
}
@@ -285,39 +297,41 @@ public abstract class NativeWindowFactory {
}
}
- public static synchronized void shutdown() {
+ public static synchronized void shutdown(boolean _isJVMShuttingDown) {
+ isJVMShuttingDown = _isJVMShuttingDown;
+ if(DEBUG) {
+ System.err.println(Thread.currentThread().getName()+" - NativeWindowFactory.shutdown() START: JVM Shutdown "+isJVMShuttingDown);
+ }
if(initialized) {
initialized = false;
- if(DEBUG) {
- System.err.println(Thread.currentThread().getName()+" - NativeWindowFactory.shutdown() START");
+ if(null != registeredFactories) {
+ registeredFactories.clear();
+ registeredFactories = null;
}
- registeredFactories.clear();
- registeredFactories = null;
GraphicsConfigurationFactory.shutdown();
- // X11Util.shutdown(..) already called via GLDrawableFactory.shutdown() ..
- if(DEBUG) {
- System.err.println(Thread.currentThread().getName()+" - NativeWindowFactory.shutdown() END");
- }
+ }
+ shutdownNativeImpl(NativeWindowFactory.class.getClassLoader()); // always re-shutdown
+ // SharedResourceToolkitLock.shutdown(DEBUG); // not used yet
+ if(DEBUG) {
+ System.err.println(Thread.currentThread().getName()+" - NativeWindowFactory.shutdown() END JVM Shutdown "+isJVMShuttingDown);
}
}
- /** @return true if initialized with <b>{@link #initSingleton(boolean) initSingleton(firstUIActionOnProcess==true)}</b>,
- otherwise false. */
- public static boolean isFirstUIActionOnProcess() {
- return isFirstUIActionOnProcess;
- }
-
+ /** Returns true if the JVM is shutting down, otherwise false. */
+ public static final boolean isJVMShuttingDown() { return isJVMShuttingDown; }
+
/** @return true if the underlying toolkit requires locking, otherwise false. */
public static boolean requiresToolkitLock() {
return requiresToolkitLock;
- }
+ }
/** @return true if not headless, AWT Component and NativeWindow's AWT part available */
public static boolean isAWTAvailable() { return isAWTAvailable; }
/**
* @param useCustom if false return the native value, if true return a custom value if set, otherwise fallback to the native value.
- * @return a define native window type, like {@link #TYPE_X11}, ..
+ * @return the native window type, e.g. {@link #TYPE_X11}, which is canonical via {@link String#intern()}.
+ * Hence {@link String#equals(Object)} and <code>==</code> produce the same result.
*/
public static String getNativeWindowType(boolean useCustom) {
return useCustom?nativeWindowingTypeCustom:nativeWindowingTypePure;
@@ -325,13 +339,13 @@ public abstract class NativeWindowFactory {
/** Don't know if we shall add this factory here ..
public static AbstractGraphicsDevice createGraphicsDevice(String type, String connection, int unitID, long handle, ToolkitLock locker) {
- if(type.equals(TYPE_EGL)) {
+ if(TYPE_EGL == type) {
return new
- } else if(type.equals(TYPE_X11)) {
- } else if(type.equals(TYPE_WINDOWS)) {
- } else if(type.equals(TYPE_MACOSX)) {
- } else if(type.equals(TYPE_AWT)) {
- } else if(type.equals(TYPE_DEFAULT)) {
+ } else if(TYPE_X11 == type) {
+ } else if(TYPE_WINDOWS == type) {
+ } else if(TYPE_MACOSX == type)) {
+ } else if(TYPE_AWT == type) {
+ } else if(TYPE_DEFAULT == type) {
}
} */
@@ -345,9 +359,24 @@ public abstract class NativeWindowFactory {
return defaultFactory;
}
+ /**
+ * Returns the AWT {@link ToolkitLock} (JAWT based) if {@link #isAWTAvailable}, otherwise null.
+ * <p>
+ * The JAWT based {@link ToolkitLock} also locks the global lock,
+ * which matters if the latter is required.
+ * </p>
+ */
+ public static ToolkitLock getAWTToolkitLock() {
+ return jawtUtilJAWTToolkitLock;
+ }
+
+ public static ToolkitLock getNullToolkitLock() {
+ return NativeWindowFactoryImpl.getNullToolkitLock();
+ }
+
/**
- * Provides the system default {@link ToolkitLock}, a singleton instance.
- * <br>
+ * Provides the system default {@link ToolkitLock} for the default system windowing type.
+ * @see #getNativeWindowType(boolean)
* @see #getDefaultToolkitLock(java.lang.String)
*/
public static ToolkitLock getDefaultToolkitLock() {
@@ -355,117 +384,41 @@ public abstract class NativeWindowFactory {
}
/**
- * Provides the default {@link ToolkitLock} for <code>type</code>, a singleton instance.
- * <br>
+ * Provides the default {@link ToolkitLock} for <code>type</code>.
* <ul>
- * <li> If {@link #initSingleton(boolean) initSingleton( <b>firstUIActionOnProcess := false</b> )} </li>
- * <ul>
- * <li>If <b>AWT-type</b> and <b>native-X11-type</b> and <b>AWT-available</b></li>
- * <ul>
- * <li> return {@link #getAWTToolkitLock()} </li>
- * </ul>
- * </ul>
- * <li> Otherwise return {@link #getNullToolkitLock()} </li>
+ * <li> JAWT {@link ToolkitLock} if required and <code>type</code> is of {@link #TYPE_AWT} and AWT available,</li>
+ * <li> {@link jogamp.nativewindow.ResourceToolkitLock} if required, otherwise</li>
+ * <li> {@link jogamp.nativewindow.NullToolkitLock} </li>
* </ul>
*/
public static ToolkitLock getDefaultToolkitLock(String type) {
- if( requiresToolkitLock() ) {
- if( TYPE_AWT == type && TYPE_X11 == getNativeWindowType(false) && isAWTAvailable() ) {
+ if( requiresToolkitLock ) {
+ if( TYPE_AWT == type && isAWTAvailable() ) {
return getAWTToolkitLock();
}
+ return ResourceToolkitLock.create();
}
return NativeWindowFactoryImpl.getNullToolkitLock();
}
- /** Returns the AWT Toolkit (JAWT based) if {@link #isAWTAvailable}, otherwise null. */
- public static ToolkitLock getAWTToolkitLock() {
- return jawtUtilJAWTToolkitLock;
- }
-
- public static ToolkitLock getNullToolkitLock() {
- return NativeWindowFactoryImpl.getNullToolkitLock();
- }
-
/**
- * Creates the default {@link ToolkitLock} for <code>type</code> and <code>deviceHandle</code>.
- * <br>
+ * Provides the default {@link ToolkitLock} for <code>type</code> and <code>deviceHandle</code>.
* <ul>
- * <li> If {@link #initSingleton(boolean) initSingleton( <b>firstUIActionOnProcess := false</b> )} </li>
- * <ul>
- * <li>If <b>X11 type</b> </li>
- * <ul>
- * <li> return {@link jogamp.nativewindow.x11.X11ToolkitLock} </li>
- * </ul>
- * </ul>
- * <li> Otherwise return {@link jogamp.nativewindow.NullToolkitLock} </li>
+ * <li> JAWT {@link ToolkitLock} if required and <code>type</code> is of {@link #TYPE_AWT} and AWT available,</li>
+ * <li> {@link jogamp.nativewindow.ResourceToolkitLock} if required, otherwise</li>
+ * <li> {@link jogamp.nativewindow.NullToolkitLock} </li>
* </ul>
*/
- public static ToolkitLock createDefaultToolkitLock(String type, long deviceHandle) {
- if( requiresToolkitLock() ) {
- if( TYPE_X11 == type ) {
- if( 0== deviceHandle ) {
- throw new RuntimeException("JAWTUtil.createDefaultToolkitLock() called with NULL device but on X11");
- }
- return createX11ToolkitLock(deviceHandle);
+ public static ToolkitLock getDefaultToolkitLock(String type, long deviceHandle) {
+ if( requiresToolkitLock ) {
+ if( TYPE_AWT == type && isAWTAvailable() ) {
+ return getAWTToolkitLock();
}
+ return ResourceToolkitLock.create();
}
return NativeWindowFactoryImpl.getNullToolkitLock();
}
- /**
- * Creates the default {@link ToolkitLock} for <code>type</code> and <code>deviceHandle</code>.
- * <br>
- * <ul>
- * <li> If {@link #initSingleton(boolean) initSingleton( <b>firstUIActionOnProcess := false</b> )} </li>
- * <ul>
- * <li>If <b>X11 type</b> </li>
- * <ul>
- * <li> If <b>shared-AWT-type</b> and <b>AWT available</b> </li>
- * <ul>
- * <li> return {@link jogamp.nativewindow.jawt.x11.X11JAWTToolkitLock} </li>
- * </ul>
- * <li> else return {@link jogamp.nativewindow.x11.X11ToolkitLock} </li>
- * </ul>
- * </ul>
- * <li> Otherwise return {@link jogamp.nativewindow.NullToolkitLock} </li>
- * </ul>
- */
- public static ToolkitLock createDefaultToolkitLock(String type, String sharedType, long deviceHandle) {
- if( requiresToolkitLock() ) {
- if( TYPE_X11 == type ) {
- if( 0== deviceHandle ) {
- throw new RuntimeException("JAWTUtil.createDefaultToolkitLock() called with NULL device but on X11");
- }
- if( TYPE_AWT == sharedType && isAWTAvailable() ) {
- return createX11AWTToolkitLock(deviceHandle);
- }
- return createX11ToolkitLock(deviceHandle);
- }
- }
- return NativeWindowFactoryImpl.getNullToolkitLock();
- }
-
- protected static ToolkitLock createX11AWTToolkitLock(long deviceHandle) {
- try {
- if(DEBUG) {
- System.err.println("NativeWindowFactory.createX11AWTToolkitLock(0x"+Long.toHexString(deviceHandle)+")");
- // Thread.dumpStack();
- }
- return (ToolkitLock) x11JAWTToolkitLockConstructor.newInstance(new Object[]{new Long(deviceHandle)});
- } catch (Exception ex) {
- throw new RuntimeException(ex);
- }
- }
-
- protected static ToolkitLock createX11ToolkitLock(long deviceHandle) {
- try {
- return (ToolkitLock) x11ToolkitLockConstructor.newInstance(new Object[]{new Long(deviceHandle)});
- } catch (Exception ex) {
- throw new RuntimeException(ex);
- }
- }
-
-
/** Returns the appropriate NativeWindowFactory to handle window
objects of the given type. The windowClass might be {@link
NativeWindow NativeWindow}, in which case the client has
diff --git a/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java b/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java
index f7dbc6c..f980010 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java
@@ -50,4 +50,7 @@ public interface OffscreenLayerSurface {
/** Returns true if a surface layer is attached, otherwise false. */
public boolean isSurfaceLayerAttached();
+ /** Sets the capabilities of this instance, allowing upstream API's to refine it, i.e. OpenGL related settings. */
+ public void setChosenCapabilities(CapabilitiesImmutable caps);
+
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java b/src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java
index 7fc9789..395fdc8 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java
@@ -1,5 +1,5 @@
/**
- * Copyright 2010 JogAmp Community. All rights reserved.
+ * Copyright 2012 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
@@ -29,242 +29,82 @@
package javax.media.nativewindow;
import jogamp.nativewindow.Debug;
-import jogamp.nativewindow.SurfaceUpdatedHelper;
-import com.jogamp.common.util.locks.LockFactory;
-import com.jogamp.common.util.locks.RecursiveLock;
-
-public abstract class ProxySurface implements NativeSurface, MutableSurface {
+/**
+ * Provides a mutable {@link NativeSurface}, i.e. {@link MutableSurface}, while allowing an
+ * {@link UpstreamSurfaceHook} to influence the lifecycle and information.
+ *
+ * @see UpstreamSurfaceHook
+ * @see MutableSurface
+ * @see NativeSurface
+ */
+public interface ProxySurface extends MutableSurface {
public static final boolean DEBUG = Debug.debug("ProxySurface");
/**
- * Implementation specific bitvalue stating the upstream's {@link AbstractGraphicsDevice} is owned by this {@link ProxySurface}.
- * @see #setImplBitfield(int)
- * @see #getImplBitfield()
+ * Implementation specific bit-value stating this {@link ProxySurface} owns the upstream's surface handle
+ * @see #addUpstreamOptionBits(int)
+ * @see #getUpstreamOptionBits()
*/
- public static final int OWN_DEVICE = 1 << 7;
+ public static final int OPT_PROXY_OWNS_UPSTREAM_SURFACE = 1 << 6;
+
+ /**
+ * Implementation specific bit-value stating this {@link ProxySurface} owns the upstream's {@link AbstractGraphicsDevice}.
+ * @see #addUpstreamOptionBits(int)
+ * @see #getUpstreamOptionBits()
+ */
+ public static final int OPT_PROXY_OWNS_UPSTREAM_DEVICE = 1 << 7;
/**
* Implementation specific bitvalue stating the upstream's {@link NativeSurface} is an invisible window, i.e. maybe incomplete.
- * @see #setImplBitfield(int)
- * @see #getImplBitfield()
+ * @see #addUpstreamOptionBits(int)
+ * @see #getUpstreamOptionBits()
*/
- public static final int INVISIBLE_WINDOW = 1 << 8;
+ public static final int OPT_UPSTREAM_WINDOW_INVISIBLE = 1 << 8;
- /** Interface allowing upstream caller to pass lifecycle actions and size info to a {@link ProxySurface} instance. */
- public interface UpstreamSurfaceHook {
- /** called within {@link ProxySurface#createNotify()} within lock, before using surface. */
- public void create(ProxySurface s);
- /** called within {@link ProxySurface#destroyNotify()} within lock, before clearing fields. */
- public void destroy(ProxySurface s);
+ /** Allow redefining the AbstractGraphicsConfiguration */
+ public void setGraphicsConfiguration(AbstractGraphicsConfiguration cfg);
- /** Returns the width of the upstream surface */
- public int getWidth(ProxySurface s);
- /** Returns the height of the upstream surface */
- public int getHeight(ProxySurface s);
- }
+ /** Returns the set {@link UpstreamSurfaceHook}, or null if not set. */
+ public UpstreamSurfaceHook getUpstreamSurfaceHook();
- private final SurfaceUpdatedHelper surfaceUpdatedHelper = new SurfaceUpdatedHelper();
- private final AbstractGraphicsConfiguration config; // control access due to delegation
- private final UpstreamSurfaceHook upstream;
- public final int initialWidth;
- public final int initialHeight;
- private long surfaceHandle_old;
- protected RecursiveLock surfaceLock = LockFactory.createRecursiveLock();
- protected long displayHandle;
- protected int scrnIndex;
- protected int implBitfield;
-
/**
- * @param cfg the {@link AbstractGraphicsConfiguration} to be used
- * @param initialWidth the initial width
- * @param initialHeight the initial height
+ * Sets the {@link UpstreamSurfaceHook} and returns the previous value.
*/
- protected ProxySurface(AbstractGraphicsConfiguration cfg, int initialWidth, int initialHeight, UpstreamSurfaceHook upstream) {
- if(null == cfg) {
- throw new IllegalArgumentException("null config");
- }
- this.config = cfg;
- this.upstream = upstream;
- this.initialWidth = initialWidth;
- this.initialHeight = initialHeight;
- this.displayHandle=config.getNativeGraphicsConfiguration().getScreen().getDevice().getHandle();
- this.surfaceHandle_old = 0;
- this.implBitfield = 0;
- }
-
- public final UpstreamSurfaceHook getUpstreamSurfaceHook() { return upstream; }
+ public void setUpstreamSurfaceHook(UpstreamSurfaceHook hook);
+
+ /**
+ * Enables or disables the {@link UpstreamSurfaceHook} lifecycle functions
+ * {@link UpstreamSurfaceHook#create(ProxySurface)} and {@link UpstreamSurfaceHook#destroy(ProxySurface)}.
+ * <p>
+ * Use this for small code blocks where the native resources shall not change,
+ * i.e. resizing a derived (OpenGL) drawable.
+ * </p>
+ */
+ public void enableUpstreamSurfaceHookLifecycle(boolean enable);
/**
- * If a valid {@link UpstreamSurfaceHook} instance is passed in the
- * {@link ProxySurface#ProxySurface(AbstractGraphicsConfiguration, int, int, UpstreamSurfaceHook) constructor},
* {@link UpstreamSurfaceHook#create(ProxySurface)} is being issued and the proxy surface/window handles shall be set.
*/
- public void createNotify() {
- if(null != upstream) {
- upstream.create(this);
- }
- this.displayHandle=config.getNativeGraphicsConfiguration().getScreen().getDevice().getHandle();
- this.surfaceHandle_old = 0;
- }
+ public void createNotify();
/**
- * If a valid {@link UpstreamSurfaceHook} instance is passed in the
- * {@link ProxySurface#ProxySurface(AbstractGraphicsConfiguration, int, int, UpstreamSurfaceHook) constructor},
- * {@link UpstreamSurfaceHook#destroy(ProxySurface)} is being issued and all fields are cleared.
+ * {@link UpstreamSurfaceHook#destroy(ProxySurface)} is being issued and all proxy surface/window handles shall be cleared.
*/
- public void destroyNotify() {
- if(null != upstream) {
- upstream.destroy(this);
- invalidateImpl();
- }
- this.displayHandle = 0;
- this.surfaceHandle_old = 0;
- }
+ public void destroyNotify();
- /**
- * Must be overridden by implementations allowing having a {@link UpstreamSurfaceHook} being passed.
- * @see #destroyNotify()
- */
- protected void invalidateImpl() {
- throw new InternalError("UpstreamSurfaceHook given, but required method not implemented.");
- }
+ public StringBuilder getUpstreamOptionBits(StringBuilder sink);
+ public int getUpstreamOptionBits();
- @Override
- public final long getDisplayHandle() {
- return displayHandle;
- }
-
- protected final AbstractGraphicsConfiguration getPrivateGraphicsConfiguration() {
- return config;
- }
-
- @Override
- public final AbstractGraphicsConfiguration getGraphicsConfiguration() {
- return config.getNativeGraphicsConfiguration();
- }
-
- @Override
- public final int getScreenIndex() {
- return getGraphicsConfiguration().getScreen().getIndex();
- }
-
- @Override
- public abstract long getSurfaceHandle();
-
- @Override
- public abstract void setSurfaceHandle(long surfaceHandle);
+ /** Returns <code>true</code> if the give bit-mask <code>v</code> is set in this instance upstream-option-bits, otherwise <code>false</code>.*/
+ public boolean containsUpstreamOptionBits(int v);
- @Override
- public final int getWidth() {
- if(null != upstream) {
- return upstream.getWidth(this);
- }
- return initialWidth;
- }
-
- @Override
- public final int getHeight() {
- if(null != upstream) {
- return upstream.getHeight(this);
- }
- return initialHeight;
- }
-
- @Override
- public boolean surfaceSwap() {
- return false;
- }
-
- @Override
- public void addSurfaceUpdatedListener(SurfaceUpdatedListener l) {
- surfaceUpdatedHelper.addSurfaceUpdatedListener(l);
- }
-
- @Override
- public void addSurfaceUpdatedListener(int index, SurfaceUpdatedListener l) throws IndexOutOfBoundsException {
- surfaceUpdatedHelper.addSurfaceUpdatedListener(index, l);
- }
-
- @Override
- public void removeSurfaceUpdatedListener(SurfaceUpdatedListener l) {
- surfaceUpdatedHelper.removeSurfaceUpdatedListener(l);
- }
-
- @Override
- public void surfaceUpdated(Object updater, NativeSurface ns, long when) {
- surfaceUpdatedHelper.surfaceUpdated(updater, ns, when);
- }
-
- @Override
- public int lockSurface() throws NativeWindowException, RuntimeException {
- surfaceLock.lock();
- int res = surfaceLock.getHoldCount() == 1 ? LOCK_SURFACE_NOT_READY : LOCK_SUCCESS; // new lock ?
-
- if ( LOCK_SURFACE_NOT_READY == res ) {
- try {
- final AbstractGraphicsDevice adevice = getGraphicsConfiguration().getScreen().getDevice();
- adevice.lock();
- try {
- res = lockSurfaceImpl();
- if(LOCK_SUCCESS == res && surfaceHandle_old != getSurfaceHandle()) {
- res = LOCK_SURFACE_CHANGED;
- if(DEBUG) {
- System.err.println("ProxySurface: surface change 0x"+Long.toHexString(surfaceHandle_old)+" -> 0x"+Long.toHexString(getSurfaceHandle()));
- // Thread.dumpStack();
- }
- }
- } finally {
- if (LOCK_SURFACE_NOT_READY >= res) {
- adevice.unlock();
- }
- }
- } finally {
- if (LOCK_SURFACE_NOT_READY >= res) {
- surfaceLock.unlock();
- }
- }
- }
- return res;
- }
-
- @Override
- public final void unlockSurface() {
- surfaceLock.validateLocked();
- surfaceHandle_old = getSurfaceHandle();
-
- if (surfaceLock.getHoldCount() == 1) {
- final AbstractGraphicsDevice adevice = getGraphicsConfiguration().getScreen().getDevice();
- try {
- unlockSurfaceImpl();
- } finally {
- adevice.unlock();
- }
- }
- surfaceLock.unlock();
- }
-
- protected abstract int lockSurfaceImpl();
-
- protected abstract void unlockSurfaceImpl() ;
-
- public final void validateSurfaceLocked() {
- surfaceLock.validateLocked();
- }
-
- @Override
- public final boolean isSurfaceLockedByOtherThread() {
- return surfaceLock.isLockedByOtherThread();
- }
-
- @Override
- public final Thread getSurfaceLockOwner() {
- return surfaceLock.getOwner();
- }
+ /** Add the given bit-mask to this instance upstream-option-bits using bit-or w/ <code>v</code>.*/
+ public void addUpstreamOptionBits(int v);
- @Override
- public abstract String toString();
+ /** Clear the given bit-mask from this instance upstream-option-bits using bit-and w/ <code>~v</code>*/
+ public void clearUpstreamOptionBits(int v);
- public int getImplBitfield() { return implBitfield; }
- public void setImplBitfield(int v) { implBitfield=v; }
+ public StringBuilder toString(StringBuilder sink);
+ public String toString();
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java b/src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java
index 30f9660..eccfcfa 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java
@@ -33,12 +33,46 @@ import jogamp.nativewindow.Debug;
/**
* Marker for a singleton global recursive blocking lock implementation,
* optionally locking a native windowing toolkit as well.
- * <br>
- * One use case is the AWT locking on X11, see {@link jogamp.nativewindow.jawt.JAWTToolkitLock}.
+ * <p>
+ * Toolkit locks are created solely via {@link NativeWindowFactory}.
+ * </p>
+ * <p>
+ * One use case is the AWT locking on X11, see {@link NativeWindowFactory#getDefaultToolkitLock(String, long)}.
+ * </p>
*/
public interface ToolkitLock {
+ public static final boolean DEBUG = Debug.debug("ToolkitLock");
public static final boolean TRACE_LOCK = Debug.isPropertyDefined("nativewindow.debug.ToolkitLock.TraceLock", true);
+ /**
+ * Blocking until the lock is acquired by this Thread or a timeout is reached.
+ * <p>
+ * Timeout is implementation specific, if used at all.
+ * </p>
+ *
+ * @throws RuntimeException in case of a timeout
+ */
public void lock();
+
+ /**
+ * Release the lock.
+ *
+ * @throws RuntimeException in case the lock is not acquired by this thread.
+ */
public void unlock();
+
+ /**
+ * @throws RuntimeException if current thread does not hold the lock
+ */
+ public void validateLocked() throws RuntimeException;
+
+ /**
+ * Dispose this instance.
+ * <p>
+ * Shall be called when instance is no more required.
+ * </p>
+ * This allows implementations sharing a lock via resources
+ * to decrease the reference counter.
+ */
+ public void dispose();
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java b/src/nativewindow/classes/javax/media/nativewindow/UpstreamSurfaceHook.java
similarity index 59%
copy from src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java
copy to src/nativewindow/classes/javax/media/nativewindow/UpstreamSurfaceHook.java
index 30f9660..6fe2e53 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/UpstreamSurfaceHook.java
@@ -1,5 +1,5 @@
/**
- * Copyright 2010 JogAmp Community. All rights reserved.
+ * Copyright 2012 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
@@ -28,17 +28,25 @@
package javax.media.nativewindow;
-import jogamp.nativewindow.Debug;
+/**
+ * Interface allowing upstream caller to pass lifecycle actions and size info
+ * to a {@link ProxySurface} instance.
+ */
+public interface UpstreamSurfaceHook {
+ /** called within {@link ProxySurface#createNotify()} within lock, before using surface. */
+ public void create(ProxySurface s);
+ /** called within {@link ProxySurface#destroyNotify()} within lock, before clearing fields. */
+ public void destroy(ProxySurface s);
-/**
- * Marker for a singleton global recursive blocking lock implementation,
- * optionally locking a native windowing toolkit as well.
- * <br>
- * One use case is the AWT locking on X11, see {@link jogamp.nativewindow.jawt.JAWTToolkitLock}.
- */
-public interface ToolkitLock {
- public static final boolean TRACE_LOCK = Debug.isPropertyDefined("nativewindow.debug.ToolkitLock.TraceLock", true);
-
- public void lock();
- public void unlock();
+ /** Returns the width of the upstream surface, used if {@link ProxySurface#UPSTREAM_PROVIDES_SIZE} is set. */
+ public int getWidth(ProxySurface s);
+ /** Returns the height of the upstream surface, used if {@link ProxySurface#UPSTREAM_PROVIDES_SIZE} is set. */
+ public int getHeight(ProxySurface s);
+
+ /**
+ * {@link UpstreamSurfaceHook} w/ mutable size, allowing it's {@link ProxySurface} user to resize.
+ */
+ public interface MutableSize extends UpstreamSurfaceHook {
+ public void setSize(int width, int height);
+ }
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTToolkitLock.java b/src/nativewindow/classes/jogamp/nativewindow/GlobalToolkitLock.java
similarity index 53%
rename from src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTToolkitLock.java
rename to src/nativewindow/classes/jogamp/nativewindow/GlobalToolkitLock.java
index 743d371..c9f8308 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTToolkitLock.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/GlobalToolkitLock.java
@@ -1,5 +1,5 @@
/**
- * Copyright 2010 JogAmp Community. All rights reserved.
+ * Copyright 2012 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
@@ -25,52 +25,54 @@
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of JogAmp Community.
*/
-package jogamp.nativewindow.jawt.x11;
-import jogamp.nativewindow.jawt.*;
-import jogamp.nativewindow.x11.X11Lib;
-import jogamp.nativewindow.x11.X11Util;
+package jogamp.nativewindow;
+
import javax.media.nativewindow.ToolkitLock;
import com.jogamp.common.util.locks.LockFactory;
import com.jogamp.common.util.locks.RecursiveLock;
/**
- * Implementing a recursive {@link javax.media.nativewindow.ToolkitLock}
- * utilizing JAWT's AWT lock via {@link JAWTUtil#lockToolkit()} and {@link X11Util#XLockDisplay(long)}.
- * <br>
- * This strategy should only be used if AWT is using the underlying native windowing toolkit
- * in a not intrinsic thread safe manner, e.g. under X11 where no XInitThreads() call
- * is issued before any other X11 usage. This is the current situation for e.g. Webstart or Applets.
+ * Implementing a global recursive {@link javax.media.nativewindow.ToolkitLock}.
+ * <p>
+ * This is the last resort for unstable driver where multiple X11 display connections
+ * to the same connection name are not treated thread safe within the GL/X11 driver.
+ * </p>
*/
-public class X11JAWTToolkitLock implements ToolkitLock {
- long displayHandle;
- RecursiveLock lock;
-
- public X11JAWTToolkitLock(long displayHandle) {
- this.displayHandle = displayHandle;
- if(!X11Util.isNativeLockAvailable()) {
- lock = LockFactory.createRecursiveLock();
- }
+public class GlobalToolkitLock implements ToolkitLock {
+ private static final RecursiveLock globalLock = LockFactory.createRecursiveLock();
+ private static GlobalToolkitLock singleton = new GlobalToolkitLock();
+
+ public static final GlobalToolkitLock getSingleton() {
+ return singleton;
}
-
+
+ private GlobalToolkitLock() { }
+
+ @Override
public final void lock() {
- if(TRACE_LOCK) { System.err.println("X11JAWTToolkitLock.lock() - native: "+(null==lock)); }
- JAWTUtil.lockToolkit();
- if(null == lock) {
- X11Lib.XLockDisplay(displayHandle);
- } else {
- lock.lock();
- }
+ globalLock.lock();
+ if(TRACE_LOCK) { System.err.println("GlobalToolkitLock.lock()"); }
}
+ @Override
public final void unlock() {
- if(TRACE_LOCK) { System.err.println("X11JAWTToolkitLock.unlock() - native: "+(null==lock)); }
- if(null == lock) {
- X11Lib.XUnlockDisplay(displayHandle);
- } else {
- lock.unlock();
- }
- JAWTUtil.unlockToolkit();
+ if(TRACE_LOCK) { System.err.println("GlobalToolkitLock.unlock()"); }
+ globalLock.unlock(); // implicit lock validation
+ }
+
+ @Override
+ public final void validateLocked() throws RuntimeException {
+ globalLock.validateLocked();
+ }
+
+ @Override
+ public final void dispose() {
+ // nop
+ }
+
+ public String toString() {
+ return "GlobalToolkitLock[obj 0x"+Integer.toHexString(hashCode())+", isOwner "+globalLock.isOwner(Thread.currentThread())+", "+globalLock.toString()+"]";
}
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java b/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java
index 9e18439..a3a66b7 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java
@@ -39,7 +39,6 @@ import javax.media.nativewindow.NativeWindow;
import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.ToolkitLock;
-import com.jogamp.common.os.Platform;
import com.jogamp.common.util.ReflectionUtil;
import com.jogamp.common.util.ReflectionUtil.AWTNames;
@@ -47,7 +46,7 @@ public class NativeWindowFactoryImpl extends NativeWindowFactory {
private static final ToolkitLock nullToolkitLock = new NullToolkitLock();
public static ToolkitLock getNullToolkitLock() {
- return nullToolkitLock;
+ return nullToolkitLock;
}
// This subclass of NativeWindowFactory handles the case of
@@ -76,21 +75,21 @@ public class NativeWindowFactoryImpl extends NativeWindowFactory {
private NativeWindow getAWTNativeWindow(Object winObj, AbstractGraphicsConfiguration config) {
if (nativeWindowConstructor == null) {
try {
- String windowingType = getNativeWindowType(true);
- String windowClassName = null;
+ final String windowingType = getNativeWindowType(true);
+ final String windowClassName;
// We break compile-time dependencies on the AWT here to
// make it easier to run this code on mobile devices
- if (windowingType.equals(TYPE_WINDOWS)) {
+ if (TYPE_WINDOWS == windowingType) {
windowClassName = "jogamp.nativewindow.jawt.windows.WindowsJAWTWindow";
- } else if (windowingType.equals(TYPE_MACOSX)) {
+ } else if (TYPE_MACOSX == windowingType) {
windowClassName = "jogamp.nativewindow.jawt.macosx.MacOSXJAWTWindow";
- } else if (windowingType.equals(TYPE_X11)) {
+ } else if (TYPE_X11 == windowingType) {
// Assume Linux, Solaris, etc. Should probably test for these explicitly.
windowClassName = "jogamp.nativewindow.jawt.x11.X11JAWTWindow";
} else {
- throw new IllegalArgumentException("OS " + Platform.getOSName() + " not yet supported");
+ throw new IllegalArgumentException("Native windowing type " + windowingType + " (custom) not yet supported, platform reported native windowing type: "+getNativeWindowType(false));
}
nativeWindowConstructor = ReflectionUtil.getConstructor(
diff --git a/src/nativewindow/classes/jogamp/nativewindow/NullToolkitLock.java b/src/nativewindow/classes/jogamp/nativewindow/NullToolkitLock.java
index 1af6bf2..5fc5fe3 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/NullToolkitLock.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/NullToolkitLock.java
@@ -28,18 +28,18 @@
package jogamp.nativewindow;
+import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.ToolkitLock;
/**
- * Implementing a singleton global recursive {@link javax.media.nativewindow.ToolkitLock}
- * without any locking. Since there is no locking it all,
- * it is intrinsically recursive.
+ * Implementing a singleton global NOP {@link javax.media.nativewindow.ToolkitLock}
+ * without any locking. Since there is no locking it all, it is intrinsically recursive.
*/
public class NullToolkitLock implements ToolkitLock {
-
/** Singleton via {@link NativeWindowFactoryImpl#getNullToolkitLock()} */
protected NullToolkitLock() { }
+ @Override
public final void lock() {
if(TRACE_LOCK) {
System.err.println("NullToolkitLock.lock()");
@@ -47,7 +47,25 @@ public class NullToolkitLock implements ToolkitLock {
}
}
+ @Override
public final void unlock() {
if(TRACE_LOCK) { System.err.println("NullToolkitLock.unlock()"); }
}
+
+ @Override
+ public final void validateLocked() throws RuntimeException {
+ if( NativeWindowFactory.requiresToolkitLock() ) {
+ throw new RuntimeException("NullToolkitLock does not lock, but locking is required.");
+ }
+ }
+
+ @Override
+ public final void dispose() {
+ // nop
+ }
+
+ public String toString() {
+ return "NullToolkitLock[]";
+ }
+
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java b/src/nativewindow/classes/jogamp/nativewindow/ProxySurfaceImpl.java
similarity index 56%
copy from src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java
copy to src/nativewindow/classes/jogamp/nativewindow/ProxySurfaceImpl.java
index 7fc9789..63f56cb 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/ProxySurfaceImpl.java
@@ -26,96 +26,89 @@
* or implied, of JogAmp Community.
*/
-package javax.media.nativewindow;
+package jogamp.nativewindow;
+
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.SurfaceUpdatedListener;
+import javax.media.nativewindow.UpstreamSurfaceHook;
-import jogamp.nativewindow.Debug;
-import jogamp.nativewindow.SurfaceUpdatedHelper;
import com.jogamp.common.util.locks.LockFactory;
import com.jogamp.common.util.locks.RecursiveLock;
-public abstract class ProxySurface implements NativeSurface, MutableSurface {
- public static final boolean DEBUG = Debug.debug("ProxySurface");
-
- /**
- * Implementation specific bitvalue stating the upstream's {@link AbstractGraphicsDevice} is owned by this {@link ProxySurface}.
- * @see #setImplBitfield(int)
- * @see #getImplBitfield()
- */
- public static final int OWN_DEVICE = 1 << 7;
-
- /**
- * Implementation specific bitvalue stating the upstream's {@link NativeSurface} is an invisible window, i.e. maybe incomplete.
- * @see #setImplBitfield(int)
- * @see #getImplBitfield()
- */
- public static final int INVISIBLE_WINDOW = 1 << 8;
-
- /** Interface allowing upstream caller to pass lifecycle actions and size info to a {@link ProxySurface} instance. */
- public interface UpstreamSurfaceHook {
- /** called within {@link ProxySurface#createNotify()} within lock, before using surface. */
- public void create(ProxySurface s);
- /** called within {@link ProxySurface#destroyNotify()} within lock, before clearing fields. */
- public void destroy(ProxySurface s);
-
- /** Returns the width of the upstream surface */
- public int getWidth(ProxySurface s);
- /** Returns the height of the upstream surface */
- public int getHeight(ProxySurface s);
- }
-
+public abstract class ProxySurfaceImpl implements ProxySurface {
private final SurfaceUpdatedHelper surfaceUpdatedHelper = new SurfaceUpdatedHelper();
- private final AbstractGraphicsConfiguration config; // control access due to delegation
- private final UpstreamSurfaceHook upstream;
- public final int initialWidth;
- public final int initialHeight;
+ protected long displayHandle; // convenient ref of config.screen.device.handle
+ private AbstractGraphicsConfiguration config; // control access due to delegation
+ private UpstreamSurfaceHook upstream;
private long surfaceHandle_old;
- protected RecursiveLock surfaceLock = LockFactory.createRecursiveLock();
- protected long displayHandle;
- protected int scrnIndex;
- protected int implBitfield;
+ private RecursiveLock surfaceLock = LockFactory.createRecursiveLock();
+ private int implBitfield;
+ private boolean upstreamSurfaceHookLifecycleEnabled;
/**
* @param cfg the {@link AbstractGraphicsConfiguration} to be used
- * @param initialWidth the initial width
- * @param initialHeight the initial height
+ * @param upstream the {@link UpstreamSurfaceHook} to be used
+ * @param ownsDevice <code>true</code> if this {@link ProxySurface} instance
+ * owns the {@link AbstractGraphicsConfiguration}'s {@link AbstractGraphicsDevice},
+ * otherwise <code>false</code>. Owning the device implies closing it at {@link #destroyNotify()}.
*/
- protected ProxySurface(AbstractGraphicsConfiguration cfg, int initialWidth, int initialHeight, UpstreamSurfaceHook upstream) {
+ protected ProxySurfaceImpl(AbstractGraphicsConfiguration cfg, UpstreamSurfaceHook upstream, boolean ownsDevice) {
if(null == cfg) {
- throw new IllegalArgumentException("null config");
+ throw new IllegalArgumentException("null AbstractGraphicsConfiguration");
+ }
+ if(null == upstream) {
+ throw new IllegalArgumentException("null UpstreamSurfaceHook");
}
this.config = cfg;
- this.upstream = upstream;
- this.initialWidth = initialWidth;
- this.initialHeight = initialHeight;
this.displayHandle=config.getNativeGraphicsConfiguration().getScreen().getDevice().getHandle();
+ this.upstream = upstream;
this.surfaceHandle_old = 0;
this.implBitfield = 0;
+ this.upstreamSurfaceHookLifecycleEnabled = true;
+ if(ownsDevice) {
+ addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_DEVICE );
+ }
}
+ @Override
public final UpstreamSurfaceHook getUpstreamSurfaceHook() { return upstream; }
- /**
- * If a valid {@link UpstreamSurfaceHook} instance is passed in the
- * {@link ProxySurface#ProxySurface(AbstractGraphicsConfiguration, int, int, UpstreamSurfaceHook) constructor},
- * {@link UpstreamSurfaceHook#create(ProxySurface)} is being issued and the proxy surface/window handles shall be set.
- */
- public void createNotify() {
- if(null != upstream) {
+ @Override
+ public void setUpstreamSurfaceHook(UpstreamSurfaceHook hook) {
+ if(null == hook) {
+ throw new IllegalArgumentException("null UpstreamSurfaceHook");
+ }
+ upstream = hook;
+ }
+
+ @Override
+ public final void enableUpstreamSurfaceHookLifecycle(boolean enable) {
+ upstreamSurfaceHookLifecycleEnabled = enable;
+ }
+
+ @Override
+ public void createNotify() {
+ if(upstreamSurfaceHookLifecycleEnabled) {
upstream.create(this);
}
this.displayHandle=config.getNativeGraphicsConfiguration().getScreen().getDevice().getHandle();
this.surfaceHandle_old = 0;
}
-
- /**
- * If a valid {@link UpstreamSurfaceHook} instance is passed in the
- * {@link ProxySurface#ProxySurface(AbstractGraphicsConfiguration, int, int, UpstreamSurfaceHook) constructor},
- * {@link UpstreamSurfaceHook#destroy(ProxySurface)} is being issued and all fields are cleared.
- */
+
+ @Override
public void destroyNotify() {
- if(null != upstream) {
+ if(upstreamSurfaceHookLifecycleEnabled) {
upstream.destroy(this);
+ if( containsUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_DEVICE ) ) {
+ final AbstractGraphicsDevice aDevice = getGraphicsConfiguration().getScreen().getDevice();
+ aDevice.close();
+ clearUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_DEVICE );
+ }
invalidateImpl();
}
this.displayHandle = 0;
@@ -145,6 +138,11 @@ public abstract class ProxySurface implements NativeSurface, MutableSurface {
}
@Override
+ public final void setGraphicsConfiguration(AbstractGraphicsConfiguration cfg) {
+ config = cfg;
+ }
+
+ @Override
public final int getScreenIndex() {
return getGraphicsConfiguration().getScreen().getIndex();
}
@@ -157,18 +155,12 @@ public abstract class ProxySurface implements NativeSurface, MutableSurface {
@Override
public final int getWidth() {
- if(null != upstream) {
- return upstream.getWidth(this);
- }
- return initialWidth;
+ return upstream.getWidth(this);
}
@Override
public final int getHeight() {
- if(null != upstream) {
- return upstream.getHeight(this);
- }
- return initialHeight;
+ return upstream.getHeight(this);
}
@Override
@@ -210,7 +202,7 @@ public abstract class ProxySurface implements NativeSurface, MutableSurface {
if(LOCK_SUCCESS == res && surfaceHandle_old != getSurfaceHandle()) {
res = LOCK_SURFACE_CHANGED;
if(DEBUG) {
- System.err.println("ProxySurface: surface change 0x"+Long.toHexString(surfaceHandle_old)+" -> 0x"+Long.toHexString(getSurfaceHandle()));
+ System.err.println("ProxySurfaceImpl: surface change 0x"+Long.toHexString(surfaceHandle_old)+" -> 0x"+Long.toHexString(getSurfaceHandle()));
// Thread.dumpStack();
}
}
@@ -262,9 +254,73 @@ public abstract class ProxySurface implements NativeSurface, MutableSurface {
return surfaceLock.getOwner();
}
+ public final StringBuilder getUpstreamOptionBits(StringBuilder sink) {
+ if(null == sink) {
+ sink = new StringBuilder();
+ }
+ sink.append("UOB[ ");
+ if(0 == implBitfield) {
+ sink.append("]");
+ return sink;
+ }
+ boolean needsOr = false;
+ if( 0 != ( implBitfield & OPT_PROXY_OWNS_UPSTREAM_SURFACE ) ) {
+ sink.append("OWNS_SURFACE");
+ needsOr = true;
+ }
+ if( 0 != ( implBitfield & OPT_PROXY_OWNS_UPSTREAM_DEVICE ) ) {
+ if(needsOr) {
+ sink.append(" | ");
+ }
+ sink.append("OWNS_DEVICE");
+ needsOr = true;
+ }
+ if( 0 != ( implBitfield & OPT_UPSTREAM_WINDOW_INVISIBLE ) ) {
+ if(needsOr) {
+ sink.append(" | ");
+ }
+ sink.append("WINDOW_INVISIBLE");
+ needsOr = true;
+ }
+ sink.append(" ]");
+ return sink;
+ }
+
@Override
- public abstract String toString();
+ public final int getUpstreamOptionBits() { return implBitfield; }
- public int getImplBitfield() { return implBitfield; }
- public void setImplBitfield(int v) { implBitfield=v; }
+ @Override
+ public final boolean containsUpstreamOptionBits(int v) {
+ return v == ( implBitfield & v ) ;
+ }
+
+ @Override
+ public final void addUpstreamOptionBits(int v) { implBitfield |= v; }
+
+ @Override
+ public final void clearUpstreamOptionBits(int v) { implBitfield &= ~v; }
+
+ @Override
+ public StringBuilder toString(StringBuilder sink) {
+ if(null == sink) {
+ sink = new StringBuilder();
+ }
+ sink.append(getUpstreamSurfaceHook()).
+ append(", displayHandle 0x" + Long.toHexString(getDisplayHandle())).
+ append(", surfaceHandle 0x" + Long.toHexString(getSurfaceHandle())).
+ append(", size " + getWidth() + "x" + getHeight()).append(", ");
+ getUpstreamOptionBits(sink);
+ sink.append(", surfaceLock "+surfaceLock);
+ return sink;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder msg = new StringBuilder();
+ msg.append(getClass().getSimpleName()).append("[ ");
+ toString(msg);
+ msg.append(" ]");
+ return msg.toString();
+ }
+
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/X11ToolkitLock.java b/src/nativewindow/classes/jogamp/nativewindow/ResourceToolkitLock.java
similarity index 58%
rename from src/nativewindow/classes/jogamp/nativewindow/x11/X11ToolkitLock.java
rename to src/nativewindow/classes/jogamp/nativewindow/ResourceToolkitLock.java
index 5166ef5..5b79de0 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/x11/X11ToolkitLock.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/ResourceToolkitLock.java
@@ -1,5 +1,5 @@
/**
- * Copyright 2010 JogAmp Community. All rights reserved.
+ * Copyright 2012 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
@@ -25,7 +25,8 @@
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of JogAmp Community.
*/
-package jogamp.nativewindow.x11;
+
+package jogamp.nativewindow;
import javax.media.nativewindow.ToolkitLock;
@@ -33,38 +34,46 @@ import com.jogamp.common.util.locks.LockFactory;
import com.jogamp.common.util.locks.RecursiveLock;
/**
- * Implementing a recursive {@link javax.media.nativewindow.ToolkitLock}
- * utilizing {@link X11Util#XLockDisplay(long)}.
- * <br>
- * This strategy should not be used in case XInitThreads() is being used,
- * or a higher level toolkit lock is required, ie AWT lock.
+ * Implementing a resource based recursive {@link javax.media.nativewindow.ToolkitLock}.
+ * <p>
+ * A resource handle maybe used within a unique object
+ * and can be synchronized across threads via an instance of ResourceToolkitLock.
+ * </p>
*/
-public class X11ToolkitLock implements ToolkitLock {
- long displayHandle;
- RecursiveLock lock;
-
- public X11ToolkitLock(long displayHandle) {
- this.displayHandle = displayHandle;
- if(!X11Util.isNativeLockAvailable()) {
- lock = LockFactory.createRecursiveLock();
- }
+public class ResourceToolkitLock implements ToolkitLock {
+ public static final ResourceToolkitLock create() {
+ return new ResourceToolkitLock();
}
+ private final RecursiveLock lock;
+
+ private ResourceToolkitLock() {
+ this.lock = LockFactory.createRecursiveLock();
+ }
+
+ @Override
public final void lock() {
- if(TRACE_LOCK) { System.err.println("X11ToolkitLock.lock() - native: "+(null==lock)); }
- if(null == lock) {
- X11Lib.XLockDisplay(displayHandle);
- } else {
- lock.lock();
- }
+ lock.lock();
+ if(TRACE_LOCK) { System.err.println("ResourceToolkitLock.lock()"); }
}
+ @Override
public final void unlock() {
- if(TRACE_LOCK) { System.err.println("X11ToolkitLock.unlock() - native: "+(null==lock)); }
- if(null == lock) {
- X11Lib.XUnlockDisplay(displayHandle);
- } else {
- lock.unlock();
- }
+ if(TRACE_LOCK) { System.err.println("ResourceToolkitLock.unlock()"); }
+ lock.unlock(); // implicit lock validation
+ }
+
+ @Override
+ public final void validateLocked() throws RuntimeException {
+ lock.validateLocked();
+ }
+
+ @Override
+ public final void dispose() {
+ // nop
+ }
+
+ public String toString() {
+ return "ResourceToolkitLock[obj 0x"+Integer.toHexString(hashCode())+", isOwner "+lock.isOwner(Thread.currentThread())+", "+lock.toString()+"]";
}
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/SharedResourceToolkitLock.java b/src/nativewindow/classes/jogamp/nativewindow/SharedResourceToolkitLock.java
new file mode 100644
index 0000000..94d12e6
--- /dev/null
+++ b/src/nativewindow/classes/jogamp/nativewindow/SharedResourceToolkitLock.java
@@ -0,0 +1,148 @@
+/**
+ * Copyright 2012 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community OR
+ * CONTRIBUTORS 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.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package jogamp.nativewindow;
+
+import java.util.Iterator;
+
+import javax.media.nativewindow.ToolkitLock;
+
+import com.jogamp.common.util.LongObjectHashMap;
+import com.jogamp.common.util.locks.LockFactory;
+import com.jogamp.common.util.locks.RecursiveLock;
+
+/**
+ * Implementing a shared resource based recursive {@link javax.media.nativewindow.ToolkitLock}.
+ * <p>
+ * A resource handle maybe used within many objects
+ * and can be synchronized across threads via an unique instance of SharedResourceToolkitLock.
+ * </p>
+ * <p>
+ * Implementation holds a synchronized map from handle to reference counted {@link SharedResourceToolkitLock}.
+ * New elements are added via {@link #get(long)} if new
+ * and removed via {@link #dispose()} if no more referenced.
+ * </p>
+ */
+public class SharedResourceToolkitLock implements ToolkitLock {
+ private static final LongObjectHashMap handle2Lock;
+ static {
+ handle2Lock = new LongObjectHashMap();
+ handle2Lock.setKeyNotFoundValue(null);
+ }
+
+ /**
+ * @return number of unclosed EGL Displays.<br>
+ */
+ public static int shutdown(boolean verbose) {
+ if(DEBUG || verbose || handle2Lock.size() > 0 ) {
+ System.err.println("SharedResourceToolkitLock: Shutdown (open: "+handle2Lock.size()+")");
+ if(DEBUG) {
+ Thread.dumpStack();
+ }
+ if( handle2Lock.size() > 0) {
+ dumpOpenDisplayConnections();
+ }
+ }
+ return handle2Lock.size();
+ }
+
+ public static void dumpOpenDisplayConnections() {
+ System.err.println("SharedResourceToolkitLock: Open ResourceToolkitLock's: "+handle2Lock.size());
+ int i=0;
+ for(Iterator<LongObjectHashMap.Entry> iter = handle2Lock.iterator(); iter.hasNext(); i++) {
+ final LongObjectHashMap.Entry e = iter.next();
+ System.err.println("SharedResourceToolkitLock: Open["+i+"]: "+e.value);
+ }
+ }
+
+ public static final SharedResourceToolkitLock get(long handle) {
+ SharedResourceToolkitLock res;
+ synchronized(handle2Lock) {
+ res = (SharedResourceToolkitLock) handle2Lock.get(handle);
+ if( null == res ) {
+ res = new SharedResourceToolkitLock(handle);
+ res.refCount++;
+ handle2Lock.put(handle, res);
+ if(DEBUG || TRACE_LOCK) { System.err.println("SharedResourceToolkitLock.get() * NEW *: "+res); }
+ } else {
+ res.refCount++;
+ if(DEBUG || TRACE_LOCK) { System.err.println("SharedResourceToolkitLock.get() * EXIST *: "+res); }
+ }
+ }
+ return res;
+ }
+
+ private final RecursiveLock lock;
+ private final long handle;
+ private volatile int refCount;
+
+ private SharedResourceToolkitLock(long handle) {
+ this.lock = LockFactory.createRecursiveLock();
+ this.handle = handle;
+ this.refCount = 0;
+ }
+
+
+ @Override
+ public final void lock() {
+ lock.lock();
+ if(TRACE_LOCK) { System.err.println("SharedResourceToolkitLock.lock()"); }
+ }
+
+ @Override
+ public final void unlock() {
+ if(TRACE_LOCK) { System.err.println("SharedResourceToolkitLock.unlock()"); }
+ lock.unlock();
+ }
+
+ @Override
+ public final void validateLocked() throws RuntimeException {
+ lock.validateLocked();
+ }
+
+ @Override
+ public final void dispose() {
+ if(0 < refCount) { // volatile OK
+ synchronized(handle2Lock) {
+ refCount--;
+ if(0 == refCount) {
+ if(DEBUG || TRACE_LOCK) { System.err.println("SharedResourceToolkitLock.dispose() * REMOV *: "+this); }
+ handle2Lock.remove(handle);
+ } else {
+ if(DEBUG || TRACE_LOCK) { System.err.println("SharedResourceToolkitLock.dispose() * DOWN *: "+this); }
+ }
+ }
+ } else {
+ if(DEBUG || TRACE_LOCK) { System.err.println("SharedResourceToolkitLock.dispose() * NULL *: "+this); }
+ }
+ }
+
+ public String toString() {
+ return "SharedResourceToolkitLock[refCount "+refCount+", handle 0x"+Long.toHexString(handle)+", obj 0x"+Integer.toHexString(hashCode())+", isOwner "+lock.isOwner(Thread.currentThread())+", "+lock.toString()+"]";
+ }
+}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/ToolkitProperties.java b/src/nativewindow/classes/jogamp/nativewindow/ToolkitProperties.java
new file mode 100644
index 0000000..ed23def
--- /dev/null
+++ b/src/nativewindow/classes/jogamp/nativewindow/ToolkitProperties.java
@@ -0,0 +1,47 @@
+package jogamp.nativewindow;
+
+import javax.media.nativewindow.NativeWindowFactory;
+
+/**
+ * Marker interface.
+ * <p>
+ * Implementation requires to provide static methods:
+ * <pre>
+ public static void initSingleton() {}
+
+ public static void shutdown() {}
+
+ public static boolean requiresToolkitLock() {}
+
+ public static boolean hasThreadingIssues() {}
+ * </pre>
+ * Above static methods are invoked by {@link NativeWindowFactory#initSingleton()},
+ * or {@link NativeWindowFactory#shutdown()} via reflection.
+ * </p>
+ */
+public interface ToolkitProperties {
+
+ /**
+ * Called by {@link NativeWindowFactory#initSingleton()}
+ */
+ // void initSingleton();
+
+ /**
+ * Cleanup resources.
+ * <p>
+ * Called by {@link NativeWindowFactory#shutdown()}
+ * </p>
+ */
+ // void shutdown();
+
+ /**
+ * Called by {@link NativeWindowFactory#initSingleton()}
+ */
+ // boolean requiresToolkitLock();
+
+ /**
+ * Called by {@link NativeWindowFactory#initSingleton()}
+ */
+ // boolean hasThreadingIssues();
+
+}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/WrappedSurface.java b/src/nativewindow/classes/jogamp/nativewindow/WrappedSurface.java
similarity index 54%
rename from src/nativewindow/classes/com/jogamp/nativewindow/WrappedSurface.java
rename to src/nativewindow/classes/jogamp/nativewindow/WrappedSurface.java
index b7f6ba4..e544bc6 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/WrappedSurface.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/WrappedSurface.java
@@ -26,17 +26,46 @@
* or implied, of JogAmp Community.
*/
-package com.jogamp.nativewindow;
+package jogamp.nativewindow;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
-public class WrappedSurface extends ProxySurface {
- protected long surfaceHandle;
+import com.jogamp.nativewindow.UpstreamSurfaceHookMutableSize;
- public WrappedSurface(AbstractGraphicsConfiguration cfg, long handle, int initialWidth, int initialHeight, UpstreamSurfaceHook upstream) {
- super(cfg, initialWidth, initialHeight, upstream);
- surfaceHandle=handle;
+public class WrappedSurface extends ProxySurfaceImpl {
+ protected long surfaceHandle;
+
+ /**
+ * Utilizes a {@link UpstreamSurfaceHook.MutableSize} to hold the size information,
+ * which is being passed to the {@link ProxySurface} instance.
+ *
+ * @param cfg the {@link AbstractGraphicsConfiguration} to be used
+ * @param handle the wrapped pre-existing native surface handle, maybe 0 if not yet determined
+ * @param initialWidth
+ * @param initialHeight
+ * @param ownsDevice <code>true</code> if this {@link ProxySurface} instance
+ * owns the {@link AbstractGraphicsConfiguration}'s {@link AbstractGraphicsDevice},
+ * otherwise <code>false</code>. Owning the device implies closing it at {@link #destroyNotify()}.
+ */
+ public WrappedSurface(AbstractGraphicsConfiguration cfg, long handle, int initialWidth, int initialHeight, boolean ownsDevice) {
+ super(cfg, new UpstreamSurfaceHookMutableSize(initialWidth, initialHeight), ownsDevice);
+ surfaceHandle=handle;
+ }
+
+ /**
+ * @param cfg the {@link AbstractGraphicsConfiguration} to be used
+ * @param handle the wrapped pre-existing native surface handle, maybe 0 if not yet determined
+ * @param upstream the {@link UpstreamSurfaceHook} to be used
+ * @param ownsDevice <code>true</code> if this {@link ProxySurface} instance
+ * owns the {@link AbstractGraphicsConfiguration}'s {@link AbstractGraphicsDevice},
+ * otherwise <code>false</code>.
+ */
+ public WrappedSurface(AbstractGraphicsConfiguration cfg, long handle, UpstreamSurfaceHook upstream, boolean ownsDevice) {
+ super(cfg, upstream, ownsDevice);
+ surfaceHandle=handle;
}
@Override
@@ -63,16 +92,4 @@ public class WrappedSurface extends ProxySurface {
protected final void unlockSurfaceImpl() {
}
- @Override
- public String toString() {
- final UpstreamSurfaceHook ush = getUpstreamSurfaceHook();
- final String ush_s = null != ush ? ( ush.getClass().getName() + ": " + ush ) : "nil";
-
- return "WrappedSurface[config " + getPrivateGraphicsConfiguration()+
- ", displayHandle 0x" + Long.toHexString(getDisplayHandle()) +
- ", surfaceHandle 0x" + Long.toHexString(getSurfaceHandle()) +
- ", size " + getWidth() + "x" + getHeight() +
- ", surfaceLock "+surfaceLock+
- ", upstreamSurfaceHook "+ush_s+"]";
- }
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTJNILibLoader.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTJNILibLoader.java
index 2377c2b..f579da2 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTJNILibLoader.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTJNILibLoader.java
@@ -60,7 +60,7 @@ public class JAWTJNILibLoader extends NWJNILibLoader {
// ensure references from jogl_awt shared object
// will succeed since JAWT shared object isn't in
// default library path
- if ( ! NativeWindowFactory.TYPE_MACOSX.equals( NativeWindowFactory.getNativeWindowType(false) ) ) {
+ if ( NativeWindowFactory.TYPE_MACOSX != NativeWindowFactory.getNativeWindowType(false) ) {
try {
loadLibrary("jawt", null, true, JAWTJNILibLoader.class.getClassLoader());
} catch (Throwable t) {
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java
index 36d7c37..349da8e 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java
@@ -48,6 +48,7 @@ import java.util.ArrayList;
import java.util.Map;
import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.ToolkitLock;
import jogamp.nativewindow.Debug;
@@ -78,6 +79,9 @@ public class JAWTUtil {
private static final Method sunToolkitAWTLockMethod;
private static final Method sunToolkitAWTUnlockMethod;
private static final boolean hasSunToolkitAWTLock;
+
+ private static volatile Thread exclusiveOwnerThread;
+ private static int lockCounter;
private static final ToolkitLock jawtToolkitLock;
@@ -228,14 +232,25 @@ public class JAWTUtil {
}
hasSunToolkitAWTLock = _hasSunToolkitAWTLock;
// hasSunToolkitAWTLock = false;
+ exclusiveOwnerThread = null;
+ lockCounter = 0;
jawtToolkitLock = new ToolkitLock() {
public final void lock() {
JAWTUtil.lockToolkit();
+ if(TRACE_LOCK) { System.err.println("JAWTToolkitLock.lock()"); }
}
public final void unlock() {
+ if(TRACE_LOCK) { System.err.println("JAWTToolkitLock.unlock()"); }
JAWTUtil.unlockToolkit();
}
+ @Override
+ public final void validateLocked() throws RuntimeException {
+ JAWTUtil.validateLocked();
+ }
+ public final void dispose() {
+ // nop
+ }
};
// trigger native AWT toolkit / properties initialization
@@ -271,10 +286,18 @@ public class JAWTUtil {
}
}
+ /**
+ * Called by {@link NativeWindowFactory#initSingleton()}
+ */
public static void initSingleton() {
// just exist to ensure static init has been run
}
-
+
+ /**
+ * Called by {@link NativeWindowFactory#shutdown()}
+ */
+ public static void shutdown() {
+ }
public static boolean hasJava2D() {
return j2dExist;
@@ -300,7 +323,7 @@ public class JAWTUtil {
* JAWT's native Lock() function calls SunToolkit.awtLock(),
* which just uses AWT's global ReentrantLock.<br>
*/
- private static void awtLock() {
+ private static final void awtLock() {
if(hasSunToolkitAWTLock) {
try {
sunToolkitAWTLockMethod.invoke(null, (Object[])null);
@@ -310,6 +333,10 @@ public class JAWTUtil {
} else {
jawtLockObject.Lock();
}
+ if(0 == lockCounter) {
+ exclusiveOwnerThread = Thread.currentThread();
+ }
+ lockCounter++;
}
/**
@@ -318,7 +345,12 @@ public class JAWTUtil {
* JAWT's native Unlock() function calls SunToolkit.awtUnlock(),
* which just uses AWT's global ReentrantLock.<br>
*/
- private static void awtUnlock() {
+ private static final void awtUnlock() {
+ awtValidateLocked();
+ lockCounter--;
+ if(0 == lockCounter) {
+ exclusiveOwnerThread = null;
+ }
if(hasSunToolkitAWTLock) {
try {
sunToolkitAWTUnlockMethod.invoke(null, (Object[])null);
@@ -330,6 +362,16 @@ public class JAWTUtil {
}
}
+ private static final void awtValidateLocked() throws RuntimeException {
+ final Thread ct = Thread.currentThread();
+ if( ct != exclusiveOwnerThread ) {
+ if ( null == exclusiveOwnerThread ) {
+ throw new RuntimeException(ct.getName()+": JAWT-ToolkitLock not locked");
+ }
+ throw new RuntimeException(ct.getName()+": Not JAWT-ToolkitLock owner. Owner is "+exclusiveOwnerThread.getName());
+ }
+ }
+
public static void lockToolkit() throws NativeWindowException {
if(ToolkitLock.TRACE_LOCK) { System.err.println("JAWTUtil-ToolkitLock.lock()"); }
if(!headlessMode && !isJava2DQueueFlusherThread()) {
@@ -343,6 +385,13 @@ public class JAWTUtil {
awtUnlock();
}
}
+
+ public static final void validateLocked() throws RuntimeException {
+ if(!headlessMode && !isJava2DQueueFlusherThread()) {
+ awtValidateLocked();
+ }
+ }
+
public static ToolkitLock getJAWTToolkitLock() {
return jawtToolkitLock;
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java
index e81d61e..5fd2422 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java
@@ -51,7 +51,6 @@ import javax.media.nativewindow.NativeWindowException;
import javax.media.nativewindow.MutableSurface;
import javax.media.nativewindow.util.Point;
-import com.jogamp.nativewindow.MutableGraphicsConfiguration;
import com.jogamp.nativewindow.awt.JAWTWindow;
import jogamp.nativewindow.jawt.JAWT;
@@ -71,17 +70,18 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface {
}
protected void invalidateNative() {
- surfaceHandle=0;
+ offscreenSurfaceHandle=0;
+ offscreenSurfaceHandleSet=false;
if(isOffscreenLayerSurfaceEnabled()) {
if(0 != rootSurfaceLayerHandle) {
OSXUtil.DestroyCALayer(rootSurfaceLayerHandle);
rootSurfaceLayerHandle = 0;
}
- if(0 != drawable) {
- OSXUtil.DestroyNSWindow(drawable);
- drawable = 0;
+ if(0 != windowHandle) {
+ OSXUtil.DestroyNSWindow(windowHandle);
}
}
+ windowHandle=0;
}
protected void attachSurfaceLayerImpl(final long layerHandle) {
@@ -92,8 +92,14 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface {
OSXUtil.RemoveCASublayer(rootSurfaceLayerHandle, layerHandle);
}
- public long getSurfaceHandle() {
- return isOffscreenLayerSurfaceEnabled() ? surfaceHandle : super.getSurfaceHandle() ;
+ @Override
+ public final long getWindowHandle() {
+ return windowHandle;
+ }
+
+ @Override
+ public final long getSurfaceHandle() {
+ return offscreenSurfaceHandleSet ? offscreenSurfaceHandle : drawable /* super.getSurfaceHandle() */ ;
}
public void setSurfaceHandle(long surfaceHandle) {
@@ -103,7 +109,8 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface {
if(DEBUG) {
System.err.println("MacOSXJAWTWindow.setSurfaceHandle(): 0x"+Long.toHexString(surfaceHandle));
}
- this.surfaceHandle = surfaceHandle;
+ this.offscreenSurfaceHandle = surfaceHandle;
+ this.offscreenSurfaceHandleSet = true;
}
protected JAWT fetchJAWTImpl() throws NativeWindowException {
@@ -167,6 +174,7 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface {
unlockSurfaceImpl();
return NativeWindow.LOCK_SURFACE_NOT_READY;
} else {
+ windowHandle = OSXUtil.GetNSWindow(drawable);
ret = NativeWindow.LOCK_SUCCESS;
}
} else {
@@ -177,36 +185,46 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface {
* The actual surface/ca-layer shall be created/attached
* by the upper framework (JOGL) since they require more information.
*/
+ String errMsg = null;
if(0 == drawable) {
- drawable = OSXUtil.CreateNSWindow(0, 0, getBounds().getWidth(), getBounds().getHeight());
- if(0 == drawable) {
- unlockSurfaceImpl();
- throw new NativeWindowException("Unable to created dummy NSWindow (layered case)");
+ windowHandle = OSXUtil.CreateNSWindow(0, 0, 64, 64);
+ if(0 == windowHandle) {
+ errMsg = "Unable to create dummy NSWindow (layered case)";
+ } else {
+ drawable = OSXUtil.GetNSView(windowHandle);
+ if(0 == drawable) {
+ errMsg = "Null NSView of NSWindow 0x"+Long.toHexString(windowHandle);
+ }
+ }
+ if(null == errMsg) {
+ // fix caps reflecting offscreen! (no GL available here ..)
+ Capabilities caps = (Capabilities) getGraphicsConfiguration().getChosenCapabilities().cloneMutable();
+ caps.setOnscreen(false);
+ setChosenCapabilities(caps);
}
- // fix caps reflecting offscreen!
- Capabilities caps = (Capabilities) getPrivateGraphicsConfiguration().getChosenCapabilities().cloneMutable();
- caps.setOnscreen(false);
- getPrivateGraphicsConfiguration().setChosenCapabilities(caps);
- caps = (Capabilities) getGraphicsConfiguration().getChosenCapabilities().cloneMutable();
- caps.setOnscreen(false);
- ((MutableGraphicsConfiguration)getGraphicsConfiguration()).setChosenCapabilities(caps);
}
- if(0 == rootSurfaceLayerHandle) {
- rootSurfaceLayerHandle = OSXUtil.CreateCALayer(bounds.getX(), bounds.getY(), bounds.getWidth(), bounds.getHeight());
- if(0 == rootSurfaceLayerHandle) {
- OSXUtil.DestroyNSWindow(drawable);
- drawable = 0;
- unlockSurfaceImpl();
- throw new NativeWindowException("Could not create root CALayer: "+this);
+ if(null == errMsg) {
+ if(0 == rootSurfaceLayerHandle) {
+ rootSurfaceLayerHandle = OSXUtil.CreateCALayer(bounds.getX(), bounds.getY(), bounds.getWidth(), bounds.getHeight());
+ if(0 == rootSurfaceLayerHandle) {
+ errMsg = "Could not create root CALayer";
+ } else if(!SetJAWTRootSurfaceLayer0(dsi.getBuffer(), rootSurfaceLayerHandle)) {
+ errMsg = "Could not set JAWT rootSurfaceLayerHandle 0x"+Long.toHexString(rootSurfaceLayerHandle);
+ }
}
- if(!SetJAWTRootSurfaceLayer0(dsi.getBuffer(), rootSurfaceLayerHandle)) {
+ }
+ if(null != errMsg) {
+ if(0 != rootSurfaceLayerHandle) {
OSXUtil.DestroyCALayer(rootSurfaceLayerHandle);
rootSurfaceLayerHandle = 0;
- OSXUtil.DestroyNSWindow(drawable);
- drawable = 0;
- unlockSurfaceImpl();
- throw new NativeWindowException("Could not set JAWT rootSurfaceLayerHandle: "+this);
}
+ if(0 != windowHandle) {
+ OSXUtil.DestroyNSWindow(windowHandle);
+ windowHandle = 0;
+ }
+ drawable = 0;
+ unlockSurfaceImpl();
+ throw new NativeWindowException(errMsg+": "+this);
}
ret = NativeWindow.LOCK_SUCCESS;
}
@@ -264,7 +282,9 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface {
private long rootSurfaceLayerHandle = 0; // attached to the JAWT_SurfaceLayer
- private long surfaceHandle = 0;
+ private long windowHandle = 0;
+ private long offscreenSurfaceHandle = 0;
+ private boolean offscreenSurfaceHandleSet = false;
// Workaround for instance of 4796548
private boolean firstLock = true;
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java
index 736718d..4678092 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java
@@ -127,7 +127,8 @@ public class X11JAWTWindow extends JAWTWindow {
}
protected Point getLocationOnScreenNativeImpl(int x, int y) {
- return X11Lib.GetRelativeLocation( getDisplayHandle(), getScreenIndex(), getWindowHandle(), 0 /*root win*/, x, y);
+ // surface is locked and hence the device
+ return X11Lib.GetRelativeLocation(getDisplayHandle(), getScreenIndex(), getWindowHandle(), 0 /*root win*/, x, y);
}
// Variables for lockSurface/unlockSurface
diff --git a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXDummyUpstreamSurfaceHook.java b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXDummyUpstreamSurfaceHook.java
new file mode 100644
index 0000000..de3206c
--- /dev/null
+++ b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXDummyUpstreamSurfaceHook.java
@@ -0,0 +1,56 @@
+package jogamp.nativewindow.macosx;
+
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
+
+import com.jogamp.nativewindow.UpstreamSurfaceHookMutableSize;
+
+public class OSXDummyUpstreamSurfaceHook extends UpstreamSurfaceHookMutableSize {
+ long nsWindow;
+
+ /**
+ * @param width the initial width as returned by {@link NativeSurface#getWidth()} via {@link UpstreamSurfaceHook#getWidth(ProxySurface)},
+ * not the actual dummy surface width.
+ * The latter is platform specific and small
+ * @param height the initial height as returned by {@link NativeSurface#getHeight()} via {@link UpstreamSurfaceHook#getHeight(ProxySurface)},
+ * not the actual dummy surface height,
+ * The latter is platform specific and small
+ */
+ public OSXDummyUpstreamSurfaceHook(int width, int height) {
+ super(width, height);
+ nsWindow = 0;
+ }
+
+ @Override
+ public final void create(ProxySurface s) {
+ if(0 == nsWindow && 0 == s.getSurfaceHandle()) {
+ nsWindow = OSXUtil.CreateNSWindow(0, 0, 64, 64);
+ if(0 == nsWindow) {
+ throw new NativeWindowException("Error NS window 0");
+ }
+ long nsView = OSXUtil.GetNSView(nsWindow);
+ if(0 == nsView) {
+ throw new NativeWindowException("Error NS view 0");
+ }
+ s.setSurfaceHandle(nsView);
+ s.addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );
+ }
+ s.addUpstreamOptionBits(ProxySurface.OPT_UPSTREAM_WINDOW_INVISIBLE);
+ }
+
+ @Override
+ public final void destroy(ProxySurface s) {
+ if( s.containsUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE ) ) {
+ if( 0 == nsWindow || 0 == s.getSurfaceHandle() ) {
+ throw new InternalError("Owns upstream surface, but no OSX view/window: "+s+", nsWindow 0x"+Long.toHexString(nsWindow));
+ }
+ OSXUtil.DestroyNSWindow(nsWindow);
+ nsWindow = 0;
+ s.setSurfaceHandle(0);
+ s.clearUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );
+ }
+ }
+
+}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
index 894084f..a195f13 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
@@ -28,42 +28,64 @@
package jogamp.nativewindow.macosx;
import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.util.Insets;
import javax.media.nativewindow.util.Point;
import jogamp.nativewindow.Debug;
import jogamp.nativewindow.NWJNILibLoader;
+import jogamp.nativewindow.ToolkitProperties;
-public class OSXUtil {
+public class OSXUtil implements ToolkitProperties {
private static boolean isInit = false;
private static final boolean DEBUG = Debug.debug("OSXUtil");
- public static synchronized void initSingleton(boolean firstX11ActionOnProcess) {
+ /**
+ * Called by {@link NativeWindowFactory#initSingleton()}
+ * @see ToolkitProperties
+ */
+ public static synchronized void initSingleton() {
if(!isInit) {
+ if(DEBUG) {
+ System.out.println("OSXUtil.initSingleton()");
+ }
if(!NWJNILibLoader.loadNativeWindow("macosx")) {
throw new NativeWindowException("NativeWindow MacOSX native library load error.");
}
if( !initIDs0() ) {
throw new NativeWindowException("MacOSX: Could not initialized native stub");
- }
-
- if(DEBUG) {
- System.out.println("OSX.isFirstX11ActionOnProcess: "+firstX11ActionOnProcess);
- }
-
+ }
isInit = true;
}
}
- public static boolean requiresToolkitLock() {
- return false;
- }
+ /**
+ * Called by {@link NativeWindowFactory#shutdown()}
+ * @see ToolkitProperties
+ */
+ public static void shutdown() { }
+
+ /**
+ * Called by {@link NativeWindowFactory#initSingleton()}
+ * @see ToolkitProperties
+ */
+ public static boolean requiresToolkitLock() { return false; }
+
+ /**
+ * Called by {@link NativeWindowFactory#initSingleton()}
+ * @see ToolkitProperties
+ */
+ public static final boolean hasThreadingIssues() { return false; }
public static boolean isNSView(long object) {
return isNSView0(object);
}
+ public static boolean isNSWindow(long object) {
+ return isNSWindow0(object);
+ }
+
/**
* In case the <code>windowOrView</code> is top-level,
* you shall set <code>topLevel</code> to true where
@@ -106,6 +128,9 @@ public class OSXUtil {
public static long GetNSView(long nsWindow) {
return GetNSView0(nsWindow);
}
+ public static long GetNSWindow(long nsView) {
+ return GetNSWindow0(nsView);
+ }
public static long CreateCALayer(int x, int y, int width, int height) {
return CreateCALayer0(x, y, width, height);
@@ -141,6 +166,11 @@ public class OSXUtil {
return IsMainThread0();
}
+ /** Returns the screen refresh rate in Hz. If unavailable, returns 60Hz. */
+ public static int GetScreenRefreshRate(int scrn_idx) {
+ return GetScreenRefreshRate0(scrn_idx);
+ }
+
/***
private static boolean isAWTEDTMainThreadInit = false;
private static boolean isAWTEDTMainThread;
@@ -164,15 +194,18 @@ public class OSXUtil {
private static native boolean initIDs0();
private static native boolean isNSView0(long object);
+ private static native boolean isNSWindow0(long object);
private static native Object GetLocationOnScreen0(long windowOrView, int src_x, int src_y);
private static native Object GetInsets0(long windowOrView);
private static native long CreateNSWindow0(int x, int y, int width, int height);
private static native void DestroyNSWindow0(long nsWindow);
private static native long GetNSView0(long nsWindow);
+ private static native long GetNSWindow0(long nsView);
private static native long CreateCALayer0(int x, int y, int width, int height);
private static native void AddCASublayer0(long rootCALayer, long subCALayer);
private static native void RemoveCASublayer0(long rootCALayer, long subCALayer);
private static native void DestroyCALayer0(long caLayer);
private static native void RunOnMainThread0(boolean waitUntilDone, Runnable runnable);
private static native boolean IsMainThread0();
+ private static native int GetScreenRefreshRate0(int scrn_idx);
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/windows/GDIDummyUpstreamSurfaceHook.java b/src/nativewindow/classes/jogamp/nativewindow/windows/GDIDummyUpstreamSurfaceHook.java
new file mode 100644
index 0000000..aa5f3da
--- /dev/null
+++ b/src/nativewindow/classes/jogamp/nativewindow/windows/GDIDummyUpstreamSurfaceHook.java
@@ -0,0 +1,50 @@
+package jogamp.nativewindow.windows;
+
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
+
+import com.jogamp.nativewindow.UpstreamSurfaceHookMutableSize;
+
+public class GDIDummyUpstreamSurfaceHook extends UpstreamSurfaceHookMutableSize {
+ /**
+ * @param width the initial width as returned by {@link NativeSurface#getWidth()} via {@link UpstreamSurfaceHook#getWidth(ProxySurface)},
+ * not the actual dummy surface width.
+ * The latter is platform specific and small
+ * @param height the initial height as returned by {@link NativeSurface#getHeight()} via {@link UpstreamSurfaceHook#getHeight(ProxySurface)},
+ * not the actual dummy surface height,
+ * The latter is platform specific and small
+ */
+ public GDIDummyUpstreamSurfaceHook(int width, int height) {
+ super(width, height);
+ }
+
+ @Override
+ public final void create(ProxySurface s) {
+ final GDISurface ms = (GDISurface)s;
+ if(0 == ms.getWindowHandle()) {
+ final long windowHandle = GDIUtil.CreateDummyWindow(0, 0, 64, 64);
+ if(0 == windowHandle) {
+ throw new NativeWindowException("Error windowHandle 0, werr: "+GDI.GetLastError());
+ }
+ ms.setWindowHandle(windowHandle);
+ ms.addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );
+ }
+ s.addUpstreamOptionBits(ProxySurface.OPT_UPSTREAM_WINDOW_INVISIBLE);
+ }
+
+ @Override
+ public final void destroy(ProxySurface s) {
+ final GDISurface ms = (GDISurface)s;
+ if( ms.containsUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE ) ) {
+ if( 0 == ms.getWindowHandle() ) {
+ throw new InternalError("Owns upstream surface, but no GDI window: "+ms);
+ }
+ GDI.ShowWindow(ms.getWindowHandle(), GDI.SW_HIDE);
+ GDIUtil.DestroyDummyWindow(ms.getWindowHandle());
+ ms.setWindowHandle(0);
+ ms.clearUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );
+ }
+ }
+}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/windows/GDISurface.java b/src/nativewindow/classes/jogamp/nativewindow/windows/GDISurface.java
index e368aa6..3db2b5f 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/windows/GDISurface.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/windows/GDISurface.java
@@ -29,9 +29,13 @@
package jogamp.nativewindow.windows;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeWindowException;
import javax.media.nativewindow.ProxySurface;
-import javax.media.nativewindow.ProxySurface.UpstreamSurfaceHook;
+import javax.media.nativewindow.UpstreamSurfaceHook;
+
+import jogamp.nativewindow.ProxySurfaceImpl;
+import jogamp.nativewindow.windows.GDI;
/**
@@ -40,12 +44,20 @@ import javax.media.nativewindow.ProxySurface.UpstreamSurfaceHook;
* The latter will get and release the HDC.
* The size via getWidth()/getHeight() is invalid.
*/
-public class GDISurface extends ProxySurface {
+public class GDISurface extends ProxySurfaceImpl {
protected long windowHandle;
protected long surfaceHandle;
- public GDISurface(AbstractGraphicsConfiguration cfg, long windowHandle, int initialWidth, int initialHeight, UpstreamSurfaceHook upstream) {
- super(cfg, initialWidth, initialHeight, upstream);
+ /**
+ * @param cfg the {@link AbstractGraphicsConfiguration} to be used
+ * @param windowHandle the wrapped pre-existing native window handle, maybe 0 if not yet determined
+ * @param upstream the {@link UpstreamSurfaceHook} to be used
+ * @param ownsDevice <code>true</code> if this {@link ProxySurface} instance
+ * owns the {@link AbstractGraphicsConfiguration}'s {@link AbstractGraphicsDevice},
+ * otherwise <code>false</code>. Owning the device implies closing it at {@link #destroyNotify()}.
+ */
+ public GDISurface(AbstractGraphicsConfiguration cfg, long windowHandle, UpstreamSurfaceHook upstream, boolean ownsDevice) {
+ super(cfg, upstream, ownsDevice);
this.windowHandle=windowHandle;
this.surfaceHandle=0;
}
@@ -114,18 +126,4 @@ public class GDISurface extends ProxySurface {
final public long getSurfaceHandle() {
return surfaceHandle;
}
-
- @Override
- final public String toString() {
- final UpstreamSurfaceHook ush = getUpstreamSurfaceHook();
- final String ush_s = null != ush ? ( ush.getClass().getName() + ": " + ush ) : "nil";
- return getClass().getSimpleName()+"[config "+getPrivateGraphicsConfiguration()+
- ", displayHandle 0x"+Long.toHexString(getDisplayHandle())+
- ", windowHandle 0x"+Long.toHexString(windowHandle)+
- ", surfaceHandle 0x"+Long.toHexString(getSurfaceHandle())+
- ", size "+getWidth()+"x"+getHeight()+
- ", surfaceLock "+surfaceLock+
- ", upstreamSurfaceHook "+ush_s+"]";
- }
-
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java b/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java
index d17a189..2f4e183 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java
@@ -29,43 +29,63 @@ package jogamp.nativewindow.windows;
import javax.media.nativewindow.util.Point;
import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.NativeWindowFactory;
import jogamp.nativewindow.NWJNILibLoader;
import jogamp.nativewindow.Debug;
+import jogamp.nativewindow.ToolkitProperties;
import jogamp.nativewindow.x11.X11Util;
-public class GDIUtil {
+public class GDIUtil implements ToolkitProperties {
private static final boolean DEBUG = Debug.debug("GDIUtil");
private static final String dummyWindowClassNameBase = "_dummyWindow_clazz" ;
private static RegisteredClassFactory dummyWindowClassFactory;
private static boolean isInit = false;
- public static synchronized void initSingleton(boolean firstX11ActionOnProcess) {
+ /**
+ * Called by {@link NativeWindowFactory#initSingleton()}
+ * @see ToolkitProperties
+ */
+ public static synchronized void initSingleton() {
if(!isInit) {
synchronized(X11Util.class) {
if(!isInit) {
- isInit = true;
+ if(DEBUG) {
+ System.out.println("GDI.initSingleton()");
+ }
if(!NWJNILibLoader.loadNativeWindow("win32")) {
throw new NativeWindowException("NativeWindow Windows native library load error.");
}
-
if( !initIDs0() ) {
throw new NativeWindowException("GDI: Could not initialized native stub");
}
-
- if(DEBUG) {
- System.out.println("GDI.isFirstX11ActionOnProcess: "+firstX11ActionOnProcess);
- }
-
- dummyWindowClassFactory = new RegisteredClassFactory(dummyWindowClassNameBase, getDummyWndProc0());
+ dummyWindowClassFactory = new RegisteredClassFactory(dummyWindowClassNameBase, getDummyWndProc0());
+ isInit = true;
}
}
}
}
+ /**
+ * Called by {@link NativeWindowFactory#shutdown()}
+ * @see ToolkitProperties
+ */
+ public static void shutdown() {
+ }
+
+ /**
+ * Called by {@link NativeWindowFactory#initSingleton()}
+ * @see ToolkitProperties
+ */
public static boolean requiresToolkitLock() { return false; }
+ /**
+ * Called by {@link NativeWindowFactory#initSingleton()}
+ * @see ToolkitProperties
+ */
+ public static final boolean hasThreadingIssues() { return false; }
+
private static RegisteredClass dummyWindowClass = null;
private static Object dummyWindowSync = new Object();
diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/X11DummyUpstreamSurfaceHook.java b/src/nativewindow/classes/jogamp/nativewindow/x11/X11DummyUpstreamSurfaceHook.java
new file mode 100644
index 0000000..67a33e5
--- /dev/null
+++ b/src/nativewindow/classes/jogamp/nativewindow/x11/X11DummyUpstreamSurfaceHook.java
@@ -0,0 +1,70 @@
+package jogamp.nativewindow.x11;
+
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
+
+import jogamp.nativewindow.x11.X11Lib;
+
+import com.jogamp.nativewindow.UpstreamSurfaceHookMutableSize;
+import com.jogamp.nativewindow.x11.X11GraphicsConfiguration;
+import com.jogamp.nativewindow.x11.X11GraphicsDevice;
+import com.jogamp.nativewindow.x11.X11GraphicsScreen;
+
+public class X11DummyUpstreamSurfaceHook extends UpstreamSurfaceHookMutableSize {
+ /**
+ * @param width the initial width as returned by {@link NativeSurface#getWidth()} via {@link UpstreamSurfaceHook#getWidth(ProxySurface)},
+ * not the actual dummy surface width.
+ * The latter is platform specific and small
+ * @param height the initial height as returned by {@link NativeSurface#getHeight()} via {@link UpstreamSurfaceHook#getHeight(ProxySurface)},
+ * not the actual dummy surface height,
+ * The latter is platform specific and small
+ */
+ public X11DummyUpstreamSurfaceHook(int width, int height) {
+ super(width, height);
+ }
+
+ @Override
+ public final void create(ProxySurface s) {
+ final X11GraphicsConfiguration cfg = (X11GraphicsConfiguration) s.getGraphicsConfiguration();
+ final X11GraphicsScreen screen = (X11GraphicsScreen) cfg.getScreen();
+ final X11GraphicsDevice device = (X11GraphicsDevice) screen.getDevice();
+ device.lock();
+ try {
+ if(0 == device.getHandle()) {
+ device.open();
+ s.addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_DEVICE );
+ }
+ if( 0 == s.getSurfaceHandle() ) {
+ final long windowHandle = X11Lib.CreateDummyWindow(device.getHandle(), screen.getIndex(), cfg.getXVisualID(), 64, 64);
+ if(0 == windowHandle) {
+ throw new NativeWindowException("Creating dummy window failed w/ "+cfg);
+ }
+ s.setSurfaceHandle(windowHandle);
+ s.addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );
+ }
+ s.addUpstreamOptionBits(ProxySurface.OPT_UPSTREAM_WINDOW_INVISIBLE);
+ } finally {
+ device.unlock();
+ }
+ }
+
+ @Override
+ public final void destroy(ProxySurface s) {
+ if( s.containsUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE ) ) {
+ final X11GraphicsDevice device = (X11GraphicsDevice) s.getGraphicsConfiguration().getScreen().getDevice();
+ if( 0 == s.getSurfaceHandle() ) {
+ throw new InternalError("Owns upstream surface, but no X11 window: "+s);
+ }
+ device.lock();
+ try {
+ X11Lib.DestroyDummyWindow(device.getHandle(), s.getSurfaceHandle());
+ s.setSurfaceHandle(0);
+ s.clearUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );
+ } finally {
+ device.unlock();
+ }
+ }
+ }
+}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java
index 7b46a1d..c771cd6 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java
@@ -34,6 +34,7 @@
package jogamp.nativewindow.x11;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
import javax.media.nativewindow.AbstractGraphicsDevice;
@@ -42,13 +43,15 @@ import javax.media.nativewindow.NativeWindowFactory;
import jogamp.nativewindow.Debug;
import jogamp.nativewindow.NWJNILibLoader;
+import jogamp.nativewindow.ToolkitProperties;
import com.jogamp.common.util.LongObjectHashMap;
+import com.jogamp.nativewindow.x11.X11GraphicsDevice;
/**
* Contains a thread safe X11 utility to retrieve display connections.
*/
-public class X11Util {
+public class X11Util implements ToolkitProperties {
/**
* See Bug 515 - https://jogamp.org/bugzilla/show_bug.cgi?id=515
* <p>
@@ -67,48 +70,56 @@ public class X11Util {
* </p>
* <p>
* You may test this, ie just reverse the destroy order below.
- * See also native test: jogl/test/native/displayMultiple02.c
+ * See also native test: jogl/test-native/displayMultiple02.c
* </p>
* <p>
- * Workaround is to not close them at all if driver vendor is ATI.
+ * Workaround is to not close them at all if driver vendor is ATI
+ * during operation.
+ * </p>
+ * <p>
+ * With ATI X11 drivers all connections must be closed at JVM shutdown,
+ * otherwise a SIGSEGV (after JVM safepoint) will be caused.
* </p>
*/
- public static final boolean ATI_HAS_XCLOSEDISPLAY_BUG = true;
+ public static final boolean ATI_HAS_XCLOSEDISPLAY_BUG = !Debug.isPropertyDefined("nativewindow.debug.X11Util.ATI_HAS_NO_XCLOSEDISPLAY_BUG", true);
+
+ /**
+ * See Bug 623 - https://jogamp.org/bugzilla/show_bug.cgi?id=623
+ */
+ public static final boolean ATI_HAS_MULTITHREADING_BUG = !Debug.isPropertyDefined("nativewindow.debug.X11Util.ATI_HAS_NO_MULTITHREADING_BUG", true);
- /** Value is <code>true</code>, best 'stable' results if always using XInitThreads(). */
- public static final boolean XINITTHREADS_ALWAYS_ENABLED = true;
-
- /** Value is <code>true</code>, best 'stable' results if not using XLockDisplay/XUnlockDisplay at all. */
- public static final boolean HAS_XLOCKDISPLAY_BUG = true;
-
public static final boolean DEBUG = Debug.debug("X11Util");
public static final boolean XSYNC_ENABLED = Debug.isPropertyDefined("nativewindow.debug.X11Util.XSync", true);
public static final boolean XERROR_STACKDUMP = DEBUG || Debug.isPropertyDefined("nativewindow.debug.X11Util.XErrorStackDump", true);
private static final boolean TRACE_DISPLAY_LIFECYCLE = Debug.isPropertyDefined("nativewindow.debug.X11Util.TraceDisplayLifecycle", true);
private static String nullDisplayName = null;
- private static boolean isX11LockAvailable = false;
- private static boolean requiresX11Lock = true;
private static volatile boolean isInit = false;
private static boolean markAllDisplaysUnclosable = false; // ATI/AMD X11 driver issues
+ private static boolean hasThreadingIssues = false; // ATI/AMD X11 driver issues
- private static int setX11ErrorHandlerRecCount = 0;
private static Object setX11ErrorHandlerLock = new Object();
-
+ private static final String X11_EXTENSION_ATIFGLRXDRI = "ATIFGLRXDRI";
+ private static final String X11_EXTENSION_ATIFGLEXTENSION = "ATIFGLEXTENSION";
- @SuppressWarnings("unused")
- public static void initSingleton(final boolean firstX11ActionOnProcess) {
+ /**
+ * Called by {@link NativeWindowFactory#initSingleton()}
+ * @see ToolkitProperties
+ */
+ public static void initSingleton() {
if(!isInit) {
synchronized(X11Util.class) {
if(!isInit) {
isInit = true;
+ if(DEBUG) {
+ System.out.println("X11Util.initSingleton()");
+ }
if(!NWJNILibLoader.loadNativeWindow("x11")) {
throw new NativeWindowException("NativeWindow X11 native library load error.");
}
- final boolean callXInitThreads = XINITTHREADS_ALWAYS_ENABLED || firstX11ActionOnProcess;
- final boolean isXInitThreadsOK = initialize0( XINITTHREADS_ALWAYS_ENABLED || firstX11ActionOnProcess, XERROR_STACKDUMP);
- isX11LockAvailable = isXInitThreadsOK && !HAS_XLOCKDISPLAY_BUG ;
+ final boolean isInitOK = initialize0( XERROR_STACKDUMP );
+ final boolean hasX11_EXTENSION_ATIFGLRXDRI, hasX11_EXTENSION_ATIFGLEXTENSION;
final long dpy = X11Lib.XOpenDisplay(null);
if(0 != dpy) {
if(XSYNC_ENABLED) {
@@ -116,20 +127,29 @@ public class X11Util {
}
try {
nullDisplayName = X11Lib.XDisplayString(dpy);
+ hasX11_EXTENSION_ATIFGLRXDRI = X11Lib.QueryExtension(dpy, X11_EXTENSION_ATIFGLRXDRI);
+ hasX11_EXTENSION_ATIFGLEXTENSION = X11Lib.QueryExtension(dpy, X11_EXTENSION_ATIFGLEXTENSION);
} finally {
X11Lib.XCloseDisplay(dpy);
}
} else {
nullDisplayName = "nil";
+ hasX11_EXTENSION_ATIFGLRXDRI = false;
+ hasX11_EXTENSION_ATIFGLEXTENSION = false;
}
+ hasThreadingIssues = ATI_HAS_MULTITHREADING_BUG && ( hasX11_EXTENSION_ATIFGLRXDRI || hasX11_EXTENSION_ATIFGLEXTENSION );
+ markAllDisplaysUnclosable = ATI_HAS_XCLOSEDISPLAY_BUG && ( hasX11_EXTENSION_ATIFGLRXDRI || hasX11_EXTENSION_ATIFGLEXTENSION );
if(DEBUG) {
- System.err.println("X11Util firstX11ActionOnProcess: "+firstX11ActionOnProcess+
- ", requiresX11Lock "+requiresX11Lock+
- ", XInitThreads [called "+callXInitThreads+", OK "+isXInitThreadsOK+"]"+
- ", isX11LockAvailable "+isX11LockAvailable+
- ", X11 Display(NULL) <"+nullDisplayName+">"+
- ", XSynchronize Enabled: "+XSYNC_ENABLED);
+ System.err.println("X11Util.initSingleton(): OK "+isInitOK+"]"+
+ ",\n\t X11 Display(NULL) <"+nullDisplayName+">"+
+ ",\n\t XSynchronize Enabled: " + XSYNC_ENABLED+
+ ",\n\t X11_EXTENSION_ATIFGLRXDRI " + hasX11_EXTENSION_ATIFGLRXDRI+
+ ",\n\t X11_EXTENSION_ATIFGLEXTENSION " + hasX11_EXTENSION_ATIFGLEXTENSION+
+ ",\n\t requiresToolkitLock "+requiresToolkitLock()+
+ ",\n\t hasThreadingIssues "+hasThreadingIssues()+
+ ",\n\t markAllDisplaysUnclosable "+getMarkAllDisplaysUnclosable()
+ );
// Thread.dumpStack();
}
}
@@ -137,30 +157,84 @@ public class X11Util {
}
}
- public static synchronized boolean isNativeLockAvailable() {
- return isX11LockAvailable;
+ // not exactly thread safe, but good enough for our purpose,
+ // which is to tag a NamedDisplay uncloseable after creation.
+ private static Object globalLock = new Object();
+ private static LongObjectHashMap openDisplayMap = new LongObjectHashMap(); // handle -> name
+ private static List<NamedDisplay> openDisplayList = new ArrayList<NamedDisplay>(); // open, no close attempt
+ private static List<NamedDisplay> reusableDisplayList = new ArrayList<NamedDisplay>(); // close attempt, marked uncloseable, for reuse
+ private static List<NamedDisplay> pendingDisplayList = new ArrayList<NamedDisplay>(); // all open (close attempt or reusable) in creation order
+ private static final HashMap<String /* displayName */, Boolean> displayXineramaEnabledMap = new HashMap<String, Boolean>();
+
+ /**
+ * Cleanup resources.
+ * <p>
+ * Called by {@link NativeWindowFactory#shutdown()}
+ * </p>
+ * @see ToolkitProperties
+ */
+ public static void shutdown() {
+ if(isInit) {
+ synchronized(X11Util.class) {
+ if(isInit) {
+ final boolean isJVMShuttingDown = NativeWindowFactory.isJVMShuttingDown() ;
+ if(DEBUG || openDisplayMap.size() > 0 || reusableDisplayList.size() > 0 || pendingDisplayList.size() > 0) {
+ System.err.println("X11Util.Display: Shutdown (JVM shutdown: "+isJVMShuttingDown+
+ ", open (no close attempt): "+openDisplayMap.size()+"/"+openDisplayList.size()+
+ ", reusable (open, marked uncloseable): "+reusableDisplayList.size()+
+ ", pending (open in creation order): "+pendingDisplayList.size()+
+ ")");
+ if(DEBUG) {
+ Thread.dumpStack();
+ }
+ if( openDisplayList.size() > 0) {
+ X11Util.dumpOpenDisplayConnections();
+ }
+ if(DEBUG) {
+ if( reusableDisplayList.size() > 0 || pendingDisplayList.size() > 0 ) {
+ X11Util.dumpPendingDisplayConnections();
+ }
+ }
+ }
+
+ synchronized(globalLock) {
+ // Only at JVM shutdown time, since AWT impl. seems to
+ // dislike closing of X11 Display's (w/ ATI driver).
+ if( isJVMShuttingDown ) {
+ isInit = false;
+ closePendingDisplayConnections();
+ openDisplayList.clear();
+ reusableDisplayList.clear();
+ pendingDisplayList.clear();
+ openDisplayMap.clear();
+ displayXineramaEnabledMap.clear();
+ shutdown0();
+ }
+ }
+ }
+ }
+ }
}
-
- public static synchronized boolean requiresToolkitLock() {
- return requiresX11Lock;
+
+ /**
+ * Called by {@link NativeWindowFactory#initSingleton()}
+ * @see ToolkitProperties
+ */
+ public static final boolean requiresToolkitLock() {
+ return true; // JAWT locking: yes, instead of native X11 locking w use a recursive lock per display connection.
}
-
+
+ /**
+ * Called by {@link NativeWindowFactory#initSingleton()}
+ * @see ToolkitProperties
+ */
+ public static final boolean hasThreadingIssues() {
+ return hasThreadingIssues; // JOGL impl. may utilize special locking "somewhere"
+ }
+
public static void setX11ErrorHandler(boolean onoff, boolean quiet) {
synchronized(setX11ErrorHandlerLock) {
- if(onoff) {
- if(0==setX11ErrorHandlerRecCount) {
- setX11ErrorHandler0(true, quiet);
- }
- setX11ErrorHandlerRecCount++;
- } else {
- if(0 >= setX11ErrorHandlerRecCount) {
- throw new InternalError();
- }
- setX11ErrorHandlerRecCount--;
- if(0==setX11ErrorHandlerRecCount) {
- setX11ErrorHandler0(false, false);
- }
- }
+ setX11ErrorHandler0(onoff, quiet);
}
}
@@ -171,19 +245,9 @@ public class X11Util {
public static boolean getMarkAllDisplaysUnclosable() {
return markAllDisplaysUnclosable;
}
- public static void setMarkAllDisplaysUnclosable(boolean v) {
- markAllDisplaysUnclosable = v;
- }
private X11Util() {}
- // not exactly thread safe, but good enough for our purpose,
- // which is to tag a NamedDisplay uncloseable after creation.
- private static Object globalLock = new Object();
- private static LongObjectHashMap openDisplayMap = new LongObjectHashMap(); // handle -> name
- private static List<NamedDisplay> openDisplayList = new ArrayList<NamedDisplay>();
- private static List<NamedDisplay> pendingDisplayList = new ArrayList<NamedDisplay>();
-
public static class NamedDisplay {
final String name;
final long handle;
@@ -217,8 +281,7 @@ public class X11Util {
public final boolean equals(Object obj) {
if(this == obj) { return true; }
if(obj instanceof NamedDisplay) {
- NamedDisplay n = (NamedDisplay) obj;
- return handle == n.handle;
+ return handle == ((NamedDisplay) obj).handle;
}
return false;
}
@@ -245,61 +308,25 @@ public class X11Util {
}
}
- /**
- * Cleanup resources.
- * If <code>realXCloseOpenAndPendingDisplays</code> is <code>false</code>,
- * keep alive all references (open display connection) for restart on same ClassLoader.
- *
- * @return number of unclosed X11 Displays.<br>
- * @param realXCloseOpenAndPendingDisplays if true, {@link #closePendingDisplayConnections()} is called.
- */
- public static int shutdown(boolean realXCloseOpenAndPendingDisplays, boolean verbose) {
- int num=0;
- if(DEBUG || verbose || openDisplayMap.size() > 0 || pendingDisplayList.size() > 0) {
- System.err.println("X11Util.Display: Shutdown (close open / pending Displays: "+realXCloseOpenAndPendingDisplays+
- ", open (no close attempt): "+openDisplayMap.size()+"/"+openDisplayList.size()+
- ", pending (not closed, marked uncloseable): "+pendingDisplayList.size()+")");
- if(DEBUG) {
- Thread.dumpStack();
- }
- if( openDisplayList.size() > 0) {
- X11Util.dumpOpenDisplayConnections();
- }
- if( pendingDisplayList.size() > 0 ) {
- X11Util.dumpPendingDisplayConnections();
- }
- }
-
- synchronized(globalLock) {
- if(realXCloseOpenAndPendingDisplays) {
- closePendingDisplayConnections();
- openDisplayList.clear();
- pendingDisplayList.clear();
- openDisplayMap.clear();
- shutdown0();
- }
- }
- return num;
- }
-
/**
- * Closing pending Display connections in reverse order.
+ * Closing pending Display connections in original creation order, if {@link #getMarkAllDisplaysUnclosable()} is true.
*
* @return number of closed Display connections
*/
- public static int closePendingDisplayConnections() {
+ private static int closePendingDisplayConnections() {
int num=0;
synchronized(globalLock) {
- if(DEBUG) {
- System.err.println("X11Util: Closing Pending X11 Display Connections: "+pendingDisplayList.size());
- }
- for(int i=pendingDisplayList.size()-1; i>=0; i--) {
- NamedDisplay ndpy = (NamedDisplay) pendingDisplayList.get(i);
- if(DEBUG) {
- System.err.println("X11Util.closePendingDisplayConnections(): Closing ["+i+"]: "+ndpy);
+ if( getMarkAllDisplaysUnclosable() ) {
+ for(int i=0; i<pendingDisplayList.size(); i++) {
+ final NamedDisplay ndpy = (NamedDisplay) pendingDisplayList.get(i);
+ if(DEBUG) {
+ final boolean closeAttempted = !openDisplayMap.containsKey(ndpy.getHandle());
+ System.err.println("X11Util.closePendingDisplayConnections(): Closing ["+i+"]: "+ndpy+" - closeAttempted "+closeAttempted);
+ }
+ XCloseDisplay(ndpy.getHandle());
+ num++;
}
- XCloseDisplay(ndpy.getHandle());
- num++;
+ System.err.println("X11Util.closePendingDisplayConnections(): Closed "+num+" pending display connections");
}
}
return num;
@@ -327,6 +354,12 @@ public class X11Util {
}
}
+ public static int getReusableDisplayConnectionNumber() {
+ synchronized(globalLock) {
+ return reusableDisplayList.size();
+ }
+ }
+
public static int getPendingDisplayConnectionNumber() {
synchronized(globalLock) {
return pendingDisplayList.size();
@@ -335,7 +368,18 @@ public class X11Util {
public static void dumpPendingDisplayConnections() {
synchronized(globalLock) {
- System.err.println("X11Util: Pending X11 Display Connections: "+pendingDisplayList.size());
+ System.err.println("X11Util: Reusable X11 Display Connections: "+reusableDisplayList.size());
+ for(int i=0; i<reusableDisplayList.size(); i++) {
+ NamedDisplay ndpy = (NamedDisplay) reusableDisplayList.get(i);
+ System.err.println("X11Util: Reusable["+i+"]: "+ndpy);
+ if(null!=ndpy) {
+ Throwable t = ndpy.getCreationStack();
+ if(null!=t) {
+ t.printStackTrace();
+ }
+ }
+ }
+ System.err.println("X11Util: Pending X11 Display Connections (creation order): "+pendingDisplayList.size());
for(int i=0; i<pendingDisplayList.size(); i++) {
NamedDisplay ndpy = (NamedDisplay) pendingDisplayList.get(i);
System.err.println("X11Util: Pending["+i+"]: "+ndpy);
@@ -368,10 +412,10 @@ public class X11Util {
name = validateDisplayName(name);
boolean reused = false;
- synchronized(globalLock) {
- for(int i=0; i<pendingDisplayList.size(); i++) {
- if(pendingDisplayList.get(i).getName().equals(name)) {
- namedDpy = pendingDisplayList.remove(i);
+ synchronized(globalLock) {
+ for(int i=0; i<reusableDisplayList.size(); i++) {
+ if(reusableDisplayList.get(i).getName().equals(name)) {
+ namedDpy = reusableDisplayList.remove(i);
dpy = namedDpy.getHandle();
reused = true;
break;
@@ -385,6 +429,7 @@ public class X11Util {
// if you like to debug and synchronize X11 commands ..
// setSynchronizeDisplay(dpy, true);
namedDpy = new NamedDisplay(name, dpy);
+ pendingDisplayList.add(namedDpy);
}
namedDpy.addRef();
openDisplayMap.put(dpy, namedDpy);
@@ -419,9 +464,11 @@ public class X11Util {
if(!namedDpy.isUncloseable()) {
XCloseDisplay(namedDpy.getHandle());
+ pendingDisplayList.remove(namedDpy);
} else {
// for reuse
- pendingDisplayList.add(namedDpy);
+ X11Lib.XSync(namedDpy.getHandle(), true); // flush output buffer and discard all events
+ reusableDisplayList.add(namedDpy);
}
if(DEBUG) {
@@ -457,53 +504,60 @@ public class X11Util {
*******************************/
public static long XOpenDisplay(String arg0) {
- NativeWindowFactory.getDefaultToolkitLock().lock();
- try {
- long handle = X11Lib.XOpenDisplay(arg0);
- if(XSYNC_ENABLED && 0 != handle) {
- X11Lib.XSynchronize(handle, true);
- }
- if(TRACE_DISPLAY_LIFECYCLE) {
- System.err.println(Thread.currentThread()+" - X11Util.XOpenDisplay("+arg0+") 0x"+Long.toHexString(handle));
- // Thread.dumpStack();
- }
- return handle;
- } finally {
- NativeWindowFactory.getDefaultToolkitLock().unlock();
+ long handle = X11Lib.XOpenDisplay(arg0);
+ if(XSYNC_ENABLED && 0 != handle) {
+ X11Lib.XSynchronize(handle, true);
+ }
+ if(TRACE_DISPLAY_LIFECYCLE) {
+ System.err.println(Thread.currentThread()+" - X11Util.XOpenDisplay("+arg0+") 0x"+Long.toHexString(handle));
+ // Thread.dumpStack();
}
+ return handle;
}
public static int XCloseDisplay(long display) {
- NativeWindowFactory.getDefaultToolkitLock().lock();
+ if(TRACE_DISPLAY_LIFECYCLE) {
+ System.err.println(Thread.currentThread()+" - X11Util.XCloseDisplay() 0x"+Long.toHexString(display));
+ // Thread.dumpStack();
+ }
+ int res = -1;
try {
- if(TRACE_DISPLAY_LIFECYCLE) {
- System.err.println(Thread.currentThread()+" - X11Util.XCloseDisplay() 0x"+Long.toHexString(display));
- // Thread.dumpStack();
- }
- int res = -1;
- X11Util.setX11ErrorHandler(true, DEBUG ? false : true);
- try {
- res = X11Lib.XCloseDisplay(display);
- } catch (Exception ex) {
- System.err.println("X11Util: Catched Exception:");
- ex.printStackTrace();
- } finally {
- X11Util.setX11ErrorHandler(false, false);
- }
- return res;
- } finally {
- NativeWindowFactory.getDefaultToolkitLock().unlock();
+ res = X11Lib.XCloseDisplay(display);
+ } catch (Exception ex) {
+ System.err.println("X11Util: Catched Exception:");
+ ex.printStackTrace();
}
+ return res;
}
static volatile boolean XineramaFetched = false;
static long XineramaLibHandle = 0;
static long XineramaQueryFunc = 0;
- public static boolean XineramaIsEnabled(long display) {
- if(0==display) {
- throw new IllegalArgumentException("Display NULL");
+ public static boolean XineramaIsEnabled(X11GraphicsDevice device) {
+ if(null == device) {
+ throw new IllegalArgumentException("X11 Display device is NULL");
+ }
+ device.lock();
+ try {
+ return XineramaIsEnabled(device.getHandle());
+ } finally {
+ device.unlock();
+ }
+ }
+
+ public static boolean XineramaIsEnabled(long displayHandle) {
+ if( 0 == displayHandle ) {
+ throw new IllegalArgumentException("X11 Display handle is NULL");
}
+ final String displayName = X11Lib.XDisplayString(displayHandle);
+ synchronized(displayXineramaEnabledMap) {
+ final Boolean b = displayXineramaEnabledMap.get(displayName);
+ if(null != b) {
+ return b.booleanValue();
+ }
+ }
+ final boolean res;
if(!XineramaFetched) { // volatile: ok
synchronized(X11Util.class) {
if( !XineramaFetched ) {
@@ -516,22 +570,27 @@ public class X11Util {
}
}
if(0!=XineramaQueryFunc) {
- final boolean res = X11Lib.XineramaIsEnabled(XineramaQueryFunc, display);
+ res = X11Lib.XineramaIsEnabled(XineramaQueryFunc, displayHandle);
+ } else {
if(DEBUG) {
- System.err.println("XineramaIsEnabled: "+res);
+ System.err.println("XineramaIsEnabled: Couldn't bind to Xinerama - lib 0x"+Long.toHexString(XineramaLibHandle)+
+ "query 0x"+Long.toHexString(XineramaQueryFunc));
}
- return res;
- } else if(DEBUG) {
- System.err.println("XineramaIsEnabled: Couldn't bind to Xinerama - lib 0x"+Long.toHexString(XineramaLibHandle)+
- "query 0x"+Long.toHexString(XineramaQueryFunc));
+ res = false;
}
- return false;
+ synchronized(displayXineramaEnabledMap) {
+ if(DEBUG) {
+ System.err.println("XineramaIsEnabled Cache: Display "+displayName+" (0x"+Long.toHexString(displayHandle)+") -> "+res);
+ }
+ displayXineramaEnabledMap.put(displayName, Boolean.valueOf(res));
+ }
+ return res;
}
private static final String getCurrentThreadName() { return Thread.currentThread().getName(); } // Callback for JNI
private static final void dumpStack() { Thread.dumpStack(); } // Callback for JNI
- private static native boolean initialize0(boolean firstUIActionOnProcess, boolean debug);
+ private static native boolean initialize0(boolean debug);
private static native void shutdown0();
private static native void setX11ErrorHandler0(boolean onoff, boolean quiet);
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/awt/X11AWTGraphicsConfigurationFactory.java b/src/nativewindow/classes/jogamp/nativewindow/x11/awt/X11AWTGraphicsConfigurationFactory.java
index 1de03e8..b152f0f 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/x11/awt/X11AWTGraphicsConfigurationFactory.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/x11/awt/X11AWTGraphicsConfigurationFactory.java
@@ -91,7 +91,7 @@ public class X11AWTGraphicsConfigurationFactory extends GraphicsConfigurationFac
final long displayHandleAWT = X11SunJDKReflection.graphicsDeviceGetDisplay(device);
final long displayHandle;
- boolean owner = false;
+ final boolean owner;
if(0==displayHandleAWT) {
displayHandle = X11Util.openDisplay(null);
owner = true;
@@ -112,9 +112,8 @@ public class X11AWTGraphicsConfigurationFactory extends GraphicsConfigurationFac
System.err.println(getThreadName()+" - X11AWTGraphicsConfigurationFactory: AWT dpy "+displayName+" / "+toHexString(displayHandleAWT)+", create X11 display "+toHexString(displayHandle));
}
}
- final ToolkitLock lock = owner ?
- NativeWindowFactory.getDefaultToolkitLock(NativeWindowFactory.TYPE_AWT) : // own non-shared X11 display connection, no X11 lock
- NativeWindowFactory.createDefaultToolkitLock(NativeWindowFactory.TYPE_X11, NativeWindowFactory.TYPE_AWT, displayHandle);
+ // Global JAWT lock required - No X11 resource locking due to private display connection
+ final ToolkitLock lock = NativeWindowFactory.getDefaultToolkitLock(NativeWindowFactory.TYPE_AWT);
final X11GraphicsDevice x11Device = new X11GraphicsDevice(displayHandle, AbstractGraphicsDevice.DEFAULT_UNIT, lock, owner);
final X11GraphicsScreen x11Screen = new X11GraphicsScreen(x11Device, awtScreen.getIndex());
if(DEBUG) {
diff --git a/src/nativewindow/native/macosx/OSXmisc.m b/src/nativewindow/native/macosx/OSXmisc.m
index 2c853a4..1cf41fc 100644
--- a/src/nativewindow/native/macosx/OSXmisc.m
+++ b/src/nativewindow/native/macosx/OSXmisc.m
@@ -119,6 +119,12 @@ Java_jogamp_nativewindow_macosx_OSXUtil_isNSView0(JNIEnv *env, jclass _unused, j
return [nsObj isMemberOfClass:[NSView class]];
}
+JNIEXPORT jboolean JNICALL
+Java_jogamp_nativewindow_macosx_OSXUtil_isNSWindow0(JNIEnv *env, jclass _unused, jlong object) {
+ NSObject *nsObj = (NSObject*) (intptr_t) object;
+ return [nsObj isMemberOfClass:[NSWindow class]];
+}
+
/*
* Class: Java_jogamp_nativewindow_macosx_OSXUtil
* Method: getLocationOnScreen0
@@ -238,8 +244,10 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_CreateNSWindow0
[myWindow setPreservesContentDuringLiveResize: YES];
// Remove animations
NS_DURING
+ if ( [myWindow respondsToSelector:@selector(setAnimationBehavior:)] ) {
// Available >= 10.7 - Removes default animations
[myWindow setAnimationBehavior: NSWindowAnimationBehaviorNone];
+ }
NS_HANDLER
NS_ENDHANDLER
@@ -278,11 +286,28 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetNSView0
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSWindow* win = (NSWindow*) ((intptr_t) window);
- DBG_PRINT( "contentView0 - window: %p (START)\n", win);
-
jlong res = (jlong) ((intptr_t) [win contentView]);
- DBG_PRINT( "contentView0 - window: %p (END)\n", win);
+ DBG_PRINT( "GetNSView(window: %p): %p\n", win, (void*) (intptr_t) res);
+
+ [pool release];
+ return res;
+}
+
+/*
+ * Class: Java_jogamp_nativewindow_macosx_OSXUtil
+ * Method: GetNSWindow0
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetNSWindow0
+ (JNIEnv *env, jclass unused, jlong view)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ NSView* v = (NSView*) ((intptr_t) view);
+
+ jlong res = (jlong) ((intptr_t) [v window]);
+
+ DBG_PRINT( "GetNSWindow(view: %p): %p\n", v, (void*) (intptr_t) res);
[pool release];
return res;
@@ -314,6 +339,8 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_CreateCALayer0
// no animations for add/remove/swap sublayers etc
// doesn't work: [layer removeAnimationForKey: kCAOnOrderIn, kCAOnOrderOut, kCATransition]
[layer removeAllAnimations];
+ [layer setAutoresizingMask: (kCALayerWidthSizable|kCALayerHeightSizable)];
+ [layer setNeedsDisplayOnBoundsChange: YES];
DBG_PRINT("CALayer::CreateCALayer.1: %p %lf/%lf %lfx%lf\n", layer, lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height);
DBG_PRINT("CALayer::CreateCALayer.X: %p (refcnt %d)\n", layer, (int)[layer retainCount]);
@@ -357,7 +384,11 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_AddCASublayer0
// no animations for add/remove/swap sublayers etc
// doesn't work: [layer removeAnimationForKey: kCAOnOrderIn, kCAOnOrderOut, kCATransition]
[rootLayer removeAllAnimations];
+ [rootLayer setAutoresizingMask: (kCALayerWidthSizable|kCALayerHeightSizable)];
+ [rootLayer setNeedsDisplayOnBoundsChange: YES];
[subLayer removeAllAnimations];
+ [subLayer setAutoresizingMask: (kCALayerWidthSizable|kCALayerHeightSizable)];
+ [subLayer setNeedsDisplayOnBoundsChange: YES];
}];
DBG_PRINT("CALayer::AddCASublayer0.X: %p . %p (refcnt %d)\n", rootLayer, subLayer, (int)[subLayer retainCount]);
JNF_COCOA_EXIT(env);
@@ -404,6 +435,63 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_DestroyCALayer0
JNF_COCOA_EXIT(env);
}
+/*
+ * Class: Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow
+ * Method: SetJAWTRootSurfaceLayer0
+ * Signature: (JJ)Z
+ */
+JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow_SetJAWTRootSurfaceLayer0
+ (JNIEnv *env, jclass unused, jobject jawtDrawingSurfaceInfoBuffer, jlong caLayer)
+{
+ JNF_COCOA_ENTER(env);
+ JAWT_DrawingSurfaceInfo* dsi = (JAWT_DrawingSurfaceInfo*) (*env)->GetDirectBufferAddress(env, jawtDrawingSurfaceInfoBuffer);
+ if (NULL == dsi) {
+ NativewindowCommon_throwNewRuntimeException(env, "Argument \"jawtDrawingSurfaceInfoBuffer\" was not a direct buffer");
+ return JNI_FALSE;
+ }
+ CALayer* layer = (CALayer*) (intptr_t) caLayer;
+ [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
+ id <JAWT_SurfaceLayers> surfaceLayers = (id <JAWT_SurfaceLayers>)dsi->platformInfo;
+ DBG_PRINT("CALayer::SetJAWTRootSurfaceLayer.0: %p -> %p (refcnt %d)\n", surfaceLayers.layer, layer, (int)[layer retainCount]);
+ surfaceLayers.layer = layer; // already incr. retain count
+ DBG_PRINT("CALayer::SetJAWTRootSurfaceLayer.X: %p (refcnt %d)\n", layer, (int)[layer retainCount]);
+ }];
+ JNF_COCOA_EXIT(env);
+ return JNI_TRUE;
+}
+
+/*
+ * Class: Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow
+ * Method: UnsetJAWTRootSurfaceLayer0
+ * Signature: (JJ)Z
+JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow_UnsetJAWTRootSurfaceLayer0
+ (JNIEnv *env, jclass unused, jobject jawtDrawingSurfaceInfoBuffer, jlong caLayer)
+{
+ JNF_COCOA_ENTER(env);
+ JAWT_DrawingSurfaceInfo* dsi = (JAWT_DrawingSurfaceInfo*) (*env)->GetDirectBufferAddress(env, jawtDrawingSurfaceInfoBuffer);
+ if (NULL == dsi) {
+ NativewindowCommon_throwNewRuntimeException(env, "Argument \"jawtDrawingSurfaceInfoBuffer\" was not a direct buffer");
+ return JNI_FALSE;
+ }
+ CALayer* layer = (CALayer*) (intptr_t) caLayer;
+ {
+ id <JAWT_SurfaceLayers> surfaceLayers = (id <JAWT_SurfaceLayers>)dsi->platformInfo;
+ if(layer != surfaceLayers.layer) {
+ NativewindowCommon_throwNewRuntimeException(env, "Attached layer %p doesn't match given layer %p\n", surfaceLayers.layer, layer);
+ return JNI_FALSE;
+ }
+ }
+ // [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
+ id <JAWT_SurfaceLayers> surfaceLayers = (id <JAWT_SurfaceLayers>)dsi->platformInfo;
+ DBG_PRINT("CALayer::detachJAWTSurfaceLayer: (%p) %p -> NULL\n", layer, surfaceLayers.layer);
+ surfaceLayers.layer = NULL;
+ [layer release];
+ // }];
+ JNF_COCOA_EXIT(env);
+ return JNI_TRUE;
+}
+ */
+
@interface MainRunnable : NSObject
{
@@ -489,60 +577,65 @@ JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_IsMainThread0
return ( [NSThread isMainThread] == YES ) ? JNI_TRUE : JNI_FALSE ;
}
-/*
- * Class: Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow
- * Method: SetJAWTRootSurfaceLayer0
- * Signature: (JJ)Z
+/***
+ * The following static functions are copied out of NEWT's OSX impl. <src/newt/native/MacWindow.m>
+ * May need to push code to NativeWindow, to remove duplication.
*/
-JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow_SetJAWTRootSurfaceLayer0
- (JNIEnv *env, jclass unused, jobject jawtDrawingSurfaceInfoBuffer, jlong caLayer)
+static NSScreen * NewtScreen_getNSScreenByIndex(int screen_idx) {
+ NSArray *screens = [NSScreen screens];
+ if(screen_idx<0) screen_idx=0;
+ if(screen_idx>=[screens count]) screen_idx=0;
+ return (NSScreen *) [screens objectAtIndex: screen_idx];
+}
+static CGDirectDisplayID NewtScreen_getCGDirectDisplayIDByNSScreen(NSScreen *screen) {
+ // Mind: typedef uint32_t CGDirectDisplayID; - however, we assume it's 64bit on 64bit ?!
+ NSDictionary * dict = [screen deviceDescription];
+ NSNumber * val = (NSNumber *) [dict objectForKey: @"NSScreenNumber"];
+ // [NSNumber integerValue] returns NSInteger which is 32 or 64 bit native size
+ return (CGDirectDisplayID) [val integerValue];
+}
+static long GetDictionaryLong(CFDictionaryRef theDict, const void* key)
{
- JNF_COCOA_ENTER(env);
- JAWT_DrawingSurfaceInfo* dsi = (JAWT_DrawingSurfaceInfo*) (*env)->GetDirectBufferAddress(env, jawtDrawingSurfaceInfoBuffer);
- if (NULL == dsi) {
- NativewindowCommon_throwNewRuntimeException(env, "Argument \"jawtDrawingSurfaceInfoBuffer\" was not a direct buffer");
- return JNI_FALSE;
- }
- CALayer* layer = (CALayer*) (intptr_t) caLayer;
- [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
- id <JAWT_SurfaceLayers> surfaceLayers = (id <JAWT_SurfaceLayers>)dsi->platformInfo;
- DBG_PRINT("CALayer::SetJAWTRootSurfaceLayer.0: %p -> %p (refcnt %d)\n", surfaceLayers.layer, layer, (int)[layer retainCount]);
- surfaceLayers.layer = layer; // already incr. retain count
- DBG_PRINT("CALayer::SetJAWTRootSurfaceLayer.X: %p (refcnt %d)\n", layer, (int)[layer retainCount]);
- }];
- JNF_COCOA_EXIT(env);
- return JNI_TRUE;
+ long value = 0;
+ CFNumberRef numRef;
+ numRef = (CFNumberRef)CFDictionaryGetValue(theDict, key);
+ if (numRef != NULL)
+ CFNumberGetValue(numRef, kCFNumberLongType, &value);
+ return value;
}
+#define CGDDGetModeRefreshRate(mode) GetDictionaryLong((mode), kCGDisplayRefreshRate)
/*
- * Class: Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow
- * Method: UnsetJAWTRootSurfaceLayer0
- * Signature: (JJ)Z
-JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow_UnsetJAWTRootSurfaceLayer0
- (JNIEnv *env, jclass unused, jobject jawtDrawingSurfaceInfoBuffer, jlong caLayer)
+ * Class: Java_jogamp_nativewindow_macosx_OSXUtil
+ * Method: GetScreenRefreshRate
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetScreenRefreshRate0
+ (JNIEnv *env, jclass unused, jint scrn_idx)
{
+ int res = 0;
JNF_COCOA_ENTER(env);
- JAWT_DrawingSurfaceInfo* dsi = (JAWT_DrawingSurfaceInfo*) (*env)->GetDirectBufferAddress(env, jawtDrawingSurfaceInfoBuffer);
- if (NULL == dsi) {
- NativewindowCommon_throwNewRuntimeException(env, "Argument \"jawtDrawingSurfaceInfoBuffer\" was not a direct buffer");
- return JNI_FALSE;
- }
- CALayer* layer = (CALayer*) (intptr_t) caLayer;
- {
- id <JAWT_SurfaceLayers> surfaceLayers = (id <JAWT_SurfaceLayers>)dsi->platformInfo;
- if(layer != surfaceLayers.layer) {
- NativewindowCommon_throwNewRuntimeException(env, "Attached layer %p doesn't match given layer %p\n", surfaceLayers.layer, layer);
- return JNI_FALSE;
+ // NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ NSScreen *screen = NewtScreen_getNSScreenByIndex((int)scrn_idx);
+ DBG_PRINT("GetScreenRefreshRate.0: screen %p\n", (void *)screen);
+ if(NULL != screen) {
+ CGDirectDisplayID display = NewtScreen_getCGDirectDisplayIDByNSScreen(screen);
+ DBG_PRINT("GetScreenRefreshRate.1: display %p\n", (void *)display);
+ if(0 != display) {
+ CFDictionaryRef mode = CGDisplayCurrentMode(display);
+ DBG_PRINT("GetScreenRefreshRate.2: mode %p\n", (void *)mode);
+ if(NULL != mode) {
+ res = CGDDGetModeRefreshRate(mode);
+ DBG_PRINT("GetScreenRefreshRate.3: res %d\n", res);
+ }
}
}
- // [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
- id <JAWT_SurfaceLayers> surfaceLayers = (id <JAWT_SurfaceLayers>)dsi->platformInfo;
- DBG_PRINT("CALayer::detachJAWTSurfaceLayer: (%p) %p -> NULL\n", layer, surfaceLayers.layer);
- surfaceLayers.layer = NULL;
- [layer release];
- // }];
+ if(0 == res) {
+ res = 60; // default .. (experienced on OSX 10.6.8)
+ }
+ DBG_PRINT(stderr, "GetScreenRefreshRate.X: %d\n", res);
+ // [pool release];
JNF_COCOA_EXIT(env);
- return JNI_TRUE;
+ return res;
}
- */
diff --git a/src/nativewindow/native/x11/Xmisc.c b/src/nativewindow/native/x11/Xmisc.c
index fcba858..129baac 100644
--- a/src/nativewindow/native/x11/Xmisc.c
+++ b/src/nativewindow/native/x11/Xmisc.c
@@ -29,6 +29,7 @@
#include "NativewindowCommon.h"
#include "Xmisc.h"
#include "jogamp_nativewindow_x11_X11Lib.h"
+#include "jogamp_nativewindow_x11_X11Util.h"
// #define VERBOSE_ON 1
@@ -160,10 +161,12 @@ static JavaVM *jvmHandle = NULL;
static int jvmVersion = 0;
static void setupJVMVars(JNIEnv * env) {
- if(0 != (*env)->GetJavaVM(env, &jvmHandle)) {
- jvmHandle = NULL;
+ if( NULL != env && NULL == jvmHandle ) {
+ if(0 != (*env)->GetJavaVM(env, &jvmHandle)) {
+ jvmHandle = NULL;
+ }
+ jvmVersion = (*env)->GetVersion(env);
}
- jvmVersion = (*env)->GetVersion(env);
}
static XErrorHandler origErrorHandler = NULL ;
@@ -175,44 +178,42 @@ static int x11ErrorHandler(Display *dpy, XErrorEvent *e)
{
if(!errorHandlerQuiet) {
const char * errnoStr = strerror(errno);
- char threadName[80];
char errCodeStr[80];
char reqCodeStr[80];
-
int shallBeDetached = 0;
- JNIEnv *jniEnv = NativewindowCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
+ JNIEnv *jniEnv = NULL;
- (void) NativewindowCommon_GetStaticStringMethod(jniEnv, X11UtilClazz, getCurrentThreadNameID, threadName, sizeof(threadName), "n/a");
snprintf(errCodeStr, sizeof(errCodeStr), "%d", e->request_code);
XGetErrorDatabaseText(dpy, "XRequest", errCodeStr, "Unknown", reqCodeStr, sizeof(reqCodeStr));
XGetErrorText(dpy, e->error_code, errCodeStr, sizeof(errCodeStr));
- fprintf(stderr, "Info: Nativewindow X11 Error (Thread: %s): %d - %s, dpy %p, id %x, # %d: %d:%d %s\n",
- threadName, e->error_code, errCodeStr, e->display, (int)e->resourceid, (int)e->serial,
+ fprintf(stderr, "Info: Nativewindow X11 Error: %d - %s, dpy %p, id %x, # %d: %d:%d %s\n",
+ e->error_code, errCodeStr, e->display, (int)e->resourceid, (int)e->serial,
(int)e->request_code, (int)e->minor_code, reqCodeStr);
+ fflush(stderr);
- if( errorHandlerDebug ) {
- (*jniEnv)->CallStaticVoidMethod(jniEnv, X11UtilClazz, dumpStackID);
+ if( NULL != jvmHandle && ( errorHandlerDebug || errorHandlerThrowException ) ) {
+ jniEnv = NativewindowCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
+ if(NULL == jniEnv) {
+ fprintf(stderr, "Nativewindow X11 Error: null JNIEnv");
+ fflush(stderr);
+ }
}
- if(errorHandlerThrowException) {
- if(NULL != jniEnv) {
- NativewindowCommon_throwNewRuntimeException(jniEnv, "Nativewindow X11 Error (Thread: %s): %d - %s, dpy %p, id %x, # %d: %d:%d %s\n",
- threadName, e->error_code, errCodeStr, e->display, (int)e->resourceid, (int)e->serial,
+ if( NULL != jniEnv ) {
+ if( errorHandlerDebug ) {
+ (*jniEnv)->CallStaticVoidMethod(jniEnv, X11UtilClazz, dumpStackID);
+ }
+
+ if(errorHandlerThrowException) {
+ NativewindowCommon_throwNewRuntimeException(jniEnv, "Nativewindow X11 Error: %d - %s, dpy %p, id %x, # %d: %d:%d %s\n",
+ e->error_code, errCodeStr, e->display, (int)e->resourceid, (int)e->serial,
(int)e->request_code, (int)e->minor_code, reqCodeStr);
- } else {
- fprintf(stderr, "Nativewindow X11 Error: null JNIEnv");
- #if 0
- if(NULL!=origErrorHandler) {
- origErrorHandler(dpy, e);
- }
- #endif
}
- }
- fflush(stderr);
- if (NULL != jniEnv && shallBeDetached) {
- (*jvmHandle)->DetachCurrentThread(jvmHandle);
+ if (shallBeDetached) {
+ (*jvmHandle)->DetachCurrentThread(jvmHandle);
+ }
}
}
@@ -246,20 +247,19 @@ static int x11IOErrorHandler(Display *dpy)
{
const char * dpyName = XDisplayName(NULL);
const char * errnoStr = strerror(errno);
- char threadName[80];
int shallBeDetached = 0;
- JNIEnv *jniEnv = NativewindowCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
+ JNIEnv *jniEnv = NULL;
- (void) NativewindowCommon_GetStaticStringMethod(jniEnv, X11UtilClazz, getCurrentThreadNameID, threadName, sizeof(threadName), "n/a");
+ fprintf(stderr, "Nativewindow X11 IOError: Display %p (%s): %s\n", dpy, dpyName, errnoStr);
+ fflush(stderr);
- fprintf(stderr, "Nativewindow X11 IOError (Thread %s): Display %p (%s): %s\n", threadName, dpy, dpyName, errnoStr);
- (*jniEnv)->CallStaticVoidMethod(jniEnv, X11UtilClazz, dumpStackID);
-
- if (NULL != jniEnv) {
- NativewindowCommon_FatalError(jniEnv, "Nativewindow X11 IOError (Thread %s): Display %p (%s): %s", threadName, dpy, dpyName, errnoStr);
-
- if (shallBeDetached) {
- (*jvmHandle)->DetachCurrentThread(jvmHandle);
+ if( NULL != jvmHandle ) {
+ jniEnv = NativewindowCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
+ if (NULL != jniEnv) {
+ NativewindowCommon_FatalError(jniEnv, "Nativewindow X11 IOError: Display %p (%s): %s", dpy, dpyName, errnoStr);
+ if (shallBeDetached) {
+ (*jvmHandle)->DetachCurrentThread(jvmHandle);
+ }
}
}
if(NULL!=origIOErrorHandler) {
@@ -280,41 +280,30 @@ static void x11IOErrorHandlerEnable(int onoff, JNIEnv * env) {
}
}
-static int _initialized=0;
-static jboolean _xinitThreadsOK=JNI_FALSE;
+static int _initialized = 0;
JNIEXPORT jboolean JNICALL
-Java_jogamp_nativewindow_x11_X11Util_initialize0(JNIEnv *env, jclass clazz, jboolean firstUIActionOnProcess, jboolean debug) {
- if(0==_initialized) {
+Java_jogamp_nativewindow_x11_X11Util_initialize0(JNIEnv *env, jclass clazz, jboolean debug) {
+ if( 0 == _initialized ) {
if(debug) {
errorHandlerDebug = 1;
}
X11UtilClazz = (jclass)(*env)->NewGlobalRef(env, clazz);
- if( JNI_TRUE == firstUIActionOnProcess ) {
- if( 0 == XInitThreads() ) {
- fprintf(stderr, "Warning: XInitThreads() failed\n");
- } else {
- _xinitThreadsOK=JNI_TRUE;
- if(debug) {
- fprintf(stderr, "X11: XInitThreads() called for concurrent Thread support\n");
- }
- }
- } else if(debug) {
- fprintf(stderr, "X11: XInitThreads() _not_ called for concurrent Thread support\n");
- }
_initClazzAccess(env);
x11IOErrorHandlerEnable(1, env);
+ NativewindowCommon_x11ErrorHandlerEnable(env, NULL, 1, 0, 0 /* no dpy, no sync */);
_initialized=1;
if(JNI_TRUE == debug) {
fprintf(stderr, "Info: NativeWindow native init passed\n");
}
}
- return _xinitThreadsOK;
+ return JNI_TRUE;
}
JNIEXPORT void JNICALL
Java_jogamp_nativewindow_x11_X11Util_shutdown0(JNIEnv *env, jclass _unused) {
+ NativewindowCommon_x11ErrorHandlerEnable(env, NULL, 0, 0, 0 /* no dpy, no sync */);
x11IOErrorHandlerEnable(0, env);
}
@@ -347,7 +336,7 @@ Java_jogamp_nativewindow_x11_X11Lib_XGetVisualInfo1__JJLjava_nio_ByteBuffer_2Lja
}
NativewindowCommon_x11ErrorHandlerEnable(env, (Display *) (intptr_t) arg0, 1, 0, 0);
_res = XGetVisualInfo((Display *) (intptr_t) arg0, (long) arg1, (XVisualInfo *) _ptr2, (int *) _ptr3);
- NativewindowCommon_x11ErrorHandlerEnable(env, (Display *) (intptr_t) arg0, 0, 0, 0);
+ // NativewindowCommon_x11ErrorHandlerEnable(env, (Display *) (intptr_t) arg0, 0, 0, 0);
count = _ptr3[0];
if (arg3 != NULL) {
(*env)->ReleasePrimitiveArrayCritical(env, arg3, _ptr3, 0);
@@ -382,7 +371,7 @@ Java_jogamp_nativewindow_x11_X11Lib_GetVisualIDFromWindow(JNIEnv *env, jclass _u
} else {
r = 0;
}
- NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
+ // NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
return r;
}
@@ -396,7 +385,7 @@ Java_jogamp_nativewindow_x11_X11Lib_DefaultVisualID(JNIEnv *env, jclass _unused,
}
NativewindowCommon_x11ErrorHandlerEnable(env, (Display *) (intptr_t) display, 1, 0, 0);
r = (jint) XVisualIDFromVisual( DefaultVisual( (Display*) (intptr_t) display, screen ) );
- NativewindowCommon_x11ErrorHandlerEnable(env, (Display *) (intptr_t) display, 0, 0, 0);
+ // NativewindowCommon_x11ErrorHandlerEnable(env, (Display *) (intptr_t) display, 0, 0, 0);
return r;
}
@@ -439,7 +428,7 @@ Java_jogamp_nativewindow_x11_X11Lib_XCloseDisplay__J(JNIEnv *env, jclass _unused
}
NativewindowCommon_x11ErrorHandlerEnable(env, NULL, 1, 0, 0);
_res = XCloseDisplay((Display *) (intptr_t) display);
- NativewindowCommon_x11ErrorHandlerEnable(env, NULL, 0, 0, 0);
+ // NativewindowCommon_x11ErrorHandlerEnable(env, NULL, 0, 0, 0);
return _res;
}
@@ -497,7 +486,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateDummyWindow
if (visual==NULL)
{
- NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
+ // NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
NativewindowCommon_throwNewRuntimeException(env, "could not query Visual by given VisualID, bail out!");
return 0;
}
@@ -541,7 +530,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateDummyWindow
XSelectInput(dpy, window, 0); // no events
- NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
+ // NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
DBG_PRINT( "X11: [CreateWindow] created window %p on display %p\n", window, dpy);
@@ -569,7 +558,7 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_x11_X11Lib_DestroyDummyWindow
XUnmapWindow(dpy, w);
XSync(dpy, False);
XDestroyWindow(dpy, w);
- NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
+ // NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
}
/*
@@ -597,7 +586,7 @@ JNIEXPORT jobject JNICALL Java_jogamp_nativewindow_x11_X11Lib_GetRelativeLocatio
res = XTranslateCoordinates(dpy, src_win, dest_win, src_x, src_y, &dest_x, &dest_y, &child);
- NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 0);
+ // NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 0);
DBG_PRINT( "X11: GetRelativeLocation0: %p %d/%d -> %p %d/%d - ok: %d\n",
(void*)src_win, src_x, src_y, (void*)dest_win, dest_x, dest_y, (int)res);
@@ -605,3 +594,38 @@ JNIEXPORT jobject JNICALL Java_jogamp_nativewindow_x11_X11Lib_GetRelativeLocatio
return (*env)->NewObject(env, pointClz, pointCstr, (jint)dest_x, (jint)dest_y);
}
+/*
+ * Class: jogamp_nativewindow_x11_X11Lib
+ * Method: QueryExtension0
+ * Signature: (JLjava/lang/String;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_x11_X11Lib_QueryExtension0
+ (JNIEnv *env, jclass unused, jlong jdisplay, jstring jextensionName)
+{
+ int32_t major_opcode, first_event, first_error;
+ jboolean res = JNI_FALSE;
+ Display * display = (Display *) (intptr_t) jdisplay;
+ const char* extensionName = NULL;
+
+ if(NULL==display) {
+ NativewindowCommon_throwNewRuntimeException(env, "NULL argument \"display\"");
+ return res;
+ }
+ if ( NULL == jextensionName ) {
+ NativewindowCommon_throwNewRuntimeException(env, "NULL argument \"extensionName\"");
+ return res;
+ }
+ extensionName = (*env)->GetStringUTFChars(env, jextensionName, (jboolean*)NULL);
+ if ( NULL == extensionName ) {
+ NativewindowCommon_throwNewRuntimeException(env, "Failed to get UTF-8 chars for argument \"extensionName\"");
+ return res;
+ }
+
+ res = True == XQueryExtension(display, extensionName, &major_opcode, &first_event, &first_error) ? JNI_TRUE : JNI_FALSE;
+
+ if ( NULL != jextensionName ) {
+ (*env)->ReleaseStringUTFChars(env, jextensionName, extensionName);
+ }
+ return res;
+}
+
diff --git a/src/newt/classes/com/jogamp/newt/Display.java b/src/newt/classes/com/jogamp/newt/Display.java
index 1e9a0e9..e97dec8 100644
--- a/src/newt/classes/com/jogamp/newt/Display.java
+++ b/src/newt/classes/com/jogamp/newt/Display.java
@@ -88,7 +88,7 @@ public abstract class Display {
public abstract boolean isNativeValid();
/**
- * @return number of references by Screen
+ * @return number of references
*/
public abstract int getReferenceCount();
@@ -96,7 +96,7 @@ public abstract class Display {
* The 1st call will initiate native creation,
* since we follow the lazy creation pattern.
*
- * @return number of references after adding one
+ * @return number of references post operation
* @throws NativeWindowException if the native creation failed.
* @see #removeReference()
*/
@@ -106,24 +106,30 @@ public abstract class Display {
* The last call may destroy this instance,
* if {@link #getDestroyWhenUnused()} returns <code>true</code>.
*
- * @return number of references after removing one
+ * @return number of references post operation
* @see #addReference()
* @see #getDestroyWhenUnused()
* @see #setDestroyWhenUnused(boolean)
*/
public abstract int removeReference();
+ /**
+ * Return the {@link AbstractGraphicsDevice} used for depending resources lifecycle,
+ * i.e. {@link Screen} and {@link Window}, as well as the event dispatching (EDT). */
public abstract AbstractGraphicsDevice getGraphicsDevice();
/**
- * @return the fully qualified Display name,
- * which is a key of {@link #getType()} + {@link #getName()} + {@link #getId()}
+ * Return the handle of the {@link AbstractGraphicsDevice} as returned by {@link #getGraphicsDevice()}.
*/
- public abstract String getFQName();
-
public abstract long getHandle();
/**
+ * @return The fully qualified Display name,
+ * which is a key of {@link #getType()} + {@link #getName()} + {@link #getId()}.
+ */
+ public abstract String getFQName();
+
+ /**
* @return this display internal serial id
*/
public abstract int getId();
@@ -141,6 +147,9 @@ public abstract class Display {
*/
public abstract String getType();
+ /** Return true if this instance is exclusive, i.e. will not be shared. */
+ public abstract boolean isExclusive();
+
/**
* Sets a new {@link EDTUtil} and returns the previous one.
* <p>
@@ -155,6 +164,14 @@ public abstract class Display {
* If <code>newEDTUtil</code> is not null and equals the previous one,
* <code>null</code> is returned and no change is being made.
* </p>
+ * <p>
+ * Note that <code>newEDTUtil</code> will not be started if not done so already,
+ * to do so you may issue {@link EDTUtil#invoke(boolean, Runnable) invoke}
+ * on the new EDTUtil:
+ * <pre>
+ * newEDTUtil.invoke(true, new Runnable() { public void run() { } } );
+ * </pre>
+ * </p>
*/
public abstract EDTUtil setEDTUtil(EDTUtil newEDTUtil);
@@ -183,11 +200,12 @@ public abstract class Display {
*
* @param type
* @param name
- * @param fromIndex start index, then increasing until found or end of list *
+ * @param fromIndex start index, then increasing until found or end of list
+ * @paran shared if true, only shared instances are found, otherwise also exclusive
* @return
*/
- public static Display getFirstDisplayOf(String type, String name, int fromIndex) {
- return getDisplayOfImpl(type, name, fromIndex, 1);
+ public static Display getFirstDisplayOf(String type, String name, int fromIndex, boolean shared) {
+ return getDisplayOfImpl(type, name, fromIndex, 1, shared);
}
/**
@@ -195,19 +213,22 @@ public abstract class Display {
* @param type
* @param name
* @param fromIndex start index, then decreasing until found or end of list. -1 is interpreted as size - 1.
+ * @paran shared if true, only shared instances are found, otherwise also exclusive
* @return
*/
- public static Display getLastDisplayOf(String type, String name, int fromIndex) {
- return getDisplayOfImpl(type, name, fromIndex, -1);
+ public static Display getLastDisplayOf(String type, String name, int fromIndex, boolean shared) {
+ return getDisplayOfImpl(type, name, fromIndex, -1, shared);
}
- private static Display getDisplayOfImpl(String type, String name, int fromIndex, int incr) {
+ private static Display getDisplayOfImpl(String type, String name, int fromIndex, int incr, boolean shared) {
synchronized(displayList) {
int i = fromIndex >= 0 ? fromIndex : displayList.size() - 1 ;
while( ( incr > 0 ) ? i < displayList.size() : i >= 0 ) {
Display display = (Display) displayList.get(i);
if( display.getType().equals(type) &&
- display.getName().equals(name) ) {
+ display.getName().equals(name) &&
+ ( !shared || shared && !display.isExclusive() )
+ ) {
return display;
}
i+=incr;
diff --git a/src/newt/classes/com/jogamp/newt/NewtFactory.java b/src/newt/classes/com/jogamp/newt/NewtFactory.java
index 61dbfb3..1bf47f4 100644
--- a/src/newt/classes/com/jogamp/newt/NewtFactory.java
+++ b/src/newt/classes/com/jogamp/newt/NewtFactory.java
@@ -49,17 +49,24 @@ import jogamp.newt.WindowImpl;
public class NewtFactory {
public static final boolean DEBUG_IMPLEMENTATION = Debug.debug("Window");
+ public static final String DRIVER_DEFAULT_ROOT_PACKAGE = "jogamp.newt.driver";
+
// Work-around for initialization order problems on Mac OS X
// between native Newt and (apparently) Fmod
static {
- NativeWindowFactory.initSingleton(false); // last resort ..
+ NativeWindowFactory.initSingleton(); // last resort ..
WindowImpl.init(NativeWindowFactory.getNativeWindowType(true));
}
public static Class<?> getCustomClass(String packageName, String classBaseName) {
Class<?> clazz = null;
if(packageName!=null && classBaseName!=null) {
- final String clazzName = packageName + "." + classBaseName ;
+ final String clazzName;
+ if( packageName.startsWith(".") ) {
+ clazzName = DRIVER_DEFAULT_ROOT_PACKAGE + packageName + "." + classBaseName ;
+ } else {
+ clazzName = packageName + "." + classBaseName ;
+ }
try {
clazz = Class.forName(clazzName);
} catch (Throwable t) {
@@ -298,7 +305,7 @@ public class NewtFactory {
* Instantiate a Display entity using the native handle.
*/
public static Display createDisplay(String type, long handle, boolean reuse) {
- return DisplayImpl.create(type, null, handle, false);
+ return DisplayImpl.create(type, null, handle, reuse);
}
public static boolean isScreenCompatible(NativeWindow parent, Screen childScreen) {
diff --git a/src/newt/classes/com/jogamp/newt/Screen.java b/src/newt/classes/com/jogamp/newt/Screen.java
index 26f19ad..a09748d 100644
--- a/src/newt/classes/com/jogamp/newt/Screen.java
+++ b/src/newt/classes/com/jogamp/newt/Screen.java
@@ -89,13 +89,14 @@ public abstract class Screen {
public abstract boolean isNativeValid();
/**
- * @return number of references by Window
+ * @return number of references
*/
public abstract int getReferenceCount();
/**
* See {@link Display#addReference()}
- *
+ *
+ * @return number of references post operation
* @throws NativeWindowException if the native creation failed.
* @see #removeReference()
* @see #setDestroyWhenUnused(boolean)
@@ -105,7 +106,8 @@ public abstract class Screen {
/**
* See {@link Display#removeReference()}
- *
+ *
+ * @return number of references post operation
* @see #addReference()
* @see #setDestroyWhenUnused(boolean)
* @see #getDestroyWhenUnused()
@@ -145,7 +147,7 @@ public abstract class Screen {
public abstract Display getDisplay();
/**
- * @return the screen fully qualified Screen name,
+ * @return The screen fully qualified Screen name,
* which is a key of {@link com.jogamp.newt.Display#getFQName()} + {@link #getIndex()}.
*/
public abstract String getFQName();
diff --git a/src/newt/classes/com/jogamp/newt/Window.java b/src/newt/classes/com/jogamp/newt/Window.java
index e8537fe..cc42465 100644
--- a/src/newt/classes/com/jogamp/newt/Window.java
+++ b/src/newt/classes/com/jogamp/newt/Window.java
@@ -129,7 +129,7 @@ public interface Window extends NativeWindow, WindowClosingProtocol {
* <pre>
* if ( 0 == windowHandle && visible ) {
* this.visible = visible;
- * if( 0 < width*height ) {
+ * if( 0 < width && 0 < height ) {
* createNative();
* }
* } else if ( this.visible != visible ) {
@@ -171,9 +171,9 @@ public interface Window extends NativeWindow, WindowClosingProtocol {
* <p>
* Zero size semantics are respected, see {@link #setVisible(boolean)}:<br>
* <pre>
- * if ( 0 != windowHandle && 0 ≥ width*height && visible ) {
+ * if ( visible && 0 != windowHandle && ( 0 ≥ width || 0 ≥ height ) ) {
* setVisible(false);
- * } else if ( 0 == windowHandle && 0 < width*height && visible ) {
+ * } else if ( visible && 0 == windowHandle && 0 < width && 0 < height ) {
* setVisible(true);
* } else {
* // as expected ..
@@ -245,6 +245,7 @@ public interface Window extends NativeWindow, WindowClosingProtocol {
String getTitle();
+ /** @see #setPointerVisible(boolean) */
boolean isPointerVisible();
/**
@@ -256,6 +257,7 @@ public interface Window extends NativeWindow, WindowClosingProtocol {
*/
void setPointerVisible(boolean pointerVisible);
+ /** @see #confinePointer(boolean) */
boolean isPointerConfined();
/**
diff --git a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
index 6f0028a..89a749c 100644
--- a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
+++ b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
@@ -68,6 +68,15 @@ import com.jogamp.newt.event.awt.AWTAdapter;
import com.jogamp.newt.event.awt.AWTKeyAdapter;
import com.jogamp.newt.event.awt.AWTMouseAdapter;
+/**
+ * AWT {@link java.awt.Canvas Canvas} containing a NEWT {@link Window} using native parenting.
+ *
+ * <h5><A NAME="java2dgl">Offscreen Layer Remarks</A></h5>
+ *
+ * {@link OffscreenLayerOption#setShallUseOffscreenLayer(boolean) setShallUseOffscreenLayer(true)}
+ * maybe called to use an offscreen drawable (FBO or PBuffer) allowing
+ * the underlying JAWT mechanism to composite the image, if supported.
+ */
@SuppressWarnings("serial")
public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProtocol, OffscreenLayerOption {
public static final boolean DEBUG = Debug.debug("Window");
diff --git a/src/newt/classes/com/jogamp/newt/event/InputEvent.java b/src/newt/classes/com/jogamp/newt/event/InputEvent.java
index 819338c..0122bda 100644
--- a/src/newt/classes/com/jogamp/newt/event/InputEvent.java
+++ b/src/newt/classes/com/jogamp/newt/event/InputEvent.java
@@ -34,22 +34,37 @@
package com.jogamp.newt.event;
+import com.jogamp.newt.Window;
+
@SuppressWarnings("serial")
public abstract class InputEvent extends NEWTEvent
{
- public static final int SHIFT_MASK = 1 << 0;
- public static final int CTRL_MASK = 1 << 1;
- public static final int META_MASK = 1 << 2;
- public static final int ALT_MASK = 1 << 3;
- public static final int ALT_GRAPH_MASK = 1 << 5;
- public static final int BUTTON1_MASK = 1 << 6;
- public static final int BUTTON2_MASK = 1 << 7;
- public static final int BUTTON3_MASK = 1 << 8;
- public static final int BUTTON4_MASK = 1 << 9;
- public static final int BUTTON5_MASK = 1 << 10;
- public static final int BUTTON6_MASK = 1 << 11;
- public static final int CONFINED_MASK = 1 << 16;
- public static final int INVISIBLE_MASK = 1 << 17;
+ public static final int SHIFT_MASK = 1 << 0;
+ public static final int CTRL_MASK = 1 << 1;
+ public static final int META_MASK = 1 << 2;
+ public static final int ALT_MASK = 1 << 3;
+ public static final int ALT_GRAPH_MASK = 1 << 4;
+
+ public static final int BUTTON1_MASK = 1 << 5;
+ public static final int BUTTON2_MASK = 1 << 6;
+ public static final int BUTTON3_MASK = 1 << 7;
+ public static final int BUTTON4_MASK = 1 << 8;
+ public static final int BUTTON5_MASK = 1 << 9;
+ public static final int BUTTON6_MASK = 1 << 10;
+ public static final int BUTTON7_MASK = 1 << 11;
+ public static final int BUTTON8_MASK = 1 << 12;
+ public static final int BUTTON9_MASK = 1 << 13;
+
+ public static final int BUTTONLAST_MASK = 1 << 20; // 16
+
+ /** Event is caused by auto-repeat. */
+ public static final int AUTOREPEAT_MASK = 1 << 29;
+
+ /** Pointer is confined, see {@link Window#confinePointer(boolean)}. */
+ public static final int CONFINED_MASK = 1 << 30;
+
+ /** Pointer is invisible, see {@link Window#setPointerVisible(boolean)}. */
+ public static final int INVISIBLE_MASK = 1 << 31;
/**
* Returns the corresponding button mask for the given button.
@@ -61,7 +76,7 @@ public abstract class InputEvent extends NEWTEvent
*/
public static final int getButtonMask(int button) {
if( 0 < button && button <= MouseEvent.BUTTON_NUMBER ) {
- return 1 << ( 5 + button ) ;
+ return 1 << ( 4 + button ) ;
}
return 0;
}
@@ -76,30 +91,64 @@ public abstract class InputEvent extends NEWTEvent
this.modifiers=modifiers;
}
+ /** Return the modifier bits of this event, e.g. see {@link #SHIFT_MASK} .. etc. */
public int getModifiers() {
return modifiers;
}
+ /** {@link #getModifiers()} contains {@link #ALT_MASK}. */
public boolean isAltDown() {
return (modifiers&ALT_MASK)!=0;
}
+ /** {@link #getModifiers()} contains {@link #ALT_GRAPH_MASK}. */
public boolean isAltGraphDown() {
return (modifiers&ALT_GRAPH_MASK)!=0;
}
+ /** {@link #getModifiers()} contains {@link #CTRL_MASK}. */
public boolean isControlDown() {
return (modifiers&CTRL_MASK)!=0;
}
+ /** {@link #getModifiers()} contains {@link #META_MASK}. */
public boolean isMetaDown() {
return (modifiers&META_MASK)!=0;
}
+ /** {@link #getModifiers()} contains {@link #SHIFT_MASK}. */
public boolean isShiftDown() {
return (modifiers&SHIFT_MASK)!=0;
}
+ /** {@link #getModifiers()} contains {@link #AUTOREPEAT_MASK}. */
+ public boolean isAutoRepeat() {
+ return (modifiers&AUTOREPEAT_MASK)!=0;
+ }
+ /** {@link #getModifiers()} contains {@link #CONFINED_MASK}. Pointer is confined, see {@link Window#confinePointer(boolean)}. */
public boolean isConfined() {
return (modifiers&CONFINED_MASK)!=0;
}
+ /** {@link #getModifiers()} contains {@link #INVISIBLE_MASK}. Pointer is invisible, see {@link Window#setPointerVisible(boolean)}. */
public boolean isInvisible() {
return (modifiers&INVISIBLE_MASK)!=0;
}
+
+ public StringBuilder getModifiersString(StringBuilder sb) {
+ if(null == sb) {
+ sb = new StringBuilder();
+ }
+ sb.append("[");
+ boolean isFirst = true;
+ if(isShiftDown()) { if(!isFirst) { sb.append(", "); } isFirst = false; sb.append("shift"); }
+ if(isControlDown()) { if(!isFirst) { sb.append(", "); } isFirst = false; sb.append("ctrl"); }
+ if(isMetaDown()) { if(!isFirst) { sb.append(", "); } isFirst = false; sb.append("meta"); }
+ if(isAltDown()) { if(!isFirst) { sb.append(", "); } isFirst = false; sb.append("alt"); }
+ if(isAltGraphDown()) { if(!isFirst) { sb.append(", "); } isFirst = false; sb.append("altg"); }
+ if(isAutoRepeat()) { if(!isFirst) { sb.append(", "); } isFirst = false; sb.append("repeat"); }
+ for(int i=1; i<=MouseEvent.BUTTON_NUMBER; i++) {
+ if(isButtonDown(i)) { if(!isFirst) { sb.append(", "); } isFirst = false; sb.append("button").append(i); }
+ }
+ if(isConfined()) { if(!isFirst) { sb.append(", "); } isFirst = false; sb.append("confined"); }
+ if(isInvisible()) { if(!isFirst) { sb.append(", "); } isFirst = false; sb.append("invisible"); }
+ sb.append("]");
+
+ return sb;
+ }
/**
* @return Array of pressed mouse buttons [{@link MouseEvent#BUTTON1} .. {@link MouseEvent#BUTTON6}].
@@ -124,7 +173,18 @@ public abstract class InputEvent extends NEWTEvent
}
public String toString() {
- return "InputEvent[modifiers: 0x"+Integer.toHexString(modifiers)+", "+super.toString()+"]";
+ return toString(null).toString();
+ }
+
+ public StringBuilder toString(StringBuilder sb) {
+ if(null == sb) {
+ sb = new StringBuilder();
+ }
+ sb.append("InputEvent[modifiers: ");
+ getModifiersString(sb);
+ sb.append(", ");
+ super.toString(sb).append("]");
+ return sb;
}
private final int modifiers;
diff --git a/src/newt/classes/com/jogamp/newt/event/KeyEvent.java b/src/newt/classes/com/jogamp/newt/event/KeyEvent.java
index 4db661e..289aa31 100644
--- a/src/newt/classes/com/jogamp/newt/event/KeyEvent.java
+++ b/src/newt/classes/com/jogamp/newt/event/KeyEvent.java
@@ -34,85 +34,148 @@
package com.jogamp.newt.event;
+/**
+ * Key events are delivered in the following order:
+ * <ol>
+ * <li>{@link #EVENT_KEY_PRESSED}</li>
+ * <li>{@link #EVENT_KEY_RELEASED}</li>
+ * <li>{@link #EVENT_KEY_TYPED}</li>
+ * </ol>
+ * In case the native platform does not
+ * deliver keyboard events in the above order or skip events,
+ * the NEWT driver will reorder and inject synthetic events if required.
+ * <p>
+ * Besides regular modifiers like {@link InputEvent#SHIFT_MASK} etc.,
+ * the {@link InputEvent#AUTOREPEAT_MASK} bit is added if repetition is detected.
+ * </p>
+ * <p>
+ * Auto-Repeat shall behave as follow:
+ * <pre>
+ D = pressed, U = released, T = typed
+ 0 = normal, 1 = auto-repeat
+
+ D(0), [ U(1), T(1), D(1), U(1) T(1) ..], U(0) T(0)
+ * </pre>
+ * The idea is if you mask out auto-repeat in your event listener
+ * you just get one long pressed key D/U/T triple.
+ * </p>
+ * <p>
+ * {@link #isModifierKey() Modifiers keys} will produce regular events (pressed, released and typed),
+ * however they will not produce Auto-Repeat events itself.
+ * </p>
+ */
@SuppressWarnings("serial")
public class KeyEvent extends InputEvent
{
- public KeyEvent(int eventType, Object source, long when, int modifiers, int keyCode, char keyChar) {
- super(eventType, source, when, modifiers);
- this.keyCode=keyCode;
- this.keyChar=keyChar;
- }
-
- /** Only valid on all platforms at {@link KeyListener#keyTyped(KeyEvent)} */
- public char getKeyChar() {
- return keyChar;
- }
-
- /** Always valid. */
- public int getKeyCode() {
- return keyCode;
- }
-
- public String toString() {
- return "KeyEvent["+getEventTypeString(getEventType())+
- ", code "+keyCode+"("+toHexString(keyCode)+"), char '"+keyChar+"' ("+toHexString((int)keyChar)+"), isActionKey "+isActionKey()+", "+super.toString()+"]";
- }
-
- public static String getEventTypeString(int type) {
- switch(type) {
+ public KeyEvent(int eventType, Object source, long when, int modifiers, int keyCode, char keyChar) {
+ super(eventType, source, when, modifiers);
+ this.keyCode=keyCode;
+ this.keyChar=keyChar;
+ }
+
+ /**
+ * Returns the character matching the {@link #getKeyCode() virtual key code}, if exist.
+ * <p>
+ * <b>Disclaimer</b>: Only valid on all platforms at {@link KeyListener#keyTyped(KeyEvent)}.
+ * Precisely, on the Windows platform we currently cannot deliver the proper character
+ * in case of shifted keys where no uppercase exists, e.g. 'shift + 1' doesn't produce '!'.
+ * </p>
+ */
+ public char getKeyChar() {
+ return keyChar;
+ }
+
+ /** Returns the virtual key code. */
+ public int getKeyCode() {
+ return keyCode;
+ }
+
+ public String toString() {
+ return toString(null).toString();
+ }
+
+ public StringBuilder toString(StringBuilder sb) {
+ if(null == sb) {
+ sb = new StringBuilder();
+ }
+ sb.append("KeyEvent[").append(getEventTypeString(getEventType())).append(", code ").append(keyCode).append("(").append(toHexString(keyCode)).append("), char '").append(keyChar).append("' (").append(toHexString((int)keyChar)).append("), isActionKey ").append(isActionKey()).append(", ");
+ return super.toString(sb).append("]");
+ }
+
+ public static String getEventTypeString(int type) {
+ switch(type) {
case EVENT_KEY_PRESSED: return "EVENT_KEY_PRESSED";
case EVENT_KEY_RELEASED: return "EVENT_KEY_RELEASED";
case EVENT_KEY_TYPED: return "EVENT_KEY_TYPED";
default: return "unknown (" + type + ")";
+ }
+ }
+
+ /** Returns true if <code>keyCode</code> represents a modifier key, i.e. one of {@link #VK_SHIFT}, {@link #VK_CONTROL}, {@link #VK_ALT}, {@link #VK_ALT_GRAPH}, {@link #VK_META}. */
+ public static boolean isModifierKey(int keyCode) {
+ switch (keyCode) {
+ case VK_SHIFT:
+ case VK_CONTROL:
+ case VK_ALT:
+ case VK_ALT_GRAPH:
+ case VK_META:
+ return true;
+ default:
+ return false;
+ }
}
- }
-
- public boolean isActionKey() {
- switch (keyCode) {
- case VK_HOME:
- case VK_END:
- case VK_PAGE_UP:
- case VK_PAGE_DOWN:
- case VK_UP:
- case VK_DOWN:
- case VK_LEFT:
- case VK_RIGHT:
-
- case VK_F1:
- case VK_F2:
- case VK_F3:
- case VK_F4:
- case VK_F5:
- case VK_F6:
- case VK_F7:
- case VK_F8:
- case VK_F9:
- case VK_F10:
- case VK_F11:
- case VK_F12:
- case VK_F13:
- case VK_F14:
- case VK_F15:
- case VK_F16:
- case VK_F17:
- case VK_F18:
- case VK_F19:
- case VK_F20:
- case VK_F21:
- case VK_F22:
- case VK_F23:
- case VK_F24:
- case VK_PRINTSCREEN:
- case VK_CAPS_LOCK:
- case VK_PAUSE:
- case VK_INSERT:
-
- case VK_HELP:
- case VK_WINDOWS:
- return true;
+
+ /** Returns true if {@link #getKeyCode()} represents a modifier key, i.e. one of {@link #VK_SHIFT}, {@link #VK_CONTROL}, {@link #VK_ALT}, {@link #VK_ALT_GRAPH}, {@link #VK_META}. */
+ public boolean isModifierKey() {
+ return isModifierKey(keyCode);
+ }
+
+ public boolean isActionKey() {
+ switch (keyCode) {
+ case VK_HOME:
+ case VK_END:
+ case VK_PAGE_UP:
+ case VK_PAGE_DOWN:
+ case VK_UP:
+ case VK_DOWN:
+ case VK_LEFT:
+ case VK_RIGHT:
+
+ case VK_F1:
+ case VK_F2:
+ case VK_F3:
+ case VK_F4:
+ case VK_F5:
+ case VK_F6:
+ case VK_F7:
+ case VK_F8:
+ case VK_F9:
+ case VK_F10:
+ case VK_F11:
+ case VK_F12:
+ case VK_F13:
+ case VK_F14:
+ case VK_F15:
+ case VK_F16:
+ case VK_F17:
+ case VK_F18:
+ case VK_F19:
+ case VK_F20:
+ case VK_F21:
+ case VK_F22:
+ case VK_F23:
+ case VK_F24:
+ case VK_PRINTSCREEN:
+ case VK_CAPS_LOCK:
+ case VK_PAUSE:
+ case VK_INSERT:
+
+ case VK_HELP:
+ case VK_WINDOWS:
+ return true;
+ }
+ return false;
}
- return false;
- }
private final int keyCode;
private final char keyChar;
@@ -123,10 +186,10 @@ public class KeyEvent extends InputEvent
/* Virtual key codes. */
- public static final int VK_ENTER = '\n';
- public static final int VK_BACK_SPACE = '\b';
- public static final int VK_TAB = '\t';
public static final int VK_CANCEL = 0x03;
+ public static final int VK_BACK_SPACE = 0x08; // '\b'
+ public static final int VK_TAB = 0x09; // '\t'
+ public static final int VK_ENTER = 0x0A; // '\n'
public static final int VK_CLEAR = 0x0C;
public static final int VK_SHIFT = 0x10;
public static final int VK_CONTROL = 0x11;
@@ -264,17 +327,9 @@ public class KeyEvent extends InputEvent
public static final int VK_ADD = 0x6B;
/**
- * This constant is obsolete, and is included only for backwards
- * compatibility.
- * @see #VK_SEPARATOR
- */
- public static final int VK_SEPARATER = 0x6C;
-
- /**
* Constant for the Numpad Separator key.
- * @since 1.4
*/
- public static final int VK_SEPARATOR = VK_SEPARATER;
+ public static final int VK_SEPARATOR = 0x6C;
public static final int VK_SUBTRACT = 0x6D;
public static final int VK_DECIMAL = 0x6E;
@@ -321,77 +376,76 @@ public class KeyEvent extends InputEvent
/**
* Constant for the F13 function key.
- * @since 1.2
+ * <p>F13 - F24 are used on IBM 3270 keyboard; use random range for constants.</p>
*/
- /* F13 - F24 are used on IBM 3270 keyboard; use random range for constants. */
public static final int VK_F13 = 0xF000;
-
+
/**
* Constant for the F14 function key.
- * @since 1.2
+ * <p>F13 - F24 are used on IBM 3270 keyboard; use random range for constants.</p>
*/
public static final int VK_F14 = 0xF001;
-
+
/**
* Constant for the F15 function key.
- * @since 1.2
+ * <p>F13 - F24 are used on IBM 3270 keyboard; use random range for constants.</p>
*/
public static final int VK_F15 = 0xF002;
-
+
/**
* Constant for the F16 function key.
- * @since 1.2
+ * <p>F13 - F24 are used on IBM 3270 keyboard; use random range for constants.</p>
*/
public static final int VK_F16 = 0xF003;
-
+
/**
* Constant for the F17 function key.
- * @since 1.2
+ * <p>F13 - F24 are used on IBM 3270 keyboard; use random range for constants.</p>
*/
public static final int VK_F17 = 0xF004;
-
+
/**
* Constant for the F18 function key.
- * @since 1.2
+ * <p>F13 - F24 are used on IBM 3270 keyboard; use random range for constants.</p>
*/
public static final int VK_F18 = 0xF005;
-
+
/**
* Constant for the F19 function key.
- * @since 1.2
+ * <p>F13 - F24 are used on IBM 3270 keyboard; use random range for constants.</p>
*/
public static final int VK_F19 = 0xF006;
-
+
/**
* Constant for the F20 function key.
- * @since 1.2
+ * <p>F13 - F24 are used on IBM 3270 keyboard; use random range for constants.</p>
*/
public static final int VK_F20 = 0xF007;
-
+
/**
* Constant for the F21 function key.
- * @since 1.2
+ * <p>F13 - F24 are used on IBM 3270 keyboard; use random range for constants.</p>
*/
public static final int VK_F21 = 0xF008;
-
+
/**
* Constant for the F22 function key.
- * @since 1.2
+ * <p>F13 - F24 are used on IBM 3270 keyboard; use random range for constants.</p>
*/
public static final int VK_F22 = 0xF009;
-
+
/**
* Constant for the F23 function key.
- * @since 1.2
+ * <p>F13 - F24 are used on IBM 3270 keyboard; use random range for constants.</p>
*/
public static final int VK_F23 = 0xF00A;
-
+
/**
* Constant for the F24 function key.
- * @since 1.2
+ * <p>F13 - F24 are used on IBM 3270 keyboard; use random range for constants.</p>
*/
public static final int VK_F24 = 0xF00B;
-
+
public static final int VK_PRINTSCREEN = 0x9A;
public static final int VK_INSERT = 0x9B;
public static final int VK_HELP = 0x9C;
@@ -403,172 +457,152 @@ public class KeyEvent extends InputEvent
/**
* Constant for the numeric keypad <b>up</b> arrow key.
* @see #VK_UP
- * @since 1.2
*/
public static final int VK_KP_UP = 0xE0;
/**
* Constant for the numeric keypad <b>down</b> arrow key.
* @see #VK_DOWN
- * @since 1.2
*/
public static final int VK_KP_DOWN = 0xE1;
/**
* Constant for the numeric keypad <b>left</b> arrow key.
* @see #VK_LEFT
- * @since 1.2
*/
public static final int VK_KP_LEFT = 0xE2;
/**
* Constant for the numeric keypad <b>right</b> arrow key.
* @see #VK_RIGHT
- * @since 1.2
*/
public static final int VK_KP_RIGHT = 0xE3;
-
- /* For European keyboards */
- /** @since 1.2 */
+
+ /** For European keyboards */
public static final int VK_DEAD_GRAVE = 0x80;
- /** @since 1.2 */
+ /** For European keyboards */
public static final int VK_DEAD_ACUTE = 0x81;
- /** @since 1.2 */
+ /** For European keyboards */
public static final int VK_DEAD_CIRCUMFLEX = 0x82;
- /** @since 1.2 */
+ /** For European keyboards */
public static final int VK_DEAD_TILDE = 0x83;
- /** @since 1.2 */
+ /** For European keyboards */
public static final int VK_DEAD_MACRON = 0x84;
- /** @since 1.2 */
+ /** For European keyboards */
public static final int VK_DEAD_BREVE = 0x85;
- /** @since 1.2 */
+ /** For European keyboards */
public static final int VK_DEAD_ABOVEDOT = 0x86;
- /** @since 1.2 */
+ /** For European keyboards */
public static final int VK_DEAD_DIAERESIS = 0x87;
- /** @since 1.2 */
+ /** For European keyboards */
public static final int VK_DEAD_ABOVERING = 0x88;
- /** @since 1.2 */
+ /** For European keyboards */
public static final int VK_DEAD_DOUBLEACUTE = 0x89;
- /** @since 1.2 */
+ /** For European keyboards */
public static final int VK_DEAD_CARON = 0x8a;
- /** @since 1.2 */
+ /** For European keyboards */
public static final int VK_DEAD_CEDILLA = 0x8b;
- /** @since 1.2 */
+ /** For European keyboards */
public static final int VK_DEAD_OGONEK = 0x8c;
- /** @since 1.2 */
+ /** For European keyboards */
public static final int VK_DEAD_IOTA = 0x8d;
- /** @since 1.2 */
+ /** For European keyboards */
public static final int VK_DEAD_VOICED_SOUND = 0x8e;
- /** @since 1.2 */
+ /** For European keyboards */
public static final int VK_DEAD_SEMIVOICED_SOUND = 0x8f;
- /** @since 1.2 */
+ /** For European keyboards */
public static final int VK_AMPERSAND = 0x96;
- /** @since 1.2 */
+ /** For European keyboards */
public static final int VK_ASTERISK = 0x97;
- /** @since 1.2 */
+ /** For European keyboards */
public static final int VK_QUOTEDBL = 0x98;
- /** @since 1.2 */
+ /** For European keyboards */
public static final int VK_LESS = 0x99;
- /** @since 1.2 */
+ /** For European keyboards */
public static final int VK_GREATER = 0xa0;
- /** @since 1.2 */
+ /** For European keyboards */
public static final int VK_BRACELEFT = 0xa1;
- /** @since 1.2 */
+ /** For European keyboards */
public static final int VK_BRACERIGHT = 0xa2;
/**
* Constant for the "@" key.
- * @since 1.2
*/
public static final int VK_AT = 0x0200;
-
+
/**
* Constant for the ":" key.
- * @since 1.2
*/
public static final int VK_COLON = 0x0201;
-
+
/**
* Constant for the "^" key.
- * @since 1.2
*/
public static final int VK_CIRCUMFLEX = 0x0202;
-
+
/**
* Constant for the "$" key.
- * @since 1.2
*/
public static final int VK_DOLLAR = 0x0203;
-
+
/**
* Constant for the Euro currency sign key.
- * @since 1.2
*/
public static final int VK_EURO_SIGN = 0x0204;
-
+
/**
* Constant for the "!" key.
- * @since 1.2
*/
public static final int VK_EXCLAMATION_MARK = 0x0205;
-
+
/**
* Constant for the inverted exclamation mark key.
- * @since 1.2
*/
public static final int VK_INVERTED_EXCLAMATION_MARK = 0x0206;
-
+
/**
* Constant for the "(" key.
- * @since 1.2
*/
public static final int VK_LEFT_PARENTHESIS = 0x0207;
-
+
/**
* Constant for the "#" key.
- * @since 1.2
*/
public static final int VK_NUMBER_SIGN = 0x0208;
-
+
/**
* Constant for the "+" key.
- * @since 1.2
*/
public static final int VK_PLUS = 0x0209;
-
+
/**
* Constant for the ")" key.
- * @since 1.2
*/
public static final int VK_RIGHT_PARENTHESIS = 0x020A;
-
+
/**
* Constant for the "_" key.
- * @since 1.2
*/
public static final int VK_UNDERSCORE = 0x020B;
-
+
/**
* Constant for the Microsoft Windows "Windows" key.
* It is used for both the left and right version of the key.
- * @see #getKeyLocation()
- * @since 1.5
*/
public static final int VK_WINDOWS = 0x020C;
-
+
/**
* Constant for the Microsoft Windows Context Menu key.
- * @since 1.5
*/
public static final int VK_CONTEXT_MENU = 0x020D;
-
+
/* for input method support on Asian Keyboards */
/* not clear what this means - listed in Microsoft Windows API */
public static final int VK_FINAL = 0x0018;
-
+
/** Constant for the Convert function key. */
/* Japanese PC 106 keyboard, Japanese Solaris keyboard: henkan */
public static final int VK_CONVERT = 0x001C;
@@ -576,7 +610,7 @@ public class KeyEvent extends InputEvent
/** Constant for the Don't Convert function key. */
/* Japanese PC 106 keyboard: muhenkan */
public static final int VK_NONCONVERT = 0x001D;
-
+
/** Constant for the Accept or Commit function key. */
/* Japanese Solaris keyboard: kakutei */
public static final int VK_ACCEPT = 0x001E;
@@ -594,87 +628,75 @@ public class KeyEvent extends InputEvent
/**
* Constant for the Alphanumeric function key.
- * @since 1.2
*/
/* Japanese PC 106 keyboard: eisuu */
public static final int VK_ALPHANUMERIC = 0x00F0;
-
+
/**
* Constant for the Katakana function key.
- * @since 1.2
*/
/* Japanese PC 106 keyboard: katakana */
public static final int VK_KATAKANA = 0x00F1;
-
+
/**
* Constant for the Hiragana function key.
- * @since 1.2
*/
/* Japanese PC 106 keyboard: hiragana */
public static final int VK_HIRAGANA = 0x00F2;
-
+
/**
* Constant for the Full-Width Characters function key.
- * @since 1.2
*/
/* Japanese PC 106 keyboard: zenkaku */
public static final int VK_FULL_WIDTH = 0x00F3;
-
+
/**
* Constant for the Half-Width Characters function key.
- * @since 1.2
*/
/* Japanese PC 106 keyboard: hankaku */
public static final int VK_HALF_WIDTH = 0x00F4;
-
+
/**
* Constant for the Roman Characters function key.
- * @since 1.2
*/
/* Japanese PC 106 keyboard: roumaji */
public static final int VK_ROMAN_CHARACTERS = 0x00F5;
-
+
/**
* Constant for the All Candidates function key.
- * @since 1.2
*/
/* Japanese PC 106 keyboard - VK_CONVERT + ALT: zenkouho */
public static final int VK_ALL_CANDIDATES = 0x0100;
-
+
/**
* Constant for the Previous Candidate function key.
- * @since 1.2
*/
/* Japanese PC 106 keyboard - VK_CONVERT + SHIFT: maekouho */
public static final int VK_PREVIOUS_CANDIDATE = 0x0101;
-
+
/**
* Constant for the Code Input function key.
- * @since 1.2
*/
/* Japanese PC 106 keyboard - VK_ALPHANUMERIC + ALT: kanji bangou */
public static final int VK_CODE_INPUT = 0x0102;
-
+
/**
* Constant for the Japanese-Katakana function key.
* This key switches to a Japanese input method and selects its Katakana input mode.
- * @since 1.2
*/
/* Japanese Macintosh keyboard - VK_JAPANESE_HIRAGANA + SHIFT */
public static final int VK_JAPANESE_KATAKANA = 0x0103;
-
+
/**
* Constant for the Japanese-Hiragana function key.
* This key switches to a Japanese input method and selects its Hiragana input mode.
- * @since 1.2
*/
/* Japanese Macintosh keyboard */
public static final int VK_JAPANESE_HIRAGANA = 0x0104;
-
+
/**
* Constant for the Japanese-Roman function key.
* This key switches to a Japanese input method and selects its Roman-Direct input mode.
- * @since 1.2
*/
/* Japanese Macintosh keyboard */
public static final int VK_JAPANESE_ROMAN = 0x0105;
@@ -682,51 +704,38 @@ public class KeyEvent extends InputEvent
/**
* Constant for the locking Kana function key.
* This key locks the keyboard into a Kana layout.
- * @since 1.3
*/
/* Japanese PC 106 keyboard with special Windows driver - eisuu + Control; Japanese Solaris keyboard: kana */
public static final int VK_KANA_LOCK = 0x0106;
/**
* Constant for the input method on/off key.
- * @since 1.3
*/
/* Japanese PC 106 keyboard: kanji. Japanese Solaris keyboard: nihongo */
public static final int VK_INPUT_METHOD_ON_OFF = 0x0107;
/* for Sun keyboards */
- /** @since 1.2 */
public static final int VK_CUT = 0xFFD1;
- /** @since 1.2 */
public static final int VK_COPY = 0xFFCD;
- /** @since 1.2 */
public static final int VK_PASTE = 0xFFCF;
- /** @since 1.2 */
public static final int VK_UNDO = 0xFFCB;
- /** @since 1.2 */
public static final int VK_AGAIN = 0xFFC9;
- /** @since 1.2 */
public static final int VK_FIND = 0xFFD0;
- /** @since 1.2 */
public static final int VK_PROPS = 0xFFCA;
- /** @since 1.2 */
public static final int VK_STOP = 0xFFC8;
-
+
/**
* Constant for the Compose function key.
- * @since 1.2
*/
public static final int VK_COMPOSE = 0xFF20;
-
+
/**
* Constant for the AltGraph function key.
- * @since 1.2
*/
public static final int VK_ALT_GRAPH = 0xFF7E;
/**
* Constant for the Begin key.
- * @since 1.5
*/
public static final int VK_BEGIN = 0xFF58;
diff --git a/src/newt/classes/com/jogamp/newt/event/MouseEvent.java b/src/newt/classes/com/jogamp/newt/event/MouseEvent.java
index ceaf7d4..914aaa6 100644
--- a/src/newt/classes/com/jogamp/newt/event/MouseEvent.java
+++ b/src/newt/classes/com/jogamp/newt/event/MouseEvent.java
@@ -49,8 +49,15 @@ public class MouseEvent extends InputEvent
public static final int BUTTON5 = 5;
/** ID for button 6, value <code>6</code> */
public static final int BUTTON6 = 6;
- /** Number of buttons, value <code>6</code> */
- public static final int BUTTON_NUMBER = 6;
+ /** ID for button 6, value <code>7</code> */
+ public static final int BUTTON7 = 7;
+ /** ID for button 6, value <code>8</code> */
+ public static final int BUTTON8 = 8;
+ /** ID for button 6, value <code>9</code> */
+ public static final int BUTTON9 = 9;
+
+ /** Maximum number of buttons, value <code>16</code> */
+ public static final int BUTTON_NUMBER = 16;
public static final int getClickTimeout() {
return 300;
@@ -165,7 +172,13 @@ public class MouseEvent extends InputEvent
}
public String toString() {
- StringBuilder sb = new StringBuilder();
+ return toString(null).toString();
+ }
+
+ public StringBuilder toString(StringBuilder sb) {
+ if(null == sb) {
+ sb = new StringBuilder();
+ }
sb.append("MouseEvent[").append(getEventTypeString(getEventType()))
.append(", ").append(x).append("/").append(y)
.append(", button ").append(button).append(", count ")
@@ -182,8 +195,8 @@ public class MouseEvent extends InputEvent
}
sb.append("]");
}
- sb.append(", ").append(super.toString()).append("]");
- return sb.toString();
+ sb.append(", ");
+ return super.toString(sb).append("]");
}
public static String getEventTypeString(int type) {
diff --git a/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java b/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java
index 3f3817b..9d8d92f 100644
--- a/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java
+++ b/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java
@@ -151,15 +151,17 @@ public class NEWTEvent extends java.util.EventObject {
}
public String toString() {
- return "NEWTEvent[sys:"+isSystemEvent()+", source:"+getSource().getClass().getName()+", when:"+getWhen()+" d "+(System.currentTimeMillis()-getWhen())+"ms]";
+ return toString(null).toString();
}
- public static String toHexString(int hex) {
- return "0x" + Integer.toHexString(hex);
+ public StringBuilder toString(StringBuilder sb) {
+ if(null == sb) {
+ sb = new StringBuilder();
+ }
+ return sb.append("NEWTEvent[sys:").append(isSystemEvent()).append(", source:").append(getSource().getClass().getName()).append(", when:").append(getWhen()).append(" d ").append((System.currentTimeMillis()-getWhen())).append("ms]");
}
- public static String toHexString(long hex) {
- return "0x" + Long.toHexString(hex);
+ static String toHexString(int hex) {
+ return "0x" + Integer.toHexString(hex);
}
-
}
diff --git a/src/newt/classes/com/jogamp/newt/event/WindowEvent.java b/src/newt/classes/com/jogamp/newt/event/WindowEvent.java
index f3d62d8..163b514 100644
--- a/src/newt/classes/com/jogamp/newt/event/WindowEvent.java
+++ b/src/newt/classes/com/jogamp/newt/event/WindowEvent.java
@@ -39,6 +39,7 @@ package com.jogamp.newt.event;
* NEWT will automatically handle component moves and resizes internally, regardless of whether a program is receiving these events or not. <br>
* The actual event semantic, here move and resize, is processed before the event is send.<br>
*/
+ at SuppressWarnings("serial")
public class WindowEvent extends NEWTEvent {
public static final int EVENT_WINDOW_RESIZED = 100;
public static final int EVENT_WINDOW_MOVED = 101;
@@ -64,8 +65,16 @@ public class WindowEvent extends NEWTEvent {
default: return "unknown (" + type + ")";
}
}
+
public String toString() {
- return "WindowEvent["+getEventTypeString(getEventType()) +
- ", " + super.toString() + "]";
+ return toString(null).toString();
+ }
+
+ public StringBuilder toString(StringBuilder sb) {
+ if(null == sb) {
+ sb = new StringBuilder();
+ }
+ sb.append("WindowEvent[").append(getEventTypeString(getEventType())).append(", ");
+ return super.toString(sb).append("]");
}
}
diff --git a/src/newt/classes/com/jogamp/newt/event/WindowUpdateEvent.java b/src/newt/classes/com/jogamp/newt/event/WindowUpdateEvent.java
index 505939d..e3f0373 100644
--- a/src/newt/classes/com/jogamp/newt/event/WindowUpdateEvent.java
+++ b/src/newt/classes/com/jogamp/newt/event/WindowUpdateEvent.java
@@ -30,6 +30,7 @@ package com.jogamp.newt.event;
import javax.media.nativewindow.util.Rectangle;
+ at SuppressWarnings("serial")
public class WindowUpdateEvent extends WindowEvent {
final Rectangle bounds;
@@ -44,6 +45,14 @@ public class WindowUpdateEvent extends WindowEvent {
}
public String toString() {
- return "WindowUpdateEvent["+super.toString()+", "+bounds+"]";
+ return toString(null).toString();
+ }
+
+ public StringBuilder toString(StringBuilder sb) {
+ if(null == sb) {
+ sb = new StringBuilder();
+ }
+ sb.append("WindowUpdateEvent[").append(bounds).append(", ");
+ return super.toString(sb).append("]");
}
}
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 69b0d04..2d63ca4 100644
--- a/src/newt/classes/com/jogamp/newt/event/awt/AWTWindowAdapter.java
+++ b/src/newt/classes/com/jogamp/newt/event/awt/AWTWindowAdapter.java
@@ -28,6 +28,8 @@
package com.jogamp.newt.event.awt;
+import java.awt.Dimension;
+
import jogamp.newt.awt.event.AWTNewtEventFactory;
public class AWTWindowAdapter
@@ -61,9 +63,9 @@ public class AWTWindowAdapter
if(awtComponent instanceof java.awt.Window) {
((java.awt.Window)awtComponent).addWindowListener(this);
}
- return this;
+ return this;
}
-
+
public AWTAdapter removeFrom(java.awt.Component awtComponent) {
awtComponent.removeFocusListener(this);
awtComponent.removeComponentListener(this);
@@ -89,6 +91,9 @@ public class AWTWindowAdapter
public void focusGained(java.awt.event.FocusEvent e) {
com.jogamp.newt.event.WindowEvent event = AWTNewtEventFactory.createWindowEvent(e, newtWindow);
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("AWT: focusGained: "+e+" -> "+event);
+ }
if(null!=newtListener) {
((com.jogamp.newt.event.WindowListener)newtListener).windowGainedFocus(event);
} else {
@@ -98,6 +103,9 @@ public class AWTWindowAdapter
public void focusLost(java.awt.event.FocusEvent e) {
com.jogamp.newt.event.WindowEvent event = AWTNewtEventFactory.createWindowEvent(e, newtWindow);
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("AWT: focusLost: "+e+" -> "+event);
+ }
if(null!=newtListener) {
((com.jogamp.newt.event.WindowListener)newtListener).windowLostFocus(event);
} else {
@@ -108,7 +116,19 @@ public class AWTWindowAdapter
public void componentResized(java.awt.event.ComponentEvent e) {
com.jogamp.newt.event.WindowEvent event = AWTNewtEventFactory.createWindowEvent(e, newtWindow);
if(DEBUG_IMPLEMENTATION) {
- System.err.println("AWT: componentResized: "+event);
+ final java.awt.Component c = e.getComponent();
+ final java.awt.Dimension sz = c.getSize();
+ final java.awt.Insets insets;
+ final java.awt.Dimension sz2;
+ if(c instanceof java.awt.Container) {
+ insets = ((java.awt.Container)c).getInsets();
+ sz2 = new Dimension(sz.width - insets.left - insets.right,
+ sz.height - insets.top - insets.bottom);
+ } else {
+ insets = null;
+ sz2 = sz;
+ }
+ System.err.println("AWT: componentResized: "+sz+" ( "+insets+", "+sz2+" ), "+e+" -> "+event);
}
if(null!=newtListener) {
((com.jogamp.newt.event.WindowListener)newtListener).windowResized(event);
@@ -120,7 +140,7 @@ public class AWTWindowAdapter
public void componentMoved(java.awt.event.ComponentEvent e) {
com.jogamp.newt.event.WindowEvent event = AWTNewtEventFactory.createWindowEvent(e, newtWindow);
if(DEBUG_IMPLEMENTATION) {
- System.err.println("AWT: componentMoved: "+event);
+ System.err.println("AWT: componentMoved: "+e+" -> "+event);
}
if(null!=newtListener) {
((com.jogamp.newt.event.WindowListener)newtListener).windowMoved(event);
diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
index 0fc1b4e..a89ccae 100644
--- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
+++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
@@ -51,6 +51,7 @@ import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawable;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLException;
@@ -97,7 +98,7 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind
* Constructor. Do not call this directly -- use {@link #create()} instead.
*/
protected GLWindow(Window window) {
- super(null, null, false);
+ super(null, null, false /* always handle device lifecycle ourselves */);
this.window = (WindowImpl) window;
this.window.setHandleDestroyNotify(false);
window.addWindowListener(new WindowAdapter() {
@@ -107,8 +108,8 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind
}
@Override
- public void windowResized(WindowEvent e) {
- defaultWindowResizedOp();
+ public void windowResized(WindowEvent e) {
+ defaultWindowResizedOp(getWidth(), getHeight());
}
@Override
@@ -201,11 +202,8 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind
@Override
public final CapabilitiesImmutable getChosenCapabilities() {
- if (drawable == null) {
- return window.getChosenCapabilities();
- }
-
- return drawable.getChosenGLCapabilities();
+ final GLDrawable _drawable = drawable;
+ return null != _drawable ? _drawable.getChosenGLCapabilities() : window.getChosenCapabilities();
}
@Override
@@ -536,19 +534,24 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind
return;
}
+ final boolean done;
final RecursiveLock lock = window.getLock();
lock.lock(); // sync: context/drawable could have been recreated/destroyed while animating
try {
if( null != context ) {
// surface is locked/unlocked implicit by context's makeCurrent/release
helper.invokeGL(drawable, context, defaultDisplayAction, defaultInitAction);
- } else if( 0<getWidth()*getHeight() ) {
- // retry drawable and context creation, will itself issue resize -> display
- setVisible(true);
+ done = true;
+ } else {
+ done = false;
}
} finally {
lock.unlock();
}
+ if( !done && 0<getWidth()*getHeight() ) {
+ // retry drawable and context creation, will itself issue resize -> display
+ setVisible(true);
+ }
}
//----------------------------------------------------------------------
diff --git a/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java b/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java
index f45b864..5252258 100644
--- a/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java
+++ b/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java
@@ -63,13 +63,13 @@ import com.jogamp.newt.Window;
import com.jogamp.newt.event.WindowEvent;
import com.jogamp.newt.util.EDTUtil;
+/**
+ * SWT {@link Canvas} containing a NEWT {@link Window} using native parenting.
+ */
public class NewtCanvasSWT extends Canvas implements WindowClosingProtocol {
private static final boolean DEBUG = Debug.debug("Window");
private static final boolean isOSX = NativeWindowFactory.TYPE_MACOSX == NativeWindowFactory.getNativeWindowType(false);
- /** SWT EDTUtil associated w/ parent's SWT Display */
- private final EDTUtil swtEDTUtil;
-
private final AbstractGraphicsScreen screen;
private WindowClosingMode newtChildCloseOp = WindowClosingMode.DISPOSE_ON_CLOSE;
@@ -117,8 +117,6 @@ public class NewtCanvasSWT extends Canvas implements WindowClosingProtocol {
public NewtCanvasSWT(final Composite parent, final int style, Window child) {
super(parent, style | SWT.NO_BACKGROUND);
- swtEDTUtil = new SWTEDTUtil(parent.getDisplay());
-
SWTAccessor.setRealized(this, true);
clientArea = getClientArea();
@@ -159,7 +157,7 @@ public class NewtCanvasSWT extends Canvas implements WindowClosingProtocol {
}
updateSizeCheck();
final Rectangle nClientArea = clientArea;
- if(0 == nClientArea.width * nClientArea.height) {
+ if(0 >= nClientArea.width || 0 >= nClientArea.height) {
return false;
}
@@ -326,8 +324,14 @@ public class NewtCanvasSWT extends Canvas implements WindowClosingProtocol {
updateSizeCheck();
final int w = clientArea.width;
final int h = clientArea.height;
-
- newtChild.getScreen().getDisplay().setEDTUtil(swtEDTUtil);
+
+ // set SWT EDT and start it
+ {
+ final Display newtDisplay = newtChild.getScreen().getDisplay();
+ final EDTUtil edt = new SWTEDTUtil(newtDisplay, getDisplay());
+ newtDisplay.setEDTUtil(edt);
+ edt.invoke(true, new Runnable() { public void run() { } } ); // start EDT
+ }
newtChild.setSize(w, h);
newtChild.reparentWindow(nativeWindow);
diff --git a/src/newt/classes/com/jogamp/newt/swt/SWTEDTUtil.java b/src/newt/classes/com/jogamp/newt/swt/SWTEDTUtil.java
index 3538caa..d4b83d8 100644
--- a/src/newt/classes/com/jogamp/newt/swt/SWTEDTUtil.java
+++ b/src/newt/classes/com/jogamp/newt/swt/SWTEDTUtil.java
@@ -27,7 +27,9 @@
*/
package com.jogamp.newt.swt;
-import org.eclipse.swt.widgets.Display;
+import java.awt.EventQueue;
+
+import jogamp.newt.Debug;
import com.jogamp.newt.util.EDTUtil;
@@ -36,64 +38,243 @@ import com.jogamp.newt.util.EDTUtil;
* of the given {@link Display}.
*/
public class SWTEDTUtil implements EDTUtil {
- private final Display swtDisplay;
+ public static final boolean DEBUG = Debug.debug("EDT");
+
+ private final Object edtLock = new Object(); // locking the EDT start/stop state
+ private final ThreadGroup threadGroup;
+ private final String name;
+ private final Runnable dispatchMessages;
+ private final org.eclipse.swt.widgets.Display swtDisplay;
+ private NewtEventDispatchThread nedt = null;
+ private int start_iter=0;
+ private static long pollPeriod = EDTUtil.defaultEDTPollPeriod;
- public SWTEDTUtil(Display swtDisplay) {
+ public SWTEDTUtil(final com.jogamp.newt.Display newtDisplay, org.eclipse.swt.widgets.Display swtDisplay) {
+ this.threadGroup = Thread.currentThread().getThreadGroup();
+ this.name=Thread.currentThread().getName()+"-SWTDisplay-"+newtDisplay.getFQName()+"-EDT-";
+ this.dispatchMessages = new Runnable() {
+ public void run() {
+ ((jogamp.newt.DisplayImpl) newtDisplay).dispatchMessages();
+ } };
this.swtDisplay = swtDisplay;
+ this.nedt = new NewtEventDispatchThread(threadGroup, name);
+ this.nedt.setDaemon(true); // don't stop JVM from shutdown ..
}
- public final Display getDisplay() {
+ public final org.eclipse.swt.widgets.Display getDisplay() {
return swtDisplay;
}
@Override
public long getPollPeriod() {
- return 0;
+ return pollPeriod;
}
@Override
public void setPollPeriod(long ms) {
+ pollPeriod = ms;
}
@Override
public void reset() {
+ synchronized(edtLock) {
+ waitUntilStopped();
+ if(DEBUG) {
+ System.err.println(Thread.currentThread()+": EDT reset - edt: "+nedt);
+ }
+ this.nedt = new NewtEventDispatchThread(threadGroup, name);
+ this.nedt.setDaemon(true); // don't stop JVM from shutdown ..
+ }
}
- @Override
- public void start() {
+ private final void startImpl() {
+ if(nedt.isAlive()) {
+ throw new RuntimeException("EDT Thread.isAlive(): true, isRunning: "+nedt.isRunning()+", edt: "+nedt);
+ }
+ start_iter++;
+ nedt.setName(name+start_iter);
+ nedt.shouldStop = false;
+ if(DEBUG) {
+ System.err.println(Thread.currentThread()+": EDT START - edt: "+nedt);
+ // Thread.dumpStack();
+ }
+ nedt.start();
}
-
+
@Override
public boolean isCurrentThreadEDT() {
return swtDisplay.getThread() == Thread.currentThread();
}
@Override
+ public final boolean isCurrentThreadNEDT() {
+ return nedt == Thread.currentThread();
+ }
+
+ @Override
+ public final boolean isCurrentThreadEDTorNEDT() {
+ final Thread ct = Thread.currentThread();
+ return ct == swtDisplay.getThread() || ct == nedt ;
+ }
+
+ @Override
public boolean isRunning() {
- return true;
+ return nedt.isRunning() ; // SWT is always running
}
-
+
@Override
- public void invokeStop(Runnable finalTask) {
- swtDisplay.syncExec(finalTask);
+ public final void invokeStop(Runnable task) {
+ invokeImpl(true, task, true);
}
@Override
- public void invoke(boolean wait, Runnable task) {
+ public final void invoke(boolean wait, Runnable task) {
+ invokeImpl(wait, task, false);
+ }
+
+ private void invokeImpl(boolean wait, Runnable task, boolean stop) {
+ if(task == null) {
+ throw new RuntimeException("Null Runnable");
+ }
+ synchronized(edtLock) { // lock the EDT status
+ if( nedt.shouldStop ) {
+ // drop task ..
+ if(DEBUG) {
+ System.err.println("Warning: EDT about (1) to stop, won't enqueue new task: "+nedt);
+ Thread.dumpStack();
+ }
+ return;
+ }
+ // System.err.println(Thread.currentThread()+" XXX stop: "+stop+", tasks: "+edt.tasks.size()+", task: "+task);
+ // Thread.dumpStack();
+ if(stop) {
+ nedt.shouldStop = true;
+ if(DEBUG) {
+ System.err.println(Thread.currentThread()+": EDT signal STOP (on edt: "+isCurrentThreadEDT()+") - "+nedt);
+ // Thread.dumpStack();
+ }
+ }
+
+ // start if should not stop && not started yet
+ if( !stop && !nedt.isRunning() ) {
+ startImpl();
+ }
+ }
if(wait) {
swtDisplay.syncExec(task);
} else {
swtDisplay.asyncExec(task);
}
- }
+ }
@Override
- public void waitUntilIdle() {
- // all sync ..
+ final public void waitUntilIdle() {
+ final NewtEventDispatchThread _edt;
+ synchronized(edtLock) {
+ _edt = nedt;
+ }
+ if(!_edt.isRunning() || EventQueue.isDispatchThread() || _edt == Thread.currentThread()) {
+ return;
+ }
+ try {
+ swtDisplay.syncExec(new Runnable() {
+ public void run() { }
+ });
+ } catch (Exception e) { }
}
@Override
- public void waitUntilStopped() {
- // all sync ..
+ final public void waitUntilStopped() {
+ synchronized(edtLock) {
+ if(nedt.isRunning() && nedt != Thread.currentThread() ) {
+ while(nedt.isRunning()) {
+ try {
+ edtLock.wait();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
}
+
+ class NewtEventDispatchThread extends Thread {
+ volatile boolean shouldStop = false;
+ volatile boolean isRunning = false;
+ Object sync = new Object();
+
+ public NewtEventDispatchThread(ThreadGroup tg, String name) {
+ super(tg, name);
+ }
+
+ final public boolean isRunning() {
+ return isRunning;
+ }
+
+ @Override
+ final public void start() throws IllegalThreadStateException {
+ isRunning = true;
+ super.start();
+ }
+
+ /**
+ * Utilizing locking only on tasks and its execution,
+ * not for event dispatching.
+ */
+ @Override
+ final public void run() {
+ if(DEBUG) {
+ System.err.println(getName()+": EDT run() START "+ getName());
+ }
+ RuntimeException error = null;
+ try {
+ do {
+ // event dispatch
+ if(!shouldStop) {
+ // FIXME: Determine whether we require to run the
+ // delivery of events (dispatch) on AWT-EDT.
+ // Since the WindowDriver itself delivers all Window related events,
+ // this shall not be required.
+ // AWTEDTExecutor.singleton.invoke(true, dispatchMessages);
+ dispatchMessages.run();
+ }
+ // wait
+ synchronized(sync) {
+ if(!shouldStop) {
+ try {
+ sync.wait(pollPeriod);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ } while(!shouldStop) ;
+ } catch (Throwable t) {
+ // handle errors ..
+ shouldStop = true;
+ if(t instanceof RuntimeException) {
+ error = (RuntimeException) t;
+ } else {
+ error = new RuntimeException("Within EDT", t);
+ }
+ } finally {
+ if(DEBUG) {
+ System.err.println(getName()+": EDT run() END "+ getName()+", "+error);
+ }
+ synchronized(edtLock) {
+ isRunning = !shouldStop;
+ if(!isRunning) {
+ edtLock.notifyAll();
+ }
+ }
+ if(DEBUG) {
+ System.err.println(getName()+": EDT run() EXIT "+ getName()+", exception: "+error);
+ }
+ if(null!=error) {
+ throw error;
+ }
+ } // finally
+ } // run()
+ } // EventDispatchThread
+
}
diff --git a/src/newt/classes/com/jogamp/newt/util/EDTUtil.java b/src/newt/classes/com/jogamp/newt/util/EDTUtil.java
index 4493e27..7e19d9d 100644
--- a/src/newt/classes/com/jogamp/newt/util/EDTUtil.java
+++ b/src/newt/classes/com/jogamp/newt/util/EDTUtil.java
@@ -28,6 +28,9 @@
package com.jogamp.newt.util;
+import jogamp.newt.DisplayImpl;
+import com.jogamp.newt.event.NEWTEvent;
+
/**
* EDT stands for Event Dispatch Thread.
* <p>
@@ -63,25 +66,46 @@ public interface EDTUtil {
/**
* Create a new EDT. One should invoke <code>reset()</code><br>
- * after <code>invokeStop(..)</code> in case another <code>start()</code> or <code>invoke(..)</code>
+ * after <code>invokeStop(..)</code> in case another start via <code>invoke(..)</code>
* is expected.
*
- * @see #start()
* @see #invoke(boolean, java.lang.Runnable)
* @see #invokeStop(java.lang.Runnable)
*/
public void reset();
/**
- * Start the EDT
+ * Returns true if the current thread is the event dispatch thread (EDT).
+ * <p>
+ * The EDT is the platform specific thread dispatching toolkit-events
+ * and executing toolkit-tasks enqueued via {@link #invoke(boolean, Runnable)}.
+ * </p>
+ * <p>
+ * Usually it is the same thread as used to dequeue informal {@link NEWTEvent}s (NEDT), see {@link #isCurrentThreadNEDT()},
+ * however, this may differ, e.g. SWT and AWT implementation.
+ * </p>
*/
- public void start();
+ public boolean isCurrentThreadEDT();
/**
- * @return True if the current thread is the EDT thread
+ * Returns true if the current thread is the internal NEWT event dequeue thread (NEDT).
+ * <p>
+ * The NEDT is the NEWT thread used to dequeue informal {@link NEWTEvent}s enqueued internally
+ * via {@link DisplayImpl#enqueueEvent(boolean, NEWTEvent)}.
+ * </p>
+ * <p>
+ * Usually it is the same thread as the EDT, see {@link #isCurrentThreadEDT()},
+ * however, this may differ, e.g. SWT and AWT implementation.
+ * </p>
*/
- public boolean isCurrentThreadEDT();
-
+ public boolean isCurrentThreadNEDT();
+
+ /**
+ * Returns <code>true</code> if either {@link #isCurrentThreadEDT()} or {@link #isCurrentThreadNEDT()} is <code>true</code>,
+ * otherwise <code>false</code>.
+ */
+ public boolean isCurrentThreadEDTorNEDT();
+
/**
* @return True if EDT is running
*/
@@ -101,9 +125,9 @@ public interface EDTUtil {
public void invokeStop(Runnable finalTask);
/**
+ * Shall start the thread if not running.<br>
* Append task to the EDT task queue.<br>
* Wait until execution is finished if <code>wait == true</code>.<br>
- * Shall start the thread if not running.<br>
* Can be issued from within EDT, ie from within an enqueued task.<br>
*
* @throws RuntimeException in case EDT is stopped and not {@link #reset()}
diff --git a/src/newt/classes/com/jogamp/newt/util/MainThread.java b/src/newt/classes/com/jogamp/newt/util/MainThread.java
index bbe415b..5e79e9b 100644
--- a/src/newt/classes/com/jogamp/newt/util/MainThread.java
+++ b/src/newt/classes/com/jogamp/newt/util/MainThread.java
@@ -74,7 +74,7 @@ import jogamp.newt.NEWTJNILibLoader;
*
* To support your NEWT Window platform,
* you have to pass your <i>main thread</i> actions to {@link #invoke invoke(..)},
- * have a look at the {@link com.jogamp.newt.macosx.MacWindow MacWindow} implementation.<br>
+ * have a look at the {@link jogamp.newt.driver.macosx.WindowDriver NEWT Mac OSX Window} driver implementation.<br>
* <i>TODO</i>: Some hardcoded dependencies exist in this implementation,
* where you have to patch this code or factor it out. <P>
*
@@ -92,7 +92,7 @@ import jogamp.newt.NEWTJNILibLoader;
* Which starts 4 threads, each with a window and OpenGL rendering.<br>
*/
public class MainThread {
- private static final String MACOSXDisplayClassName = "jogamp.newt.driver.macosx.MacDisplay";
+ private static final String MACOSXDisplayClassName = "jogamp.newt.driver.macosx.DisplayDriver";
private static final Platform.OSType osType;
private static final boolean isMacOSX;
private static final ThreadGroup rootThreadGroup;
@@ -101,7 +101,7 @@ public class MainThread {
public static final boolean HINT_USE_MAIN_THREAD;
static {
- NativeWindowFactory.initSingleton(true);
+ NativeWindowFactory.initSingleton();
NEWTJNILibLoader.loadNEWT();
HINT_USE_MAIN_THREAD = !NativeWindowFactory.isAWTAvailable() ||
Debug.getBooleanProperty("newt.MainThread.force", true);
diff --git a/src/newt/classes/jogamp/newt/DefaultEDTUtil.java b/src/newt/classes/jogamp/newt/DefaultEDTUtil.java
index bdbe960..18418a8 100644
--- a/src/newt/classes/jogamp/newt/DefaultEDTUtil.java
+++ b/src/newt/classes/jogamp/newt/DefaultEDTUtil.java
@@ -49,12 +49,12 @@ import com.jogamp.newt.util.EDTUtil;
public class DefaultEDTUtil implements EDTUtil {
public static final boolean DEBUG = Debug.debug("EDT");
- private ThreadGroup threadGroup;
+ private final Object edtLock = new Object(); // locking the EDT start/stop state
+ private final ThreadGroup threadGroup;
+ private final String name;
+ private final Runnable dispatchMessages;
private EventDispatchThread edt = null;
- private Object edtLock = new Object(); // locking the EDT start/stop state
- private String name;
- int start_iter=0;
- private Runnable dispatchMessages;
+ private int start_iter=0;
private static long pollPeriod = EDTUtil.defaultEDTPollPeriod;
public DefaultEDTUtil(ThreadGroup tg, String name, Runnable dispatchMessages) {
@@ -65,14 +65,17 @@ public class DefaultEDTUtil implements EDTUtil {
this.edt.setDaemon(true); // don't stop JVM from shutdown ..
}
+ @Override
final public long getPollPeriod() {
return pollPeriod;
}
+ @Override
final public void setPollPeriod(long ms) {
pollPeriod = ms;
}
+ @Override
public final void reset() {
synchronized(edtLock) {
waitUntilStopped();
@@ -88,36 +91,46 @@ public class DefaultEDTUtil implements EDTUtil {
}
}
- public final void start() {
- synchronized(edtLock) {
- if(!edt.isRunning() && !edt.shouldStop) {
- if(edt.isAlive()) {
- throw new RuntimeException("EDT Thread.isAlive(): true, isRunning: "+edt.isRunning()+", edt: "+edt+", tasks: "+edt.tasks.size());
- }
- start_iter++;
- edt.setName(name+start_iter);
- edt.shouldStop = false;
- if(DEBUG) {
- System.err.println(Thread.currentThread()+": EDT START - edt: "+edt);
- // Thread.dumpStack();
- }
- edt.start();
- }
+ private final void startImpl() {
+ if(edt.isAlive()) {
+ throw new RuntimeException("EDT Thread.isAlive(): true, isRunning: "+edt.isRunning()+", edt: "+edt+", tasks: "+edt.tasks.size());
}
+ start_iter++;
+ edt.setName(name+start_iter);
+ edt.shouldStop = false;
+ if(DEBUG) {
+ System.err.println(Thread.currentThread()+": EDT START - edt: "+edt);
+ // Thread.dumpStack();
+ }
+ edt.start();
}
+ @Override
public final boolean isCurrentThreadEDT() {
- return edt == Thread.currentThread();
+ return edt == Thread.currentThread(); // EDT == NEDT
+ }
+
+ @Override
+ public final boolean isCurrentThreadNEDT() {
+ return edt == Thread.currentThread(); // EDT == NEDT
}
+ @Override
+ public final boolean isCurrentThreadEDTorNEDT() {
+ return edt == Thread.currentThread(); // EDT == NEDT
+ }
+
+ @Override
public final boolean isRunning() {
return edt.isRunning() ;
}
+ @Override
public final void invokeStop(Runnable task) {
invokeImpl(true, task, true);
}
+ @Override
public final void invoke(boolean wait, Runnable task) {
invokeImpl(wait, task, false);
}
@@ -158,8 +171,11 @@ public class DefaultEDTUtil implements EDTUtil {
}
}
} else {
+ // start if should not stop && not started yet
+ if( !stop && !edt.isRunning() ) {
+ startImpl();
+ }
synchronized(edt.tasks) {
- start(); // start if not started yet and !shouldStop
wait = wait && edt.isRunning();
rTask = new RunnableTask(task,
wait ? rTaskLock : null,
@@ -195,6 +211,7 @@ public class DefaultEDTUtil implements EDTUtil {
}
}
+ @Override
final public void waitUntilIdle() {
final EventDispatchThread _edt;
synchronized(edtLock) {
@@ -215,6 +232,7 @@ public class DefaultEDTUtil implements EDTUtil {
}
}
+ @Override
final public void waitUntilStopped() {
synchronized(edtLock) {
if(edt.isRunning() && edt != Thread.currentThread() ) {
diff --git a/src/newt/classes/jogamp/newt/DisplayImpl.java b/src/newt/classes/jogamp/newt/DisplayImpl.java
index b178bb5..fbccc57 100644
--- a/src/newt/classes/jogamp/newt/DisplayImpl.java
+++ b/src/newt/classes/jogamp/newt/DisplayImpl.java
@@ -42,9 +42,9 @@ import com.jogamp.newt.event.NEWTEventConsumer;
import jogamp.newt.event.NEWTEventTask;
import com.jogamp.newt.util.EDTUtil;
import java.util.ArrayList;
+
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeWindowException;
-import javax.media.nativewindow.NativeWindowFactory;
public abstract class DisplayImpl extends Display {
private static int serialno = 1;
@@ -52,26 +52,9 @@ public abstract class DisplayImpl extends Display {
private static Class<?> getDisplayClass(String type)
throws ClassNotFoundException
{
- Class<?> displayClass = NewtFactory.getCustomClass(type, "Display");
- if(null==displayClass) {
- if (NativeWindowFactory.TYPE_ANDROID == type) {
- displayClass = Class.forName("jogamp.newt.driver.android.AndroidDisplay");
- } else if (NativeWindowFactory.TYPE_EGL == type) {
- displayClass = Class.forName("jogamp.newt.driver.kd.KDDisplay");
- } else if (NativeWindowFactory.TYPE_WINDOWS == type) {
- displayClass = Class.forName("jogamp.newt.driver.windows.WindowsDisplay");
- } else if (NativeWindowFactory.TYPE_MACOSX == type) {
- displayClass = Class.forName("jogamp.newt.driver.macosx.MacDisplay");
- } else if (NativeWindowFactory.TYPE_X11 == type) {
- displayClass = Class.forName("jogamp.newt.driver.x11.X11Display");
- } else if (NativeWindowFactory.TYPE_AWT == type) {
- displayClass = Class.forName("jogamp.newt.driver.awt.AWTDisplay");
- } else {
- throw new RuntimeException("Unknown display type \"" + type + "\"");
- }
- }
+ final Class<?> displayClass = NewtFactory.getCustomClass(type, "DisplayDriver");
if(null==displayClass) {
- throw new ClassNotFoundException("Failed to find NEWT Display Class <"+type+".Display>");
+ throw new ClassNotFoundException("Failed to find NEWT Display Class <"+type+".DisplayDriver>");
}
return displayClass;
}
@@ -84,7 +67,7 @@ public abstract class DisplayImpl extends Display {
name = display.validateDisplayName(name, handle);
synchronized(displayList) {
if(reuse) {
- Display display0 = Display.getLastDisplayOf(type, name, -1);
+ Display display0 = Display.getLastDisplayOf(type, name, -1, true /* shared only */);
if(null != display0) {
if(DEBUG) {
System.err.println("Display.create() REUSE: "+display0+" "+getThreadName());
@@ -92,9 +75,9 @@ public abstract class DisplayImpl extends Display {
return display0;
}
}
+ display.exclusive = !reuse;
display.name = name;
display.type=type;
- display.destroyWhenUnused=false;
display.refCount=0;
display.id = serialno++;
display.fqname = getFQName(display.type, display.name, display.id);
@@ -112,7 +95,7 @@ public abstract class DisplayImpl extends Display {
throw new RuntimeException(e);
}
}
-
+
@Override
public boolean equals(Object obj) {
if (obj == null) {
@@ -134,10 +117,12 @@ public abstract class DisplayImpl extends Display {
return true;
}
+ @Override
public int hashCode() {
return hashCode;
}
+ @Override
public synchronized final void createNative()
throws NativeWindowException
{
@@ -166,10 +151,6 @@ public abstract class DisplayImpl extends Display {
}
}
- protected boolean shallRunOnEDT() {
- return true;
- }
-
protected EDTUtil createEDTUtil() {
final EDTUtil def;
if(NewtFactory.useEDT()) {
@@ -187,8 +168,7 @@ public abstract class DisplayImpl extends Display {
public EDTUtil setEDTUtil(EDTUtil newEDTUtil) {
if(null == newEDTUtil) {
newEDTUtil = createEDTUtil();
- }
- if( newEDTUtil == edtUtil ) {
+ } else if( newEDTUtil == edtUtil ) {
if(DEBUG) {
System.err.println("Display.setEDTUtil: "+newEDTUtil+" - keep!");
}
@@ -198,12 +178,7 @@ public abstract class DisplayImpl extends Display {
if(DEBUG) {
System.err.println("Display.setEDTUtil: "+oldEDTUtil+" -> "+newEDTUtil);
}
- if(null != oldEDTUtil) {
- stopEDT( new Runnable() { public void run() {} } );
- // ready for restart ..
- oldEDTUtil.waitUntilStopped();
- oldEDTUtil.reset();
- }
+ removeEDT( new Runnable() { public void run() {} } );
edtUtil = newEDTUtil;
return oldEDTUtil;
}
@@ -213,16 +188,19 @@ public abstract class DisplayImpl extends Display {
return edtUtil;
}
- private void stopEDT(final Runnable task) {
- if( shallRunOnEDT() && null!=edtUtil ) {
+ private void removeEDT(final Runnable task) {
+ if(null!=edtUtil) {
edtUtil.invokeStop(task);
+ // ready for restart ..
+ edtUtil.waitUntilStopped();
+ edtUtil.reset();
} else {
task.run();
}
}
public void runOnEDTIfAvail(boolean wait, final Runnable task) {
- if( shallRunOnEDT() && null!=edtUtil && !edtUtil.isCurrentThreadEDT()) {
+ if( null!=edtUtil && !edtUtil.isCurrentThreadEDT()) {
edtUtil.invoke(wait, task);
} else {
task.run();
@@ -231,18 +209,17 @@ public abstract class DisplayImpl extends Display {
public boolean validateEDT() {
if(0==refCount && null==aDevice && null != edtUtil && edtUtil.isRunning()) {
- stopEDT( new Runnable() {
+ removeEDT( new Runnable() {
public void run() {
// nop
}
} );
- edtUtil.waitUntilStopped();
- edtUtil.reset();
return true;
}
return false;
}
+ @Override
public synchronized final void destroy() {
if(DEBUG) {
dumpDisplayList("Display.destroy("+getFQName()+") BEGIN");
@@ -258,17 +235,13 @@ public abstract class DisplayImpl extends Display {
}
final AbstractGraphicsDevice f_aDevice = aDevice;
final DisplayImpl f_dpy = this;
- stopEDT( new Runnable() {
+ removeEDT( new Runnable() {
public void run() {
if ( null != f_aDevice ) {
f_dpy.closeNativeImpl();
}
}
} );
- if(null!=edtUtil) {
- edtUtil.waitUntilStopped();
- edtUtil.reset();
- }
aDevice = null;
refCount=0;
if(DEBUG) {
@@ -309,21 +282,30 @@ public abstract class DisplayImpl extends Display {
protected abstract void createNativeImpl();
protected abstract void closeNativeImpl();
+ @Override
public final int getId() {
return id;
}
+ @Override
public final String getType() {
return type;
}
+ @Override
public final String getName() {
return name;
}
+ @Override
public final String getFQName() {
return fqname;
}
+
+ @Override
+ public final boolean isExclusive() {
+ return exclusive;
+ }
public static final String nilString = "nil" ;
@@ -343,9 +325,10 @@ public abstract class DisplayImpl extends Display {
sb.append(name);
sb.append("-");
sb.append(id);
- return sb.toString().intern();
+ return sb.toString();
}
+ @Override
public final long getHandle() {
if(null!=aDevice) {
return aDevice.getHandle();
@@ -353,14 +336,17 @@ public abstract class DisplayImpl extends Display {
return 0;
}
+ @Override
public final AbstractGraphicsDevice getGraphicsDevice() {
return aDevice;
}
+ @Override
public synchronized final boolean isNativeValid() {
return null != aDevice;
}
+ @Override
public boolean isEDTRunning() {
if(null!=edtUtil) {
return edtUtil.isRunning();
@@ -370,9 +356,10 @@ public abstract class DisplayImpl extends Display {
@Override
public String toString() {
- return "NEWT-Display["+getFQName()+", refCount "+refCount+", hasEDT "+(null!=edtUtil)+", edtRunning "+isEDTRunning()+", "+aDevice+"]";
+ return "NEWT-Display["+getFQName()+", excl "+exclusive+", refCount "+refCount+", hasEDT "+(null!=edtUtil)+", edtRunning "+isEDTRunning()+", "+aDevice+"]";
}
+ /** Dispatch native Toolkit messageges */
protected abstract void dispatchMessagesNative();
private Object eventsLock = new Object();
@@ -384,7 +371,7 @@ public abstract class DisplayImpl extends Display {
DisplayImpl.this.dispatchMessages();
}
}
- DispatchMessagesRunnable dispatchMessagesRunnable = new DispatchMessagesRunnable();
+ protected DispatchMessagesRunnable dispatchMessagesRunnable = new DispatchMessagesRunnable();
final void dispatchMessage(final NEWTEventTask eventTask) {
final NEWTEvent event = eventTask.get();
@@ -422,6 +409,7 @@ public abstract class DisplayImpl extends Display {
eventTask.notifyCaller();
}
+ @Override
public void dispatchMessages() {
// System.err.println("Display.dispatchMessages() 0 "+this+" "+getThreadName());
if(0==refCount || // no screens
@@ -464,8 +452,8 @@ public abstract class DisplayImpl extends Display {
return;
}
- // can't wait if we are on EDT -> consume right away
- if(wait && edtUtil.isCurrentThreadEDT()) {
+ // can't wait if we are on EDT or NEDT -> consume right away
+ if(wait && edtUtil.isCurrentThreadEDTorNEDT() ) {
dispatchMessage(new NEWTEventTask(e, null));
return;
}
@@ -494,20 +482,23 @@ public abstract class DisplayImpl extends Display {
public interface DisplayRunnable<T> {
T run(long dpy);
}
- public final <T> T runWithLockedDisplayHandle(DisplayRunnable<T> action) {
- final AbstractGraphicsDevice aDevice = getGraphicsDevice();
- if(null == aDevice) {
- throw new RuntimeException("null device - not initialized: "+this);
- }
+ public static final <T> T runWithLockedDevice(AbstractGraphicsDevice device, DisplayRunnable<T> action) {
T res;
- aDevice.lock();
+ device.lock();
try {
- res = action.run(aDevice.getHandle());
+ res = action.run(device.getHandle());
} finally {
- aDevice.unlock();
+ device.unlock();
}
return res;
}
+ public final <T> T runWithLockedDisplayDevice(DisplayRunnable<T> action) {
+ final AbstractGraphicsDevice device = getGraphicsDevice();
+ if(null == device) {
+ throw new RuntimeException("null device - not initialized: "+this);
+ }
+ return runWithLockedDevice(device, action);
+ }
protected EDTUtil edtUtil = null;
protected int id;
@@ -516,7 +507,7 @@ public abstract class DisplayImpl extends Display {
protected String fqname;
protected int hashCode;
protected int refCount; // number of Display references by Screen
- protected boolean destroyWhenUnused;
+ protected boolean exclusive; // do not share this display, uses NullLock!
protected AbstractGraphicsDevice aDevice;
}
diff --git a/src/newt/classes/jogamp/newt/OffscreenWindow.java b/src/newt/classes/jogamp/newt/OffscreenWindow.java
index ba98ca3..c6c1814 100644
--- a/src/newt/classes/jogamp/newt/OffscreenWindow.java
+++ b/src/newt/classes/jogamp/newt/OffscreenWindow.java
@@ -39,20 +39,16 @@ import javax.media.nativewindow.AbstractGraphicsScreen;
import javax.media.nativewindow.GraphicsConfigurationFactory;
import javax.media.nativewindow.MutableSurface;
import javax.media.nativewindow.NativeWindowException;
-import javax.media.nativewindow.ProxySurface;
import javax.media.nativewindow.VisualIDHolder;
import javax.media.nativewindow.util.Insets;
import javax.media.nativewindow.util.Point;
public class OffscreenWindow extends WindowImpl implements MutableSurface {
- long surfaceHandle = 0;
- ProxySurface.UpstreamSurfaceHook upstreamHook;
- ProxySurface dummySurface;
+ long surfaceHandle;
public OffscreenWindow() {
- upstreamHook = null;
- dummySurface = null;
+ surfaceHandle = 0;
}
static long nextWindowHandle = 0x100; // start here - a marker
@@ -62,17 +58,6 @@ public class OffscreenWindow extends WindowImpl implements MutableSurface {
throw new NativeWindowException("Capabilities is onscreen");
}
final AbstractGraphicsScreen aScreen = getScreen().getGraphicsScreen();
- /** Cannot use OpenGL here ..
- if(capsRequested instanceof GLCapabilitiesImmutable) {
- final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) capsRequested;
- if(caps.isFBO() && GLContext.isFBOAvailable(aScreen.getDevice(), caps.getGLProfile()) ) {
- final GLDrawableFactoryImpl factory = (GLDrawableFactoryImpl) GLDrawableFactory.getFactory(caps.getGLProfile());
- final GLCapabilitiesImmutable dummyCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(caps);
- final ProxySurface dummySurface = factory.createDummySurfaceImpl(aScreen.getDevice(), false, dummyCaps, null, 64, 64);
- upstreamHook = dummySurface.getUpstreamSurfaceHook();
- dummySurface.createNotify();
- }
- } */
final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(aScreen.getDevice(), capsRequested).chooseGraphicsConfiguration(
capsRequested, capsRequested, capabilitiesChooser, aScreen, VisualIDHolder.VID_UNDEFINED);
if (null == cfg) {
@@ -83,6 +68,7 @@ public class OffscreenWindow extends WindowImpl implements MutableSurface {
synchronized(OffscreenWindow.class) {
setWindowHandle(nextWindowHandle++);
}
+ visibleChanged(false, true);
}
protected void closeNativeImpl() {
@@ -92,11 +78,6 @@ public class OffscreenWindow extends WindowImpl implements MutableSurface {
@Override
public synchronized void destroy() {
super.destroy();
- if(null != dummySurface) {
- dummySurface.destroyNotify();
- dummySurface = null;
- upstreamHook = null;
- }
surfaceHandle = 0;
}
@@ -106,10 +87,6 @@ public class OffscreenWindow extends WindowImpl implements MutableSurface {
@Override
public long getSurfaceHandle() {
- if(null != dummySurface) {
- return dummySurface.getSurfaceHandle();
- // return upstreamHook.getWidth();
- }
return surfaceHandle;
}
@@ -128,8 +105,8 @@ public class OffscreenWindow extends WindowImpl implements MutableSurface {
}
protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) {
+ sizeChanged(false, width, height, false);
if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) {
- sizeChanged(false, width, height, false);
visibleChanged(false, 0 != ( FLAG_IS_VISIBLE & flags));
} else {
/**
diff --git a/src/newt/classes/jogamp/newt/ScreenImpl.java b/src/newt/classes/jogamp/newt/ScreenImpl.java
index cf614b6..56d6f67 100644
--- a/src/newt/classes/jogamp/newt/ScreenImpl.java
+++ b/src/newt/classes/jogamp/newt/ScreenImpl.java
@@ -42,7 +42,6 @@ import java.util.List;
import javax.media.nativewindow.AbstractGraphicsScreen;
import javax.media.nativewindow.NativeWindowException;
-import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.util.Dimension;
import javax.media.nativewindow.util.DimensionImmutable;
import javax.media.nativewindow.util.Point;
@@ -90,31 +89,13 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
});
}
- @SuppressWarnings("unchecked")
- private static Class<? extends Screen> getScreenClass(String type) throws ClassNotFoundException
+ private static Class<?> getScreenClass(String type) throws ClassNotFoundException
{
- Class<?> screenClass = NewtFactory.getCustomClass(type, "Screen");
+ final Class<?> screenClass = NewtFactory.getCustomClass(type, "ScreenDriver");
if(null==screenClass) {
- if (NativeWindowFactory.TYPE_ANDROID == type) {
- screenClass = Class.forName("jogamp.newt.driver.android.AndroidScreen");
- } else if (NativeWindowFactory.TYPE_EGL == type) {
- screenClass = Class.forName("jogamp.newt.driver.kd.KDScreen");
- } else if (NativeWindowFactory.TYPE_WINDOWS == type) {
- screenClass = Class.forName("jogamp.newt.driver.windows.WindowsScreen");
- } else if (NativeWindowFactory.TYPE_MACOSX == type) {
- screenClass = Class.forName("jogamp.newt.driver.macosx.MacScreen");
- } else if (NativeWindowFactory.TYPE_X11 == type) {
- screenClass = Class.forName("jogamp.newt.driver.x11.X11Screen");
- } else if (NativeWindowFactory.TYPE_AWT == type) {
- screenClass = Class.forName("jogamp.newt.driver.awt.AWTScreen");
- } else {
- throw new RuntimeException("Unknown window type \"" + type + "\"");
- }
+ throw new ClassNotFoundException("Failed to find NEWT Screen Class <"+type+".ScreenDriver>");
}
- if(null==screenClass) {
- throw new ClassNotFoundException("Failed to find NEWT Screen Class <"+type+".Screen>");
- }
- return (Class<? extends Screen>)screenClass;
+ return screenClass;
}
public static Screen create(Display display, int idx) {
@@ -133,7 +114,7 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
}
}
synchronized(screenList) {
- Class<? extends Screen> screenClass = getScreenClass(display.getType());
+ Class<?> screenClass = getScreenClass(display.getType());
ScreenImpl screen = (ScreenImpl) screenClass.newInstance();
screen.display = (DisplayImpl) display;
idx = screen.validateScreenIndex(idx);
@@ -148,7 +129,7 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
}
}
screen.screen_idx = idx;
- screen.fqname = (display.getFQName()+idx).intern();
+ screen.fqname = display.getFQName()+"-s"+idx;
screen.hashCode = screen.fqname.hashCode();
screenList.add(screen);
if(DEBUG) {
@@ -296,7 +277,7 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
protected void updateVirtualScreenOriginAndSize() {
getVirtualScreenOriginAndSize(vOrigin, vSize);
if(DEBUG) {
- System.err.println("Detected screen origin "+vOrigin+", size "+vSize);
+ System.err.println("Detected virtual screen origin "+vOrigin+", size "+vSize);
}
}
@@ -340,18 +321,24 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
return null;
}
+ private final ScreenModeStatus getScreenModeStatus(boolean throwException) {
+ final String key = this.getFQName();
+ final ScreenModeStatus res = ScreenModeStatus.getScreenModeStatus(key);
+ if(null == res & throwException) {
+ throw new InternalError("ScreenModeStatus.getScreenModeStatus("+key+") == null");
+ }
+ return res;
+ }
+
public ScreenMode getOriginalScreenMode() {
- ScreenModeStatus sms = ScreenModeStatus.getScreenModeStatus(this.getFQName());
+ final ScreenModeStatus sms = getScreenModeStatus(false);
return ( null != sms ) ? sms.getOriginalScreenMode() : null ;
}
public ScreenMode getCurrentScreenMode() {
ScreenMode smU = null;
- ScreenModeStatus sms = ScreenModeStatus.getScreenModeStatus(this.getFQName());
- if(null == sms) {
- throw new InternalError("ScreenModeStatus.getScreenModeStatus("+this.getFQName()+") == null");
- }
- ScreenMode sm0 = getCurrentScreenModeIntern();
+ final ScreenModeStatus sms = getScreenModeStatus(true);
+ final ScreenMode sm0 = getCurrentScreenModeIntern();
if(null == sm0) {
throw new InternalError("getCurrentScreenModeImpl() == null");
}
@@ -397,12 +384,23 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
System.err.println("Screen.setCurrentScreenMode ("+(System.nanoTime()-tStart)/1e6+"ms): fireScreenModeChangeNotify() "+smU);
}
- success = setCurrentScreenModeImpl(smU);
- if(DEBUG) {
- System.err.println("Screen.setCurrentScreenMode ("+(System.nanoTime()-tStart)/1e6+"ms): setCurrentScreenModeImpl() "+smU+", success: "+success);
+ success = setCurrentScreenModeImpl(smU);
+ if(success) {
+ if(DEBUG) {
+ System.err.println("Screen.setCurrentScreenMode ("+(System.nanoTime()-tStart)/1e6+"ms): setCurrentScreenModeImpl() "+smU+", success(1): "+success);
+ }
+ } else {
+ // 2nd attempt validate!
+ final ScreenMode queriedCurrent = getCurrentScreenMode(); // may fireScreenModeChanged(..) if successful and differs!
+ final ScreenMode smsCurrent = sms.getCurrentScreenMode();
+ success = smsCurrent.hashCode() == smU.hashCode() && queriedCurrent.hashCode() == smU.hashCode() ;
+ if(DEBUG) {
+ System.err.println("Screen.setCurrentScreenMode.2: queried "+queriedCurrent);
+ System.err.println("Screen.setCurrentScreenMode.2: SMS "+smsCurrent);
+ System.err.println("Screen.setCurrentScreenMode ("+(System.nanoTime()-tStart)/1e6+"ms): setCurrentScreenModeImpl() "+smU+", success(2): "+success);
+ }
}
-
- sms.fireScreenModeChanged(smU, success);
+ sms.fireScreenModeChanged(smU, success);
if(DEBUG) {
System.err.println("Screen.setCurrentScreenMode ("+(System.nanoTime()-tStart)/1e6+"ms): X.X "+smU+", success: "+success);
}
@@ -501,7 +499,7 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
res = getCurrentScreenModeImpl();
}
if(null == res) {
- if( 0==getWidth()*getHeight() ) {
+ if( 0>=getWidth() || 0>=getHeight() ) {
updateVirtualScreenOriginAndSize();
}
int[] props = new int[ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL];
diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java
index 606101a..4f8eb3d 100644
--- a/src/newt/classes/jogamp/newt/WindowImpl.java
+++ b/src/newt/classes/jogamp/newt/WindowImpl.java
@@ -37,6 +37,7 @@ package jogamp.newt;
import java.util.ArrayList;
import java.lang.reflect.Method;
+import com.jogamp.common.util.IntBitfield;
import com.jogamp.common.util.ReflectionUtil;
import com.jogamp.newt.NewtFactory;
import com.jogamp.newt.Display;
@@ -85,7 +86,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
private volatile long windowHandle = 0; // lifecycle critical
private volatile boolean visible = false; // lifecycle critical
private RecursiveLock windowLock = LockFactory.createRecursiveLock(); // Window instance wide lock
- private RecursiveLock surfaceLock = LockFactory.createRecursiveLock(); // Surface only lock
+ private int surfaceLockCount = 0; // surface lock recursion count
private ScreenImpl screen; // never null after create - may change reference though (reparent)
private boolean screenReferenceAdded = false;
@@ -152,26 +153,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
private static Class<?> getWindowClass(String type)
throws ClassNotFoundException
{
- Class<?> windowClass = NewtFactory.getCustomClass(type, "Window");
+ final Class<?> windowClass = NewtFactory.getCustomClass(type, "WindowDriver");
if(null==windowClass) {
- if (NativeWindowFactory.TYPE_ANDROID == type) {
- windowClass = Class.forName("jogamp.newt.driver.android.AndroidWindow");
- } else if (NativeWindowFactory.TYPE_EGL == type) {
- windowClass = Class.forName("jogamp.newt.driver.kd.KDWindow");
- } else if (NativeWindowFactory.TYPE_WINDOWS == type) {
- windowClass = Class.forName("jogamp.newt.driver.windows.WindowsWindow");
- } else if (NativeWindowFactory.TYPE_MACOSX == type) {
- windowClass = Class.forName("jogamp.newt.driver.macosx.MacWindow");
- } else if (NativeWindowFactory.TYPE_X11 == type) {
- windowClass = Class.forName("jogamp.newt.driver.x11.X11Window");
- } else if (NativeWindowFactory.TYPE_AWT == type) {
- windowClass = Class.forName("jogamp.newt.driver.awt.AWTWindow");
- } else {
- throw new NativeWindowException("Unknown window type \"" + type + "\"");
- }
- }
- if(null==windowClass) {
- throw new ClassNotFoundException("Failed to find NEWT Window Class <"+type+".Window>");
+ throw new ClassNotFoundException("Failed to find NEWT Window Class <"+type+".WindowDriver>");
}
return windowClass;
}
@@ -570,10 +554,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
@Override
public final int lockSurface() throws NativeWindowException, RuntimeException {
final RecursiveLock _wlock = windowLock;
- final RecursiveLock _slock = surfaceLock;
_wlock.lock();
- _slock.lock();
- int res = _slock.getHoldCount() == 1 ? LOCK_SURFACE_NOT_READY : LOCK_SUCCESS; // new lock ?
+ surfaceLockCount++;
+ int res = ( 1 == surfaceLockCount ) ? LOCK_SURFACE_NOT_READY : LOCK_SUCCESS; // new lock ?
if ( LOCK_SURFACE_NOT_READY == res ) {
try {
@@ -590,7 +573,6 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
} finally {
if (LOCK_SURFACE_NOT_READY >= res) {
- _slock.unlock();
_wlock.unlock();
}
}
@@ -600,12 +582,10 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
@Override
public final void unlockSurface() {
- final RecursiveLock _slock = surfaceLock;
final RecursiveLock _wlock = windowLock;
- _slock.validateLocked();
_wlock.validateLocked();
- if (_slock.getHoldCount() == 1) {
+ if ( 1 == surfaceLockCount ) {
final AbstractGraphicsDevice adevice = getGraphicsConfiguration().getScreen().getDevice();
try {
unlockSurfaceImpl();
@@ -613,42 +593,48 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
adevice.unlock();
}
}
- _slock.unlock();
+ surfaceLockCount--;
_wlock.unlock();
}
@Override
public final boolean isSurfaceLockedByOtherThread() {
- return surfaceLock.isLockedByOtherThread();
+ return windowLock.isLockedByOtherThread();
}
@Override
public final Thread getSurfaceLockOwner() {
- return surfaceLock.getOwner();
+ return windowLock.getOwner();
}
public final RecursiveLock getLock() {
return windowLock;
}
+ @Override
public long getSurfaceHandle() {
return windowHandle; // default: return window handle
}
+ @Override
public boolean surfaceSwap() {
return false;
}
+ @Override
public final AbstractGraphicsConfiguration getGraphicsConfiguration() {
return config.getNativeGraphicsConfiguration();
}
- public final long getDisplayHandle() {
- return getScreen().getDisplay().getHandle();
+ @Override
+ public long getDisplayHandle() {
+ // Actually: return getGraphicsConfiguration().getScreen().getDevice().getHandle();
+ return screen.getDisplay().getHandle(); // shortcut
}
+ @Override
public final int getScreenIndex() {
- return getScreen().getIndex();
+ return screen.getIndex();
}
//----------------------------------------------------------------------
@@ -784,11 +770,15 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
}
- public void setVisible(boolean visible) {
+ protected void setVisible(boolean wait, boolean visible) {
if(DEBUG_IMPLEMENTATION) {
System.err.println("Window setVisible: START ("+getThreadName()+") "+getX()+"/"+getY()+" "+getWidth()+"x"+getHeight()+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible: "+this.visible+" -> "+visible+", parentWindowHandle "+toHexString(parentWindowHandle)+", parentWindow "+(null!=parentWindow));
}
- runOnEDTIfAvail(true, new VisibleAction(visible));
+ runOnEDTIfAvail(wait, new VisibleAction(visible));
+ }
+
+ public void setVisible(boolean visible) {
+ setVisible(true, visible);
}
private class SetSizeAction implements Runnable {
@@ -800,27 +790,18 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
public final void run() {
- boolean recreate = false;
final RecursiveLock _lock = windowLock;
_lock.lock();
try {
if ( !isFullscreen() && ( getWidth() != width || getHeight() != height ) ) {
- recreate = isNativeValid() && !getGraphicsConfiguration().getChosenCapabilities().isOnscreen();
if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window setSize: START "+getWidth()+"x"+getHeight()+" -> "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible "+visible+", recreate "+recreate);
- }
- if(recreate) {
- // will trigger visibleAction:=2 -> create if wasVisible
- final boolean wasVisible = WindowImpl.this.visible;
- screen.addReference(); // retain screen
- destroyAction.run();
- WindowImpl.this.visible = wasVisible;
+ System.err.println("Window setSize: START "+getWidth()+"x"+getHeight()+" -> "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible "+visible);
}
int visibleAction; // 0 nop, 1 invisible, 2 visible (create)
- if ( isNativeValid() && 0>=width*height && visible ) {
+ if ( visible && isNativeValid() && ( 0 >= width || 0 >= height ) ) {
visibleAction=1; // invisible
defineSize(0, 0);
- } else if ( !isNativeValid() && 0<width*height && visible ) {
+ } else if ( visible && !isNativeValid() && 0 < width && 0 < height ) {
visibleAction = 2; // visible (create)
defineSize(width, height);
} else if ( isNativeValid() ) {
@@ -840,9 +821,6 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
}
} finally {
- if(recreate) {
- screen.removeReference(); // bring back ref-count
- }
_lock.unlock();
}
}
@@ -957,11 +935,15 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
*/
protected static boolean isOffscreenInstance(NativeWindow cWin, NativeWindow pWin) {
boolean ofs = false;
- if( null != cWin.getGraphicsConfiguration() ) {
- ofs = !cWin.getGraphicsConfiguration().getChosenCapabilities().isOnscreen();
+ final AbstractGraphicsConfiguration cWinCfg = cWin.getGraphicsConfiguration();
+ if( null != cWinCfg ) {
+ ofs = !cWinCfg.getChosenCapabilities().isOnscreen();
}
- if( !ofs && null != pWin && null != pWin.getGraphicsConfiguration() ) {
- ofs |= !pWin.getGraphicsConfiguration().getChosenCapabilities().isOnscreen();
+ if( !ofs && null != pWin ) {
+ final AbstractGraphicsConfiguration pWinCfg = pWin.getGraphicsConfiguration();
+ if( null != pWinCfg ) {
+ ofs = !pWinCfg.getChosenCapabilities().isOnscreen();
+ }
}
return ofs;
}
@@ -1069,7 +1051,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
setScreen( (ScreenImpl) newScreen );
}
}
- if( 0<width*height ) {
+ if( 0 < width && 0 < height ) {
operation = ReparentOperation.ACTION_NATIVE_CREATION;
} else {
operation = ReparentOperation.ACTION_NATIVE_CREATION_PENDING;
@@ -1108,7 +1090,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
} else if( !isNativeValid() || forceDestroyCreate ) {
// Destroy this window and mark it for [pending] creation.
destroy();
- if( 0<width*height ) {
+ if( 0 < width && 0 < height ) {
operation = ReparentOperation.ACTION_NATIVE_CREATION;
} else {
operation = ReparentOperation.ACTION_NATIVE_CREATION_PENDING;
@@ -1575,8 +1557,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
for (int i = 0; i < keyListeners.size(); i++ ) {
sb.append(keyListeners.get(i)+", ");
}
- sb.append("], surfaceLock "+surfaceLock);
- sb.append(", windowLock "+windowLock+"]");
+ sb.append("], windowLock "+windowLock+"]");
return sb.toString();
}
@@ -1731,6 +1712,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
// set current state
WindowImpl.this.fullscreen = fullscreen;
+ final ScreenMode sm = screen.getCurrentScreenMode();
int x,y,w,h;
if(fullscreen) {
@@ -1740,8 +1722,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
nfs_height = getHeight();
x = screen.getX();
y = screen.getY();
- w = screen.getWidth();
- h = screen.getHeight();
+ w = sm.getRotatedWidth();
+ h = sm.getRotatedHeight();
} else {
x = nfs_x;
y = nfs_y;
@@ -1763,7 +1745,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
}
if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window fs: "+fullscreen+" "+x+"/"+y+" "+w+"x"+h+", "+isUndecorated()+", "+screen);
+ System.err.println("Window fs: "+fullscreen+" "+x+"/"+y+" "+w+"x"+h+", "+isUndecorated()+
+ ", virtl-size: "+screen.getWidth()+"x"+screen.getHeight()+", SM "+sm.getRotatedWidth()+"x"+sm.getRotatedHeight());
}
DisplayImpl display = (DisplayImpl) screen.getDisplay();
@@ -2187,6 +2170,33 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
//
// KeyListener/Event Support
//
+ protected IntBitfield keyPressedState = new IntBitfield(KeyEvent.VK_CONTEXT_MENU+1);
+ protected IntBitfield keyRepeatState = new IntBitfield(KeyEvent.VK_CONTEXT_MENU+1);
+
+ /**
+ * @param keyCode
+ * @return 1 if pressed, 0 if not pressed, -1 if not handled.
+ */
+ protected final int isKeyPressed(int keyCode) {
+ if( 0 <= keyCode && keyCode < keyPressedState.capacity() ) {
+ return keyPressedState.get(keyCode) ? 1 : 0;
+ }
+ return -1;
+ }
+ /**
+ * @param keyCode
+ * @return 1 if pressed, 0 if not pressed, -1 if not handled.
+ */
+ protected final int isKeyInAutoRepeat(int keyCode) {
+ if( 0 <= keyCode && keyCode < keyRepeatState.capacity() ) {
+ return keyRepeatState.get(keyCode) ? 1 : 0;
+ }
+ return -1;
+ }
+ protected final boolean isKeyCodeTracked(int keyCode) {
+ return 0 <= keyCode && keyCode < keyRepeatState.capacity();
+ }
+
public void sendKeyEvent(int eventType, int modifiers, int keyCode, char keyChar) {
consumeKeyEvent(new KeyEvent(eventType, this, System.currentTimeMillis(), modifiers, keyCode, keyChar) );
}
diff --git a/src/newt/classes/jogamp/newt/driver/android/AndroidDisplay.java b/src/newt/classes/jogamp/newt/driver/android/DisplayDriver.java
similarity index 94%
copy from src/newt/classes/jogamp/newt/driver/android/AndroidDisplay.java
copy to src/newt/classes/jogamp/newt/driver/android/DisplayDriver.java
index 0a43c9b..a367462 100644
--- a/src/newt/classes/jogamp/newt/driver/android/AndroidDisplay.java
+++ b/src/newt/classes/jogamp/newt/driver/android/DisplayDriver.java
@@ -33,11 +33,11 @@ import jogamp.opengl.egl.*;
import javax.media.nativewindow.*;
-public class AndroidDisplay extends jogamp.newt.DisplayImpl {
+public class DisplayDriver extends jogamp.newt.DisplayImpl {
static {
NEWTJNILibLoader.loadNEWT();
- if (!AndroidWindow.initIDs0()) {
+ if (!WindowDriver.initIDs0()) {
throw new NativeWindowException("Failed to initialize Android NEWT Windowing library");
}
}
@@ -47,7 +47,7 @@ public class AndroidDisplay extends jogamp.newt.DisplayImpl {
}
- public AndroidDisplay() {
+ public DisplayDriver() {
}
protected void createNativeImpl() {
diff --git a/src/newt/classes/jogamp/newt/driver/android/NewtBaseActivity.java b/src/newt/classes/jogamp/newt/driver/android/NewtBaseActivity.java
index 4537fa9..28c4da7 100644
--- a/src/newt/classes/jogamp/newt/driver/android/NewtBaseActivity.java
+++ b/src/newt/classes/jogamp/newt/driver/android/NewtBaseActivity.java
@@ -36,7 +36,7 @@ import javax.media.opengl.FPSCounter;
import com.jogamp.newt.Window;
import com.jogamp.opengl.util.Animator;
-import jogamp.newt.driver.android.AndroidWindow;
+import jogamp.newt.driver.android.WindowDriver;
import android.app.Activity;
import android.content.Context;
@@ -83,10 +83,10 @@ public class NewtBaseActivity extends Activity {
*/
public void setContentView(android.view.Window androidWindow, Window newtWindow) {
newtWindow = newtWindow.getDelegatedWindow();
- if(newtWindow instanceof AndroidWindow) {
+ if(newtWindow instanceof WindowDriver) {
adaptTheme4Transparency(newtWindow.getRequestedCapabilities());
layoutForNEWTWindow(androidWindow, newtWindow);
- AndroidWindow newtAWindow = (AndroidWindow)newtWindow;
+ WindowDriver newtAWindow = (WindowDriver)newtWindow;
androidWindow.setContentView(newtAWindow.getAndroidView());
registerNEWTWindow(newtAWindow);
} else {
@@ -107,8 +107,8 @@ public class NewtBaseActivity extends Activity {
*/
public void addContentView(android.view.Window androidWindow, Window newtWindow, android.view.ViewGroup.LayoutParams params) {
newtWindow = newtWindow.getDelegatedWindow();
- if(newtWindow instanceof AndroidWindow) {
- AndroidWindow newtAWindow = (AndroidWindow)newtWindow;
+ if(newtWindow instanceof WindowDriver) {
+ WindowDriver newtAWindow = (WindowDriver)newtWindow;
androidWindow.addContentView(newtAWindow.getAndroidView(), params);
registerNEWTWindow(newtAWindow);
} else {
@@ -265,16 +265,17 @@ public class NewtBaseActivity extends Activity {
if(!isDelegatedActivity()) {
super.onResume();
}
- if(null != animator) {
- animator.resume();
- animator.resetFPSCounter();
- }
- for(int i=newtWindows.size()-1; i>=0; i--) {
+ for(int i=0; i<newtWindows.size(); i++) {
final Window win = newtWindows.get(i);
+ win.setVisible(true);
if(win instanceof FPSCounter) {
((FPSCounter)win).resetFPSCounter();
}
}
+ if(null != animator) {
+ animator.resume();
+ animator.resetFPSCounter();
+ }
}
@Override
@@ -283,6 +284,10 @@ public class NewtBaseActivity extends Activity {
if(null != animator) {
animator.pause();
}
+ for(int i=0; i<newtWindows.size(); i++) {
+ final Window win = newtWindows.get(i);
+ win.setVisible(false);
+ }
if(!isDelegatedActivity()) {
super.onPause();
}
diff --git a/src/newt/classes/jogamp/newt/driver/android/NewtVersionActivity.java b/src/newt/classes/jogamp/newt/driver/android/NewtVersionActivity.java
index 36b8333..a49f164 100644
--- a/src/newt/classes/jogamp/newt/driver/android/NewtVersionActivity.java
+++ b/src/newt/classes/jogamp/newt/driver/android/NewtVersionActivity.java
@@ -69,7 +69,7 @@ public class NewtVersionActivity extends NewtBaseActivity {
glWindow.setUndecorated(true);
glWindow.setSize(32, 32);
glWindow.setPosition(0, 0);
- final android.view.View androidGLView = ((AndroidWindow)glWindow.getDelegatedWindow()).getAndroidView();
+ final android.view.View androidGLView = ((WindowDriver)glWindow.getDelegatedWindow()).getAndroidView();
viewGroup.addView(androidGLView, new android.widget.FrameLayout.LayoutParams(glWindow.getWidth(), glWindow.getHeight(), Gravity.BOTTOM|Gravity.RIGHT));
registerNEWTWindow(glWindow);
diff --git a/src/newt/classes/jogamp/newt/driver/android/AndroidScreen.java b/src/newt/classes/jogamp/newt/driver/android/ScreenDriver.java
similarity index 97%
rename from src/newt/classes/jogamp/newt/driver/android/AndroidScreen.java
rename to src/newt/classes/jogamp/newt/driver/android/ScreenDriver.java
index e108ed0..795aac5 100644
--- a/src/newt/classes/jogamp/newt/driver/android/AndroidScreen.java
+++ b/src/newt/classes/jogamp/newt/driver/android/ScreenDriver.java
@@ -41,13 +41,13 @@ import android.util.DisplayMetrics;
import android.view.Surface;
import android.view.WindowManager;
-public class AndroidScreen extends jogamp.newt.ScreenImpl {
+public class ScreenDriver extends jogamp.newt.ScreenImpl {
static {
- AndroidDisplay.initSingleton();
+ DisplayDriver.initSingleton();
}
- public AndroidScreen() {
+ public ScreenDriver() {
}
protected void createNativeImpl() {
diff --git a/src/newt/classes/jogamp/newt/driver/android/AndroidWindow.java b/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java
similarity index 89%
rename from src/newt/classes/jogamp/newt/driver/android/AndroidWindow.java
rename to src/newt/classes/jogamp/newt/driver/android/WindowDriver.java
index 73192a0..f185206 100644
--- a/src/newt/classes/jogamp/newt/driver/android/AndroidWindow.java
+++ b/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java
@@ -39,6 +39,7 @@ import javax.media.nativewindow.util.Insets;
import javax.media.nativewindow.util.Point;
import javax.media.opengl.GLCapabilitiesChooser;
import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLException;
import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
@@ -59,9 +60,9 @@ import android.view.inputmethod.InputMethodManager;
import android.view.SurfaceView;
import android.view.View;
-public class AndroidWindow extends jogamp.newt.WindowImpl implements Callback2 {
+public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 {
static {
- AndroidDisplay.initSingleton();
+ DisplayDriver.initSingleton();
}
public static CapabilitiesImmutable fixCaps(boolean matchFormatPrecise, int format, CapabilitiesImmutable rCaps) {
@@ -142,11 +143,11 @@ public class AndroidWindow extends jogamp.newt.WindowImpl implements Callback2 {
@Override
public boolean onTouch(View v, android.view.MotionEvent event) {
- final com.jogamp.newt.event.MouseEvent[] newtEvents = AndroidNewtEventFactory.createMouseEvents(event, AndroidWindow.this);
+ final com.jogamp.newt.event.MouseEvent[] newtEvents = AndroidNewtEventFactory.createMouseEvents(event, WindowDriver.this);
if(null != newtEvents) {
focusChanged(false, true);
for(int i=0; i<newtEvents.length; i++) {
- AndroidWindow.this.enqueueEvent(false, newtEvents[i]);
+ WindowDriver.this.enqueueEvent(false, newtEvents[i]);
}
try { Thread.sleep((long) (1000.0F/30.0F)); }
catch(InterruptedException e) { }
@@ -157,10 +158,10 @@ public class AndroidWindow extends jogamp.newt.WindowImpl implements Callback2 {
@Override
public boolean onKey(View v, int keyCode, android.view.KeyEvent event) {
- final com.jogamp.newt.event.KeyEvent[] newtEvents = AndroidNewtEventFactory.createKeyEvents(keyCode, event, AndroidWindow.this);
+ final com.jogamp.newt.event.KeyEvent[] newtEvents = AndroidNewtEventFactory.createKeyEvents(keyCode, event, WindowDriver.this);
if(null != newtEvents) {
for(int i=0; i<newtEvents.length; i++) {
- AndroidWindow.this.enqueueEvent(false, newtEvents[i]);
+ WindowDriver.this.enqueueEvent(false, newtEvents[i]);
}
return true;
}
@@ -169,7 +170,7 @@ public class AndroidWindow extends jogamp.newt.WindowImpl implements Callback2 {
@Override
public void onFocusChange(View v, boolean hasFocus) {
- AndroidWindow.this.focusChanged(false, hasFocus);
+ WindowDriver.this.focusChanged(false, hasFocus);
}
}
@@ -178,7 +179,7 @@ public class AndroidWindow extends jogamp.newt.WindowImpl implements Callback2 {
return new Class<?>[] { Context.class } ;
}
- public AndroidWindow() {
+ public WindowDriver() {
reset();
}
@@ -212,7 +213,7 @@ public class AndroidWindow extends jogamp.newt.WindowImpl implements Callback2 {
androidView.setFocusableInTouchMode(true);
final SurfaceHolder sh = androidView.getHolder();
- sh.addCallback(AndroidWindow.this);
+ sh.addCallback(WindowDriver.this);
sh.setFormat(getFormat(getRequestedCapabilities()));
// default size -> TBD !
@@ -263,15 +264,24 @@ public class AndroidWindow extends jogamp.newt.WindowImpl implements Callback2 {
setGraphicsConfiguration(eglConfig);
setWindowHandle(surfaceHandle);
focusChanged(false, true);
- Log.d(MD.TAG, "createNativeImpl X");
+ Log.d(MD.TAG, "createNativeImpl X: eglSurfaceHandle 0x"+Long.toHexString(eglSurface));
}
@Override
protected void closeNativeImpl() {
+ Log.d(MD.TAG, "closeNativeImpl 0 - surfaceHandle 0x"+Long.toHexString(surfaceHandle)+
+ ", eglSurfaceHandle 0x"+Long.toHexString(eglSurface)+
+ ", format [a "+androidFormat+", n "+nativeFormat+"], "+getX()+"/"+getY()+" "+getWidth()+"x"+getHeight()+" - "+Thread.currentThread().getName());
+ if(0 != eglSurface) {
+ final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) getScreen().getDisplay().getGraphicsDevice();
+ if (!EGL.eglDestroySurface(eglDevice.getHandle(), eglSurface)) {
+ throw new GLException("Error destroying window surface (eglDestroySurface)");
+ }
+ eglSurface = 0;
+ }
release0(surfaceHandle);
surface = null;
surfaceHandle = 0;
- eglSurface = 0;
}
@Override
@@ -291,25 +301,33 @@ public class AndroidWindow extends jogamp.newt.WindowImpl implements Callback2 {
}
}
- protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) {
+ protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) {
+ boolean res = true;
+
if( 0 != ( FLAG_CHANGE_FULLSCREEN & flags) ) {
Log.d(MD.TAG, "reconfigureWindowImpl.setFullscreen post creation (setContentView()) n/a");
return false;
}
- if(width>0 || height>0) {
+ if(getWidth() != width || getHeight() != height) {
if(0!=getWindowHandle()) {
Log.d(MD.TAG, "reconfigureWindowImpl.setSize n/a");
- return false;
+ res = false;
+ } else {
+ defineSize(width, height);
}
}
- if(x>=0 || y>=0) {
- Log.d(MD.TAG, "reconfigureWindowImpl.setPos n/a");
- return false;
+ if(getX() != x || getY() != y) {
+ if(0!=getWindowHandle()) {
+ Log.d(MD.TAG, "reconfigureWindowImpl.setPos n/a");
+ res = false;
+ } else {
+ definePosition(x, y);
+ }
}
if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) {
visibleChanged(false, 0 != ( FLAG_IS_VISIBLE & flags));
}
- return true;
+ return res;
}
protected Point getLocationOnScreenImpl(int x, int y) {
@@ -410,7 +428,7 @@ public class AndroidWindow extends jogamp.newt.WindowImpl implements Callback2 {
getX()+"/"+getY()+" "+nWidth+"x"+nHeight+", visible: "+isVisible());
if(isVisible()) {
- setVisible(true);
+ setVisible(false, true);
}
}
sizeChanged(false, aWidth, aHeight, false);
diff --git a/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java b/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java
index a795004..17eb6a2 100644
--- a/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java
+++ b/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -34,6 +35,7 @@
package jogamp.newt.driver.awt;
import java.awt.Canvas;
+import java.awt.Graphics;
import java.awt.GraphicsDevice;
import java.awt.GraphicsConfiguration;
import java.lang.reflect.Method;
@@ -60,14 +62,16 @@ public class AWTCanvas extends Canvas {
private GraphicsConfiguration chosen;
private AWTGraphicsConfiguration awtConfig;
+ private WindowDriver newtWindowImpl;
private CapabilitiesChooser chooser=null;
private CapabilitiesImmutable capabilities;
private boolean displayConfigChanged=false;
- public AWTCanvas(CapabilitiesImmutable capabilities, CapabilitiesChooser chooser) {
+ public AWTCanvas(WindowDriver newtWindowImpl, CapabilitiesImmutable capabilities, CapabilitiesChooser chooser) {
super();
+ this.newtWindowImpl = newtWindowImpl;
if(null==capabilities) {
throw new NativeWindowException("Capabilities null");
}
@@ -79,6 +83,25 @@ public class AWTCanvas extends Canvas {
return awtConfig;
}
+ /**
+ * Overridden from Canvas to prevent the AWT's clearing of the
+ * canvas from interfering with the OpenGL rendering.
+ */
+ @Override
+ public void update(Graphics g) {
+ paint(g);
+ }
+
+ /** Overridden to cause OpenGL rendering to be performed during
+ repaint cycles. Subclasses which override this method must call
+ super.paint() in their paint() method in order to function
+ properly.
+ */
+ @Override
+ public void paint(Graphics g) {
+ newtWindowImpl.windowRepaint(0, 0, getWidth(), getHeight());
+ }
+
public boolean hasDeviceChanged() {
boolean res = displayConfigChanged;
displayConfigChanged=false;
@@ -274,10 +297,10 @@ public class AWTCanvas extends Canvas {
private void disableBackgroundErase() {
if (!disableBackgroundEraseInitialized) {
try {
- AccessController.doPrivileged(new PrivilegedAction() {
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
try {
- Class clazz = getToolkit().getClass();
+ Class<?> clazz = getToolkit().getClass();
while (clazz != null && disableBackgroundEraseMethod == null) {
try {
disableBackgroundEraseMethod =
diff --git a/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java b/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java
index 9426511..8771f5c 100644
--- a/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java
+++ b/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java
@@ -28,72 +28,239 @@
package jogamp.newt.driver.awt;
-import javax.media.opengl.Threading;
+import java.awt.EventQueue;
import com.jogamp.newt.util.EDTUtil;
+
+import jogamp.common.awt.AWTEDTExecutor;
import jogamp.newt.Debug;
public class AWTEDTUtil implements EDTUtil {
public static final boolean DEBUG = Debug.debug("EDT");
-
- private static AWTEDTUtil singletonMainThread = new AWTEDTUtil(); // one singleton MainThread
- public static AWTEDTUtil getSingleton() {
- return singletonMainThread;
- }
+ private final Object edtLock = new Object(); // locking the EDT start/stop state
+ private final ThreadGroup threadGroup;
+ private final String name;
+ private final Runnable dispatchMessages;
+ private NewtEventDispatchThread nedt = null;
+ private int start_iter=0;
+ private static long pollPeriod = EDTUtil.defaultEDTPollPeriod;
- AWTEDTUtil() {
- // package private access ..
+ public AWTEDTUtil(ThreadGroup tg, String name, Runnable dispatchMessages) {
+ this.threadGroup = tg;
+ this.name=Thread.currentThread().getName()+"-"+name+"-EDT-";
+ this.dispatchMessages=dispatchMessages;
+ this.nedt = new NewtEventDispatchThread(threadGroup, name);
+ this.nedt.setDaemon(true); // don't stop JVM from shutdown ..
}
+ @Override
final public long getPollPeriod() {
- return 0;
+ return pollPeriod;
}
+ @Override
final public void setPollPeriod(long ms) {
- // nop
+ pollPeriod = ms;
}
+ @Override
final public void reset() {
- // nop AWT is always running
+ synchronized(edtLock) {
+ waitUntilStopped();
+ if(DEBUG) {
+ System.err.println(Thread.currentThread()+": EDT reset - edt: "+nedt);
+ }
+ this.nedt = new NewtEventDispatchThread(threadGroup, name);
+ this.nedt.setDaemon(true); // don't stop JVM from shutdown ..
+ }
}
- final public void start() {
- // nop AWT is always running
+ private final void startImpl() {
+ if(nedt.isAlive()) {
+ throw new RuntimeException("EDT Thread.isAlive(): true, isRunning: "+nedt.isRunning()+", edt: "+nedt);
+ }
+ start_iter++;
+ nedt.setName(name+start_iter);
+ nedt.shouldStop = false;
+ if(DEBUG) {
+ System.err.println(Thread.currentThread()+": EDT START - edt: "+nedt);
+ // Thread.dumpStack();
+ }
+ nedt.start();
}
+ @Override
final public boolean isCurrentThreadEDT() {
- return Threading.isToolkitThread();
+ return EventQueue.isDispatchThread();
}
+ @Override
+ public final boolean isCurrentThreadNEDT() {
+ return nedt == Thread.currentThread();
+ }
+
+ @Override
+ public final boolean isCurrentThreadEDTorNEDT() {
+ return EventQueue.isDispatchThread() || nedt == Thread.currentThread();
+ }
+
+ @Override
final public boolean isRunning() {
- return true; // AWT is always running
+ return nedt.isRunning() ; // AWT is always running
}
- final public void invokeStop(Runnable r) {
- invoke(true, r); // AWT is always running
+ @Override
+ public final void invokeStop(Runnable task) {
+ invokeImpl(true, task, true);
}
- final public void invoke(boolean wait, Runnable r) {
- if(r == null) {
- return;
- }
-
- Threading.invoke(wait, r, null);
+ @Override
+ public final void invoke(boolean wait, Runnable task) {
+ invokeImpl(wait, task, false);
}
+
+ private void invokeImpl(boolean wait, Runnable task, boolean stop) {
+ if(task == null) {
+ throw new RuntimeException("Null Runnable");
+ }
+ synchronized(edtLock) { // lock the EDT status
+ if( nedt.shouldStop ) {
+ // drop task ..
+ if(DEBUG) {
+ System.err.println("Warning: EDT about (1) to stop, won't enqueue new task: "+nedt);
+ Thread.dumpStack();
+ }
+ return;
+ }
+ // System.err.println(Thread.currentThread()+" XXX stop: "+stop+", tasks: "+edt.tasks.size()+", task: "+task);
+ // Thread.dumpStack();
+ if(stop) {
+ nedt.shouldStop = true;
+ if(DEBUG) {
+ System.err.println(Thread.currentThread()+": EDT signal STOP (on edt: "+isCurrentThreadEDT()+") - "+nedt);
+ // Thread.dumpStack();
+ }
+ }
+
+ // start if should not stop && not started yet
+ if( !stop && !nedt.isRunning() ) {
+ startImpl();
+ }
+ }
+ AWTEDTExecutor.singleton.invoke(wait, task);
+ }
+ @Override
final public void waitUntilIdle() {
- // wait until previous events are processed, at least ..
+ final NewtEventDispatchThread _edt;
+ synchronized(edtLock) {
+ _edt = nedt;
+ }
+ if(!_edt.isRunning() || EventQueue.isDispatchThread() || _edt == Thread.currentThread()) {
+ return;
+ }
try {
- Threading.invoke(true, new Runnable() {
+ AWTEDTExecutor.singleton.invoke(true, new Runnable() {
public void run() { }
- }, null);
+ });
} catch (Exception e) { }
}
+ @Override
final public void waitUntilStopped() {
- // nop: AWT is always running
+ synchronized(edtLock) {
+ if(nedt.isRunning() && nedt != Thread.currentThread() ) {
+ while(nedt.isRunning()) {
+ try {
+ edtLock.wait();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
}
+
+ class NewtEventDispatchThread extends Thread {
+ volatile boolean shouldStop = false;
+ volatile boolean isRunning = false;
+ Object sync = new Object();
+
+ public NewtEventDispatchThread(ThreadGroup tg, String name) {
+ super(tg, name);
+ }
+
+ final public boolean isRunning() {
+ return isRunning;
+ }
+
+ @Override
+ final public void start() throws IllegalThreadStateException {
+ isRunning = true;
+ super.start();
+ }
+
+ /**
+ * Utilizing locking only on tasks and its execution,
+ * not for event dispatching.
+ */
+ @Override
+ final public void run() {
+ if(DEBUG) {
+ System.err.println(getName()+": EDT run() START "+ getName());
+ }
+ RuntimeException error = null;
+ try {
+ do {
+ // event dispatch
+ if(!shouldStop) {
+ // FIXME: Determine whether we require to run the
+ // delivery of events (dispatch) on AWT-EDT.
+ // Since the WindowDriver itself delivers all Window related events,
+ // this shall not be required.
+ // AWTEDTExecutor.singleton.invoke(true, dispatchMessages);
+ dispatchMessages.run();
+ }
+ // wait
+ synchronized(sync) {
+ if(!shouldStop) {
+ try {
+ sync.wait(pollPeriod);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ } while(!shouldStop) ;
+ } catch (Throwable t) {
+ // handle errors ..
+ shouldStop = true;
+ if(t instanceof RuntimeException) {
+ error = (RuntimeException) t;
+ } else {
+ error = new RuntimeException("Within EDT", t);
+ }
+ } finally {
+ if(DEBUG) {
+ System.err.println(getName()+": EDT run() END "+ getName()+", "+error);
+ }
+ synchronized(edtLock) {
+ isRunning = !shouldStop;
+ if(!isRunning) {
+ edtLock.notifyAll();
+ }
+ }
+ if(DEBUG) {
+ System.err.println(getName()+": EDT run() EXIT "+ getName()+", exception: "+error);
+ }
+ if(null!=error) {
+ throw error;
+ }
+ } // finally
+ } // run()
+ } // EventDispatchThread
+
}
diff --git a/src/newt/classes/jogamp/newt/driver/awt/AWTDisplay.java b/src/newt/classes/jogamp/newt/driver/awt/DisplayDriver.java
similarity index 84%
rename from src/newt/classes/jogamp/newt/driver/awt/AWTDisplay.java
rename to src/newt/classes/jogamp/newt/driver/awt/DisplayDriver.java
index 65f8b47..ead567d 100644
--- a/src/newt/classes/jogamp/newt/driver/awt/AWTDisplay.java
+++ b/src/newt/classes/jogamp/newt/driver/awt/DisplayDriver.java
@@ -38,10 +38,11 @@ import com.jogamp.nativewindow.awt.AWTGraphicsDevice;
import com.jogamp.newt.NewtFactory;
import com.jogamp.newt.util.EDTUtil;
+import jogamp.newt.DefaultEDTUtil;
import jogamp.newt.DisplayImpl;
-public class AWTDisplay extends DisplayImpl {
- public AWTDisplay() {
+public class DisplayDriver extends DisplayImpl {
+ public DisplayDriver() {
}
protected void createNativeImpl() {
@@ -52,15 +53,12 @@ public class AWTDisplay extends DisplayImpl {
aDevice = d;
}
- protected void closeNativeImpl() { }
-
- @Override
protected EDTUtil createEDTUtil() {
final EDTUtil def;
if(NewtFactory.useEDT()) {
- def = AWTEDTUtil.getSingleton();
+ def = new AWTEDTUtil(Thread.currentThread().getThreadGroup(), "AWTDisplay-"+getFQName(), dispatchMessagesRunnable);
if(DEBUG) {
- System.err.println("AWTDisplay.createNative("+getFQName()+") Create EDTUtil: "+def.getClass().getName());
+ System.err.println("Display.createNative("+getFQName()+") Create EDTUtil: "+def.getClass().getName());
}
} else {
def = null;
@@ -68,6 +66,10 @@ public class AWTDisplay extends DisplayImpl {
return def;
}
+ protected void closeNativeImpl() {
+ aDevice.close();
+ }
+
protected void dispatchMessagesNative() { /* nop */ }
}
diff --git a/src/newt/classes/jogamp/newt/driver/awt/AWTScreen.java b/src/newt/classes/jogamp/newt/driver/awt/ScreenDriver.java
similarity index 97%
rename from src/newt/classes/jogamp/newt/driver/awt/AWTScreen.java
rename to src/newt/classes/jogamp/newt/driver/awt/ScreenDriver.java
index a3c0281..6b1283a 100644
--- a/src/newt/classes/jogamp/newt/driver/awt/AWTScreen.java
+++ b/src/newt/classes/jogamp/newt/driver/awt/ScreenDriver.java
@@ -42,8 +42,8 @@ import javax.media.nativewindow.util.Point;
import com.jogamp.nativewindow.awt.AWTGraphicsDevice;
import com.jogamp.nativewindow.awt.AWTGraphicsScreen;
-public class AWTScreen extends ScreenImpl {
- public AWTScreen() {
+public class ScreenDriver extends ScreenImpl {
+ public ScreenDriver() {
}
protected void createNativeImpl() {
diff --git a/src/newt/classes/jogamp/newt/driver/awt/AWTWindow.java b/src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java
similarity index 71%
rename from src/newt/classes/jogamp/newt/driver/awt/AWTWindow.java
rename to src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java
index 2b2fed5..bee43a9 100644
--- a/src/newt/classes/jogamp/newt/driver/awt/AWTWindow.java
+++ b/src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java
@@ -36,6 +36,7 @@ package jogamp.newt.driver.awt;
import java.awt.BorderLayout;
import java.awt.Container;
+import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Insets;
@@ -47,6 +48,8 @@ import jogamp.newt.WindowImpl;
import com.jogamp.nativewindow.awt.AWTGraphicsConfiguration;
import com.jogamp.nativewindow.awt.AWTGraphicsDevice;
import com.jogamp.nativewindow.awt.AWTGraphicsScreen;
+import com.jogamp.newt.event.WindowEvent;
+import com.jogamp.newt.event.WindowUpdateEvent;
import com.jogamp.newt.event.awt.AWTKeyAdapter;
import com.jogamp.newt.event.awt.AWTMouseAdapter;
import com.jogamp.newt.event.awt.AWTWindowAdapter;
@@ -55,9 +58,9 @@ import com.jogamp.newt.event.awt.AWTWindowAdapter;
AWT. This is provided for convenience of porting to platforms
supporting Java SE. */
-public class AWTWindow extends WindowImpl {
+public class WindowDriver extends WindowImpl {
- public AWTWindow() {
+ public WindowDriver() {
this(null);
}
@@ -65,7 +68,7 @@ public class AWTWindow extends WindowImpl {
return new Class<?>[] { Container.class } ;
}
- public AWTWindow(Container container) {
+ public WindowDriver(Container container) {
super();
this.container = container;
if(container instanceof Frame) {
@@ -107,18 +110,18 @@ public class AWTWindow extends WindowImpl {
frame.setTitle(getTitle());
}
container.setLayout(new BorderLayout());
- canvas = new AWTCanvas(capsRequested, AWTWindow.this.capabilitiesChooser);
-
- addWindowListener(new LocalWindowListener());
-
- new AWTMouseAdapter(this).addTo(canvas); // fwd all AWT Mouse events to here
- new AWTKeyAdapter(this).addTo(canvas); // fwd all AWT Key events to here
+
+ canvas = new AWTCanvas(this, capsRequested, WindowDriver.this.capabilitiesChooser);
// canvas.addComponentListener(listener);
container.add(canvas, BorderLayout.CENTER);
- container.setSize(getWidth(), getHeight());
- container.setLocation(getX(), getY());
- new AWTWindowAdapter(this).addTo(container); // fwd all AWT Window events to here
+
+ // via EDT ..
+ new AWTMouseAdapter(this).addTo(canvas); // fwd all AWT Mouse events to here
+ new AWTKeyAdapter(this).addTo(canvas); // fwd all AWT Key events to here
+
+ // direct w/o EDT
+ new AWTWindowAdapter(new LocalWindowListener(), this).addTo(canvas); // fwd all AWT Window events to here
reconfigureWindowImpl(getX(), getY(), getWidth(), getHeight(), getReconfigureFlags(FLAG_CHANGE_VISIBILITY | FLAG_CHANGE_DECORATION, true));
// throws exception if failed ..
@@ -152,10 +155,10 @@ public class AWTWindow extends WindowImpl {
setGraphicsConfiguration(cfg);
// propagate new info ..
- ((AWTScreen)getScreen()).setAWTGraphicsScreen((AWTGraphicsScreen)cfg.getScreen());
- ((AWTDisplay)getScreen().getDisplay()).setAWTGraphicsDevice((AWTGraphicsDevice)cfg.getScreen().getDevice());
+ ((ScreenDriver)getScreen()).setAWTGraphicsScreen((AWTGraphicsScreen)cfg.getScreen());
+ ((DisplayDriver)getScreen().getDisplay()).setAWTGraphicsDevice((AWTGraphicsDevice)cfg.getScreen().getDevice());
- ((AWTScreen)getScreen()).updateVirtualScreenOriginAndSize();
+ ((ScreenDriver)getScreen()).updateVirtualScreenOriginAndSize();
}
return res;
}
@@ -174,20 +177,32 @@ public class AWTWindow extends WindowImpl {
frame.setUndecorated(isUndecorated());
} else {
if(DEBUG_IMPLEMENTATION) {
- System.err.println("AWTWindow can't undecorate already created frame");
+ System.err.println(getThreadName()+": AWTWindow can't undecorate already created frame");
}
}
}
+ final Dimension szClient = new Dimension(width, height);
+ canvas.setMinimumSize(szClient);
+ canvas.setPreferredSize(szClient);
+ canvas.setSize(szClient);
+ if(DEBUG_IMPLEMENTATION) {
+ final Insets insets = container.getInsets();
+ final Dimension szContainer = new Dimension(width + insets.left + insets.right,
+ height + insets.top + insets.bottom);
+ System.err.println(getThreadName()+": AWTWindow new size: szClient "+szClient+", szCont "+szContainer+", insets "+insets);
+ }
+
if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) {
+ if(null != frame) {
+ frame.pack();
+ }
+ container.validate();
container.setVisible(0 != ( FLAG_IS_VISIBLE & flags));
}
container.setLocation(x, y);
- Insets insets = container.getInsets();
- container.setSize(width + insets.left + insets.right,
- height + insets.top + insets.bottom);
-
+
if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) {
if( 0 != ( FLAG_IS_VISIBLE & flags ) ) {
if( !hasDeviceChanged() ) {
@@ -200,6 +215,12 @@ public class AWTWindow extends WindowImpl {
}
}
visibleChanged(false, 0 != ( FLAG_IS_VISIBLE & flags));
+ } else {
+ container.invalidate();
+ if(null != frame) {
+ frame.pack();
+ }
+ container.validate();
}
return true;
@@ -216,18 +237,41 @@ public class AWTWindow extends WindowImpl {
return canvas;
}
- class LocalWindowListener extends com.jogamp.newt.event.WindowAdapter {
+ class LocalWindowListener implements com.jogamp.newt.event.WindowListener {
@Override
public void windowMoved(com.jogamp.newt.event.WindowEvent e) {
if(null!=container) {
- definePosition(container.getX(), container.getY());
+ WindowDriver.this.positionChanged(false, container.getX(), container.getY());
}
}
@Override
public void windowResized(com.jogamp.newt.event.WindowEvent e) {
if(null!=canvas) {
- defineSize(canvas.getWidth(), canvas.getHeight());
+ WindowDriver.this.sizeChanged(false, canvas.getWidth(), canvas.getHeight(), false);
+ }
+ }
+ @Override
+ public void windowDestroyNotify(WindowEvent e) {
+ WindowDriver.this.windowDestroyNotify(false);
+ }
+ @Override
+ public void windowDestroyed(WindowEvent e) {
+ if(isNativeValid()) {
+ WindowDriver.this.windowDestroyNotify(true);
}
+
+ }
+ @Override
+ public void windowGainedFocus(WindowEvent e) {
+ WindowDriver.this.focusChanged(false, true);
+ }
+ @Override
+ public void windowLostFocus(WindowEvent e) {
+ WindowDriver.this.focusChanged(false, false);
+ }
+ @Override
+ public void windowRepaint(WindowUpdateEvent e) {
+ WindowDriver.this.windowRepaint(false, 0, 0, getWidth(), getHeight());
}
}
}
diff --git a/src/newt/classes/jogamp/newt/driver/broadcom/egl/Display.java b/src/newt/classes/jogamp/newt/driver/bcm/egl/DisplayDriver.java
similarity index 90%
rename from src/newt/classes/jogamp/newt/driver/broadcom/egl/Display.java
rename to src/newt/classes/jogamp/newt/driver/bcm/egl/DisplayDriver.java
index e3f50b7..cc55c33 100644
--- a/src/newt/classes/jogamp/newt/driver/broadcom/egl/Display.java
+++ b/src/newt/classes/jogamp/newt/driver/bcm/egl/DisplayDriver.java
@@ -32,22 +32,23 @@
*
*/
-package jogamp.newt.driver.broadcom.egl;
+package jogamp.newt.driver.bcm.egl;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeWindowException;
import jogamp.newt.NEWTJNILibLoader;
import jogamp.opengl.egl.EGL;
+import jogamp.opengl.egl.EGLDisplayUtil;
import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
-public class Display extends jogamp.newt.DisplayImpl {
+public class DisplayDriver extends jogamp.newt.DisplayImpl {
static {
NEWTJNILibLoader.loadNEWT();
- if (!Window.initIDs()) {
+ if (!WindowDriver.initIDs()) {
throw new NativeWindowException("Failed to initialize BCEGL Window jmethodIDs");
}
}
@@ -57,11 +58,11 @@ public class Display extends jogamp.newt.DisplayImpl {
}
- public Display() {
+ public DisplayDriver() {
}
protected void createNativeImpl() {
- final long handle = CreateDisplay(Screen.fixedWidth, Screen.fixedHeight);
+ final long handle = CreateDisplay(ScreenDriver.fixedWidth, ScreenDriver.fixedHeight);
if (handle == EGL.EGL_NO_DISPLAY) {
throw new NativeWindowException("BC EGL CreateDisplay failed");
}
@@ -72,6 +73,7 @@ public class Display extends jogamp.newt.DisplayImpl {
if (aDevice.getHandle() != EGL.EGL_NO_DISPLAY) {
DestroyDisplay(aDevice.getHandle());
}
+ aDevice.close();
}
protected void dispatchMessagesNative() {
diff --git a/src/newt/classes/jogamp/newt/driver/broadcom/egl/Screen.java b/src/newt/classes/jogamp/newt/driver/bcm/egl/ScreenDriver.java
similarity index 94%
rename from src/newt/classes/jogamp/newt/driver/broadcom/egl/Screen.java
rename to src/newt/classes/jogamp/newt/driver/bcm/egl/ScreenDriver.java
index 0544bc0..deb2a53 100644
--- a/src/newt/classes/jogamp/newt/driver/broadcom/egl/Screen.java
+++ b/src/newt/classes/jogamp/newt/driver/bcm/egl/ScreenDriver.java
@@ -32,20 +32,20 @@
*
*/
-package jogamp.newt.driver.broadcom.egl;
+package jogamp.newt.driver.bcm.egl;
import javax.media.nativewindow.DefaultGraphicsScreen;
import javax.media.nativewindow.util.Dimension;
import javax.media.nativewindow.util.Point;
-public class Screen extends jogamp.newt.ScreenImpl {
+public class ScreenDriver extends jogamp.newt.ScreenImpl {
static {
- Display.initSingleton();
+ DisplayDriver.initSingleton();
}
- public Screen() {
+ public ScreenDriver() {
}
protected void createNativeImpl() {
diff --git a/src/newt/classes/jogamp/newt/driver/broadcom/egl/Window.java b/src/newt/classes/jogamp/newt/driver/bcm/egl/WindowDriver.java
similarity index 97%
rename from src/newt/classes/jogamp/newt/driver/broadcom/egl/Window.java
rename to src/newt/classes/jogamp/newt/driver/bcm/egl/WindowDriver.java
index 223ad64..49d3d98 100644
--- a/src/newt/classes/jogamp/newt/driver/broadcom/egl/Window.java
+++ b/src/newt/classes/jogamp/newt/driver/bcm/egl/WindowDriver.java
@@ -32,7 +32,7 @@
*
*/
-package jogamp.newt.driver.broadcom.egl;
+package jogamp.newt.driver.bcm.egl;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.GraphicsConfigurationFactory;
@@ -44,12 +44,12 @@ import javax.media.opengl.GLCapabilitiesImmutable;
import jogamp.opengl.egl.EGLGraphicsConfiguration;
-public class Window extends jogamp.newt.WindowImpl {
+public class WindowDriver extends jogamp.newt.WindowImpl {
static {
- Display.initSingleton();
+ DisplayDriver.initSingleton();
}
- public Window() {
+ public WindowDriver() {
}
protected void createNativeImpl() {
diff --git a/src/newt/classes/jogamp/newt/driver/android/AndroidDisplay.java b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/DisplayDriver.java
similarity index 68%
copy from src/newt/classes/jogamp/newt/driver/android/AndroidDisplay.java
copy to src/newt/classes/jogamp/newt/driver/bcm/vc/iv/DisplayDriver.java
index 0a43c9b..08c5c57 100644
--- a/src/newt/classes/jogamp/newt/driver/android/AndroidDisplay.java
+++ b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/DisplayDriver.java
@@ -1,5 +1,5 @@
/**
- * Copyright 2011 JogAmp Community. All rights reserved.
+ * Copyright 2012 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
@@ -26,19 +26,28 @@
* or implied, of JogAmp Community.
*/
-package jogamp.newt.driver.android;
+package jogamp.newt.driver.bcm.vc.iv;
-import jogamp.newt.*;
-import jogamp.opengl.egl.*;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.NativeWindowException;
-import javax.media.nativewindow.*;
+import jogamp.newt.DisplayImpl;
+import jogamp.newt.NEWTJNILibLoader;
+import jogamp.opengl.egl.EGL;
+import jogamp.opengl.egl.EGLDisplayUtil;
-public class AndroidDisplay extends jogamp.newt.DisplayImpl {
+public class DisplayDriver extends DisplayImpl {
static {
NEWTJNILibLoader.loadNEWT();
- if (!AndroidWindow.initIDs0()) {
- throw new NativeWindowException("Failed to initialize Android NEWT Windowing library");
+ if (!DisplayDriver.initIDs()) {
+ throw new NativeWindowException("Failed to initialize bcm.vc.iv Display jmethodIDs");
+ }
+ if (!ScreenDriver.initIDs()) {
+ throw new NativeWindowException("Failed to initialize bcm.vc.iv Screen jmethodIDs");
+ }
+ if (!WindowDriver.initIDs()) {
+ throw new NativeWindowException("Failed to initialize bcm.vc.iv Window jmethodIDs");
}
}
@@ -47,11 +56,11 @@ public class AndroidDisplay extends jogamp.newt.DisplayImpl {
}
- public AndroidDisplay() {
+ public DisplayDriver() {
}
protected void createNativeImpl() {
- // EGL Device
+ // FIXME: map name to EGL_*_DISPLAY
aDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(EGL.EGL_DEFAULT_DISPLAY, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
}
@@ -60,7 +69,10 @@ public class AndroidDisplay extends jogamp.newt.DisplayImpl {
}
protected void dispatchMessagesNative() {
- // n/a .. DispatchMessages();
- }
+ DispatchMessages();
+ }
+
+ protected static native boolean initIDs();
+ private native void DispatchMessages();
}
diff --git a/src/newt/classes/jogamp/newt/driver/android/AndroidDisplay.java b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/ScreenDriver.java
similarity index 57%
rename from src/newt/classes/jogamp/newt/driver/android/AndroidDisplay.java
rename to src/newt/classes/jogamp/newt/driver/bcm/vc/iv/ScreenDriver.java
index 0a43c9b..787d1a1 100644
--- a/src/newt/classes/jogamp/newt/driver/android/AndroidDisplay.java
+++ b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/ScreenDriver.java
@@ -1,5 +1,5 @@
/**
- * Copyright 2011 JogAmp Community. All rights reserved.
+ * Copyright 2012 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
@@ -26,41 +26,48 @@
* or implied, of JogAmp Community.
*/
-package jogamp.newt.driver.android;
+package jogamp.newt.driver.bcm.vc.iv;
-import jogamp.newt.*;
-import jogamp.opengl.egl.*;
+import javax.media.nativewindow.DefaultGraphicsScreen;
+import javax.media.nativewindow.util.Dimension;
+import javax.media.nativewindow.util.Point;
-import javax.media.nativewindow.*;
+import jogamp.newt.ScreenImpl;
-public class AndroidDisplay extends jogamp.newt.DisplayImpl {
+public class ScreenDriver extends ScreenImpl {
static {
- NEWTJNILibLoader.loadNEWT();
-
- if (!AndroidWindow.initIDs0()) {
- throw new NativeWindowException("Failed to initialize Android NEWT Windowing library");
- }
- }
-
- public static void initSingleton() {
- // just exist to ensure static init has been run
+ DisplayDriver.initSingleton();
}
-
- public AndroidDisplay() {
+ public ScreenDriver() {
}
protected void createNativeImpl() {
- // EGL Device
- aDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(EGL.EGL_DEFAULT_DISPLAY, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
+ aScreen = new DefaultGraphicsScreen(getDisplay().getGraphicsDevice(), screen_idx);
+ initNative();
}
- protected void closeNativeImpl() {
- aDevice.close();
+ protected void closeNativeImpl() { }
+
+ protected int validateScreenIndex(int idx) {
+ return 0; // only one screen available
+ }
+
+ protected void getVirtualScreenOriginAndSize(Point virtualOrigin, Dimension virtualSize) {
+ virtualOrigin.setX(0);
+ virtualOrigin.setY(0);
+ virtualSize.setWidth(cachedWidth);
+ virtualSize.setHeight(cachedHeight);
+ }
+
+ protected void setScreenSize(int width, int height) {
+ cachedWidth = width;
+ cachedHeight = height;
}
+
+ private static int cachedWidth = 0;
+ private static int cachedHeight = 0;
- protected void dispatchMessagesNative() {
- // n/a .. DispatchMessages();
- }
+ protected static native boolean initIDs();
+ protected native void initNative();
}
-
diff --git a/src/newt/classes/jogamp/newt/driver/kd/KDWindow.java b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/WindowDriver.java
similarity index 52%
copy from src/newt/classes/jogamp/newt/driver/kd/KDWindow.java
copy to src/newt/classes/jogamp/newt/driver/bcm/vc/iv/WindowDriver.java
index 9f9d694..21fbea9 100644
--- a/src/newt/classes/jogamp/newt/driver/kd/KDWindow.java
+++ b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/WindowDriver.java
@@ -1,107 +1,107 @@
-/*
- * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
- * Copyright (c) 2012 JogAmp Community. All rights reserved.
+/**
+ * Copyright 2012 JogAmp Community. 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 and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
*
- * - Redistribution of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
*
- * - 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.
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community OR
+ * CONTRIBUTORS 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.
*
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
*/
-package jogamp.newt.driver.kd;
+package jogamp.newt.driver.bcm.vc.iv;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.Capabilities;
import javax.media.nativewindow.GraphicsConfigurationFactory;
import javax.media.nativewindow.NativeWindowException;
import javax.media.nativewindow.VisualIDHolder;
-import javax.media.nativewindow.VisualIDHolder.VIDType;
import javax.media.nativewindow.util.Insets;
import javax.media.nativewindow.util.Point;
-import javax.media.opengl.GLCapabilitiesImmutable;
import jogamp.newt.WindowImpl;
-import jogamp.opengl.egl.EGLGraphicsConfiguration;
+import jogamp.newt.driver.linux.LinuxMouseTracker;
-public class KDWindow extends WindowImpl {
+public class WindowDriver extends WindowImpl {
private static final String WINDOW_CLASS_NAME = "NewtWindow";
static {
- KDDisplay.initSingleton();
+ DisplayDriver.initSingleton();
}
- public KDWindow() {
+ public WindowDriver() {
}
protected void createNativeImpl() {
if(0!=getParentWindowHandle()) {
throw new RuntimeException("Window parenting not supported (yet)");
}
+
final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(getScreen().getDisplay().getGraphicsDevice(), capsRequested).chooseGraphicsConfiguration(
capsRequested, capsRequested, capabilitiesChooser, getScreen().getGraphicsScreen(), VisualIDHolder.VID_UNDEFINED);
if (null == cfg) {
throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
}
+ final Capabilities chosenCaps = (Capabilities) cfg.getChosenCapabilities();
+ // FIXME: Pass along opaque flag, since EGL doesn't determine it
+ if(capsRequested.isBackgroundOpaque() != chosenCaps.isBackgroundOpaque()) {
+ chosenCaps.setBackgroundOpaque(capsRequested.isBackgroundOpaque());
+ }
setGraphicsConfiguration(cfg);
-
- GLCapabilitiesImmutable eglCaps = (GLCapabilitiesImmutable) cfg.getChosenCapabilities();
- int eglConfigID = eglCaps.getVisualID(VIDType.EGL_CONFIG);
- long eglConfig = EGLGraphicsConfiguration.EGLConfigId2EGLConfig(getDisplayHandle(), eglConfigID);
-
- eglWindowHandle = CreateWindow(getDisplayHandle(), eglConfig);
- if (eglWindowHandle == 0) {
- throw new NativeWindowException("Error creating egl window: "+cfg+", eglConfigID "+eglConfigID+", eglConfig 0x"+Long.toHexString(eglConfig));
+ nativeWindowHandle = CreateWindow(getWidth(), getHeight(), chosenCaps.isBackgroundOpaque(), chosenCaps.getAlphaBits());
+ if (nativeWindowHandle == 0) {
+ throw new NativeWindowException("Error creating egl window: "+cfg);
}
- setVisible0(eglWindowHandle, false);
- setWindowHandle(RealizeWindow(eglWindowHandle));
+ setVisible0(nativeWindowHandle, false);
+ setWindowHandle(nativeWindowHandle);
if (0 == getWindowHandle()) {
throw new NativeWindowException("Error native Window Handle is null");
}
- windowHandleClose = eglWindowHandle;
+ windowHandleClose = nativeWindowHandle;
+ addWindowListener(LinuxMouseTracker.getSingleton());
+ focusChanged(false, true);
}
protected void closeNativeImpl() {
+ removeWindowListener(LinuxMouseTracker.getSingleton());
+
if(0!=windowHandleClose) {
CloseWindow(windowHandleClose, windowUserData);
windowUserData=0;
}
}
- protected void requestFocusImpl(boolean reparented) { }
+ protected void requestFocusImpl(boolean reparented) {
+ focusChanged(false, true);
+ }
protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) {
if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) {
- setVisible0(eglWindowHandle, 0 != ( FLAG_IS_VISIBLE & flags));
+ setVisible0(nativeWindowHandle, 0 != ( FLAG_IS_VISIBLE & flags));
visibleChanged(false, 0 != ( FLAG_IS_VISIBLE & flags));
}
- if(0!=eglWindowHandle) {
+ if(0!=nativeWindowHandle) {
if(0 != ( FLAG_CHANGE_FULLSCREEN & flags)) {
final boolean fs = 0 != ( FLAG_IS_FULLSCREEN & flags) ;
- setFullScreen0(eglWindowHandle, fs);
+ setFullScreen0(nativeWindowHandle, fs);
if(fs) {
return true;
}
@@ -111,7 +111,7 @@ public class KDWindow extends WindowImpl {
width=(width>0)?width:getWidth();
height=(height>0)?height:getHeight();
if(width>0 || height>0) {
- setSize0(eglWindowHandle, width, height);
+ setSize0(nativeWindowHandle, width, height);
}
if(x>=0 || y>=0) {
System.err.println("setPosition n/a in KD");
@@ -138,7 +138,7 @@ public class KDWindow extends WindowImpl {
//
protected static native boolean initIDs();
- private native long CreateWindow(long displayHandle, long eglConfig);
+ private native long CreateWindow(int width, int height, boolean opaque, int alphaBits);
private native long RealizeWindow(long eglWindowHandle);
private native int CloseWindow(long eglWindowHandle, long userData);
private native void setVisible0(long eglWindowHandle, boolean visible);
@@ -149,15 +149,7 @@ public class KDWindow extends WindowImpl {
windowUserData=userData;
}
- @Override
- protected void sizeChanged(boolean defer, int newWidth, int newHeight, boolean force) {
- if(isFullscreen()) {
- ((KDScreen)getScreen()).sizeChanged(getWidth(), getHeight());
- }
- super.sizeChanged(defer, newWidth, newHeight, force);
- }
-
- private long eglWindowHandle;
+ private long nativeWindowHandle;
private long windowHandleClose;
private long windowUserData;
}
diff --git a/src/newt/classes/jogamp/newt/driver/intel/gdl/Display.java b/src/newt/classes/jogamp/newt/driver/intel/gdl/DisplayDriver.java
similarity index 87%
rename from src/newt/classes/jogamp/newt/driver/intel/gdl/Display.java
rename to src/newt/classes/jogamp/newt/driver/intel/gdl/DisplayDriver.java
index 20e151e..e370038 100644
--- a/src/newt/classes/jogamp/newt/driver/intel/gdl/Display.java
+++ b/src/newt/classes/jogamp/newt/driver/intel/gdl/DisplayDriver.java
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2012 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -36,16 +37,16 @@ package jogamp.newt.driver.intel.gdl;
import jogamp.newt.*;
import javax.media.nativewindow.*;
-public class Display extends jogamp.newt.DisplayImpl {
+public class DisplayDriver extends jogamp.newt.DisplayImpl {
static int initCounter = 0;
static {
NEWTJNILibLoader.loadNEWT();
- if (!Screen.initIDs()) {
+ if (!ScreenDriver.initIDs()) {
throw new NativeWindowException("Failed to initialize GDL Screen jmethodIDs");
}
- if (!Window.initIDs()) {
+ if (!WindowDriver.initIDs()) {
throw new NativeWindowException("Failed to initialize GDL Window jmethodIDs");
}
}
@@ -55,11 +56,11 @@ public class Display extends jogamp.newt.DisplayImpl {
}
- public Display() {
+ public DisplayDriver() {
}
protected void createNativeImpl() {
- synchronized(Display.class) {
+ synchronized(DisplayDriver.class) {
if(0==initCounter) {
displayHandle = CreateDisplay();
if(0==displayHandle) {
@@ -75,7 +76,7 @@ public class Display extends jogamp.newt.DisplayImpl {
if(0==displayHandle) {
throw new NativeWindowException("displayHandle null; initCnt "+initCounter);
}
- synchronized(Display.class) {
+ synchronized(DisplayDriver.class) {
if(initCounter>0) {
initCounter--;
if(0==initCounter) {
@@ -83,6 +84,7 @@ public class Display extends jogamp.newt.DisplayImpl {
}
}
}
+ aDevice.close();
}
protected void dispatchMessagesNative() {
@@ -91,14 +93,14 @@ public class Display extends jogamp.newt.DisplayImpl {
}
}
- protected void setFocus(Window focus) {
+ protected void setFocus(WindowDriver focus) {
focusedWindow = focus;
}
private long displayHandle = 0;
- private Window focusedWindow = null;
+ private WindowDriver focusedWindow = null;
private native long CreateDisplay();
private native void DestroyDisplay(long displayHandle);
- private native void DispatchMessages(long displayHandle, Window focusedWindow);
+ private native void DispatchMessages(long displayHandle, WindowDriver focusedWindow);
}
diff --git a/src/newt/classes/jogamp/newt/driver/intel/gdl/Screen.java b/src/newt/classes/jogamp/newt/driver/intel/gdl/ScreenDriver.java
similarity index 94%
rename from src/newt/classes/jogamp/newt/driver/intel/gdl/Screen.java
rename to src/newt/classes/jogamp/newt/driver/intel/gdl/ScreenDriver.java
index 66ad1c6..8eed14d 100644
--- a/src/newt/classes/jogamp/newt/driver/intel/gdl/Screen.java
+++ b/src/newt/classes/jogamp/newt/driver/intel/gdl/ScreenDriver.java
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2012 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -38,13 +39,13 @@ import javax.media.nativewindow.DefaultGraphicsScreen;
import javax.media.nativewindow.util.Dimension;
import javax.media.nativewindow.util.Point;
-public class Screen extends jogamp.newt.ScreenImpl {
+public class ScreenDriver extends jogamp.newt.ScreenImpl {
static {
- Display.initSingleton();
+ DisplayDriver.initSingleton();
}
- public Screen() {
+ public ScreenDriver() {
}
protected void createNativeImpl() {
diff --git a/src/newt/classes/jogamp/newt/driver/intel/gdl/Window.java b/src/newt/classes/jogamp/newt/driver/intel/gdl/WindowDriver.java
similarity index 90%
rename from src/newt/classes/jogamp/newt/driver/intel/gdl/Window.java
rename to src/newt/classes/jogamp/newt/driver/intel/gdl/WindowDriver.java
index d5c75ab..98335f1 100644
--- a/src/newt/classes/jogamp/newt/driver/intel/gdl/Window.java
+++ b/src/newt/classes/jogamp/newt/driver/intel/gdl/WindowDriver.java
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2012 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -37,12 +38,12 @@ import javax.media.nativewindow.*;
import javax.media.nativewindow.util.Insets;
import javax.media.nativewindow.util.Point;
-public class Window extends jogamp.newt.WindowImpl {
+public class WindowDriver extends jogamp.newt.WindowImpl {
static {
- Display.initSingleton();
+ DisplayDriver.initSingleton();
}
- public Window() {
+ public WindowDriver() {
}
static long nextWindowHandle = 1;
@@ -61,7 +62,7 @@ public class Window extends jogamp.newt.WindowImpl {
}
setGraphicsConfiguration(cfg);
- synchronized(Window.class) {
+ synchronized(WindowDriver.class) {
setWindowHandle(nextWindowHandle++); // just a marker
surfaceHandle = CreateSurface(aDevice.getHandle(), getScreen().getWidth(), getScreen().getHeight(), getX(), getY(), getWidth(), getHeight());
@@ -73,16 +74,16 @@ public class Window extends jogamp.newt.WindowImpl {
protected void closeNativeImpl() {
if(0!=surfaceHandle) {
- synchronized(Window.class) {
+ synchronized(WindowDriver.class) {
CloseSurface(getDisplayHandle(), surfaceHandle);
}
surfaceHandle = 0;
- ((Display)getScreen().getDisplay()).setFocus(null);
+ ((DisplayDriver)getScreen().getDisplay()).setFocus(null);
}
}
protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) {
- Screen screen = (Screen) getScreen();
+ ScreenDriver screen = (ScreenDriver) getScreen();
if(width>screen.getWidth()) {
width=screen.getWidth();
@@ -103,7 +104,7 @@ public class Window extends jogamp.newt.WindowImpl {
if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) {
if(0 != ( FLAG_IS_VISIBLE & flags)) {
- ((Display)getScreen().getDisplay()).setFocus(this);
+ ((DisplayDriver)getScreen().getDisplay()).setFocus(this);
}
visibleChanged(false, 0 != ( FLAG_IS_VISIBLE & flags));
}
@@ -112,7 +113,7 @@ public class Window extends jogamp.newt.WindowImpl {
}
protected void requestFocusImpl(boolean reparented) {
- ((Display)getScreen().getDisplay()).setFocus(this);
+ ((DisplayDriver)getScreen().getDisplay()).setFocus(this);
}
@Override
diff --git a/src/newt/classes/jogamp/newt/driver/kd/KDDisplay.java b/src/newt/classes/jogamp/newt/driver/kd/DisplayDriver.java
similarity index 94%
rename from src/newt/classes/jogamp/newt/driver/kd/KDDisplay.java
rename to src/newt/classes/jogamp/newt/driver/kd/DisplayDriver.java
index 07b0318..745be5d 100644
--- a/src/newt/classes/jogamp/newt/driver/kd/KDDisplay.java
+++ b/src/newt/classes/jogamp/newt/driver/kd/DisplayDriver.java
@@ -42,13 +42,12 @@ import jogamp.newt.NEWTJNILibLoader;
import jogamp.opengl.egl.EGL;
import jogamp.opengl.egl.EGLDisplayUtil;
-public class KDDisplay extends DisplayImpl {
-
+public class DisplayDriver extends DisplayImpl {
static {
NEWTJNILibLoader.loadNEWT();
- if (!KDWindow.initIDs()) {
- throw new NativeWindowException("Failed to initialize KDWindow jmethodIDs");
+ if (!WindowDriver.initIDs()) {
+ throw new NativeWindowException("Failed to initialize kd.Window jmethodIDs");
}
}
@@ -57,7 +56,7 @@ public class KDDisplay extends DisplayImpl {
}
- public KDDisplay() {
+ public DisplayDriver() {
}
protected void createNativeImpl() {
diff --git a/src/newt/classes/jogamp/newt/driver/kd/KDScreen.java b/src/newt/classes/jogamp/newt/driver/kd/ScreenDriver.java
similarity index 95%
rename from src/newt/classes/jogamp/newt/driver/kd/KDScreen.java
rename to src/newt/classes/jogamp/newt/driver/kd/ScreenDriver.java
index ee34758..656bcf5 100644
--- a/src/newt/classes/jogamp/newt/driver/kd/KDScreen.java
+++ b/src/newt/classes/jogamp/newt/driver/kd/ScreenDriver.java
@@ -40,12 +40,12 @@ import javax.media.nativewindow.util.Point;
import jogamp.newt.ScreenImpl;
-public class KDScreen extends ScreenImpl {
+public class ScreenDriver extends ScreenImpl {
static {
- KDDisplay.initSingleton();
+ DisplayDriver.initSingleton();
}
- public KDScreen() {
+ public ScreenDriver() {
}
protected void createNativeImpl() {
diff --git a/src/newt/classes/jogamp/newt/driver/kd/KDWindow.java b/src/newt/classes/jogamp/newt/driver/kd/WindowDriver.java
similarity index 97%
rename from src/newt/classes/jogamp/newt/driver/kd/KDWindow.java
rename to src/newt/classes/jogamp/newt/driver/kd/WindowDriver.java
index 9f9d694..c733a3e 100644
--- a/src/newt/classes/jogamp/newt/driver/kd/KDWindow.java
+++ b/src/newt/classes/jogamp/newt/driver/kd/WindowDriver.java
@@ -46,14 +46,14 @@ import javax.media.opengl.GLCapabilitiesImmutable;
import jogamp.newt.WindowImpl;
import jogamp.opengl.egl.EGLGraphicsConfiguration;
-public class KDWindow extends WindowImpl {
+public class WindowDriver extends WindowImpl {
private static final String WINDOW_CLASS_NAME = "NewtWindow";
static {
- KDDisplay.initSingleton();
+ DisplayDriver.initSingleton();
}
- public KDWindow() {
+ public WindowDriver() {
}
protected void createNativeImpl() {
@@ -152,7 +152,7 @@ public class KDWindow extends WindowImpl {
@Override
protected void sizeChanged(boolean defer, int newWidth, int newHeight, boolean force) {
if(isFullscreen()) {
- ((KDScreen)getScreen()).sizeChanged(getWidth(), getHeight());
+ ((ScreenDriver)getScreen()).sizeChanged(getWidth(), getHeight());
}
super.sizeChanged(defer, newWidth, newHeight, force);
}
diff --git a/src/newt/classes/jogamp/newt/driver/linux/LinuxMouseTracker.java b/src/newt/classes/jogamp/newt/driver/linux/LinuxMouseTracker.java
new file mode 100644
index 0000000..885649d
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/driver/linux/LinuxMouseTracker.java
@@ -0,0 +1,221 @@
+/**
+ * Copyright 2012 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community OR
+ * CONTRIBUTORS 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.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package jogamp.newt.driver.linux;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+
+import jogamp.newt.WindowImpl;
+
+import com.jogamp.newt.Window;
+import com.jogamp.newt.event.MouseEvent;
+import com.jogamp.newt.event.WindowEvent;
+import com.jogamp.newt.event.WindowListener;
+import com.jogamp.newt.event.WindowUpdateEvent;
+
+/**
+ * Experimental native mouse tracker thread for GNU/Linux
+ * just reading <code>/dev/input/mice</code>
+ * within it's own polling thread.
+ */
+public class LinuxMouseTracker implements WindowListener {
+
+ private static final LinuxMouseTracker lmt;
+
+ static {
+ lmt = new LinuxMouseTracker();
+ final Thread t = new Thread(lmt.mouseDevicePoller, "NEWT-LinuxMouseTracker");
+ t.setDaemon(true);
+ t.start();
+ }
+
+ public static LinuxMouseTracker getSingleton() {
+ return lmt;
+ }
+
+ private volatile boolean stop = false;
+ private int x = 0;
+ private int y = 0;
+ private int buttonDown = 0;
+ private int old_x = 0;
+ private int old_y = 0;
+ private int old_buttonDown = 0;
+ private WindowImpl focusedWindow = null;
+ private MouseDevicePoller mouseDevicePoller = new MouseDevicePoller();
+
+ @Override
+ public void windowResized(WindowEvent e) { }
+
+ @Override
+ public void windowMoved(WindowEvent e) { }
+
+ @Override
+ public void windowDestroyNotify(WindowEvent e) {
+ Object s = e.getSource();
+ if(focusedWindow == s) {
+ focusedWindow = null;
+ }
+ }
+
+ @Override
+ public void windowDestroyed(WindowEvent e) { }
+
+ @Override
+ public void windowGainedFocus(WindowEvent e) {
+ Object s = e.getSource();
+ if(s instanceof WindowImpl) {
+ focusedWindow = (WindowImpl) s;
+ }
+ }
+
+ @Override
+ public void windowLostFocus(WindowEvent e) {
+ Object s = e.getSource();
+ if(focusedWindow == s) {
+ focusedWindow = null;
+ }
+ }
+
+ @Override
+ public void windowRepaint(WindowUpdateEvent e) { }
+
+ class MouseDevicePoller implements Runnable {
+ @Override
+ public void run() {
+ final byte[] b = new byte[3];
+ final File f = new File("/dev/input/mice");
+ f.setReadOnly();
+ InputStream fis;
+ try {
+ fis = new FileInputStream(f);
+ } catch (FileNotFoundException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ return;
+ }
+ int xd=0,yd=0; //x/y movement delta
+ boolean xo=false,yo=false; // x/y overflow (out of range -255 to +255)
+ boolean lb=false,mb=false,rb=false,hs=false,vs=false; //left/middle/right mousebutton
+ while(!stop) {
+ int remaining=3;
+ while(remaining>0) {
+ int read = 0;
+ try {
+ read = fis.read(b, 0, remaining);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ if(read<0) {
+ stop = true; // EOF of mouse !?
+ } else {
+ remaining -= read;
+ }
+ }
+ lb=(b[0]&1)>0;
+ rb=(b[0]&2)>0;
+ mb=(b[0]&4)>0;
+ hs=(b[0]&16)>0;
+ vs=(b[0]&32)>0;
+ xo=(b[0]&64)>0;
+ yo=(b[0]&128)>0;
+ xd=b[1];
+ yd=b[2];
+
+ x+=xd;
+ y+=yd;
+
+ if(x<0) {
+ x=0;
+ }
+ if(y<0) {
+ y=0;
+ }
+
+ if(lb) {
+ buttonDown = MouseEvent.BUTTON1;
+ }
+ if(mb) {
+ buttonDown = MouseEvent.BUTTON2;
+ }
+ if(rb) {
+ buttonDown = MouseEvent.BUTTON3;
+ }
+
+ if(null != focusedWindow) {
+ if( x >= focusedWindow.getScreen().getWidth() ) {
+ x = focusedWindow.getScreen().getWidth() - 1;
+ }
+ if( y >= focusedWindow.getScreen().getHeight() ) {
+ y = focusedWindow.getScreen().getHeight() - 1;
+ }
+ int wx = x - focusedWindow.getX(), wy = y - focusedWindow.getY();
+
+ if(old_x != x || old_y != y) {
+ // mouse moved
+ focusedWindow.sendMouseEvent(MouseEvent.EVENT_MOUSE_MOVED, 0, wx, wy, 0, 0 );
+ }
+
+ if(old_buttonDown != buttonDown) {
+ // press/release
+ if( 0 != buttonDown ) {
+ focusedWindow.sendMouseEvent(
+ MouseEvent.EVENT_MOUSE_PRESSED,
+ 0, wx, wy, buttonDown, 0 );
+ } else {
+ focusedWindow.sendMouseEvent(
+ MouseEvent.EVENT_MOUSE_RELEASED,
+ 0, wx, wy, old_buttonDown, 0 );
+ }
+ }
+ } else {
+ if(Window.DEBUG_MOUSE_EVENT) {
+ System.out.println(x+"/"+y+", hs="+hs+",vs="+vs+",lb="+lb+",rb="+rb+",mb="+mb+",xo="+xo+",yo="+yo+"xd="+xd+",yd="+yd);
+ }
+ }
+
+ old_x = x;
+ old_y = y;
+ old_buttonDown = buttonDown;
+
+ }
+ if(null != fis) {
+ try {
+ fis.close();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+}
diff --git a/src/newt/classes/jogamp/newt/driver/macosx/MacDisplay.java b/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java
similarity index 92%
rename from src/newt/classes/jogamp/newt/driver/macosx/MacDisplay.java
rename to src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java
index 18f8d95..b49c6b6 100644
--- a/src/newt/classes/jogamp/newt/driver/macosx/MacDisplay.java
+++ b/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2012 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -41,14 +42,14 @@ import com.jogamp.nativewindow.macosx.MacOSXGraphicsDevice;
import jogamp.newt.DisplayImpl;
import jogamp.newt.NEWTJNILibLoader;
-public class MacDisplay extends DisplayImpl {
+public class DisplayDriver extends DisplayImpl {
static {
NEWTJNILibLoader.loadNEWT();
if(!initNSApplication0()) {
throw new NativeWindowException("Failed to initialize native Application hook");
}
- if(!MacWindow.initIDs0()) {
+ if(!WindowDriver.initIDs0()) {
throw new NativeWindowException("Failed to initialize jmethodIDs");
}
if(DEBUG) {
@@ -60,7 +61,7 @@ public class MacDisplay extends DisplayImpl {
// just exist to ensure static init has been run
}
- public MacDisplay() {
+ public DisplayDriver() {
}
protected void dispatchMessagesNative() {
@@ -71,7 +72,9 @@ public class MacDisplay extends DisplayImpl {
aDevice = new MacOSXGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT);
}
- protected void closeNativeImpl() { }
+ protected void closeNativeImpl() {
+ aDevice.close();
+ }
public static void runNSApplication() {
runNSApplication0();
diff --git a/src/newt/classes/jogamp/newt/driver/macosx/MacKeyUtil.java b/src/newt/classes/jogamp/newt/driver/macosx/MacKeyUtil.java
index 46625f7..5966bd3 100644
--- a/src/newt/classes/jogamp/newt/driver/macosx/MacKeyUtil.java
+++ b/src/newt/classes/jogamp/newt/driver/macosx/MacKeyUtil.java
@@ -1,3 +1,30 @@
+/**
+ * Copyright 2011 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community OR
+ * CONTRIBUTORS 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.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
package jogamp.newt.driver.macosx;
import com.jogamp.newt.event.KeyEvent;
@@ -135,13 +162,13 @@ public class MacKeyUtil {
case kVK_Space: return KeyEvent.VK_SPACE;
case kVK_Delete: return KeyEvent.VK_BACK_SPACE;
case kVK_Escape: return KeyEvent.VK_ESCAPE;
- case kVK_Command: return KeyEvent.VK_ALT;
+ case kVK_Command: return KeyEvent.VK_WINDOWS;
case kVK_Shift: return KeyEvent.VK_SHIFT;
case kVK_CapsLock: return KeyEvent.VK_CAPS_LOCK;
- case kVK_Option: return KeyEvent.VK_WINDOWS;
+ case kVK_Option: return KeyEvent.VK_ALT;
case kVK_Control: return KeyEvent.VK_CONTROL;
case kVK_RightShift: return KeyEvent.VK_SHIFT;
- case kVK_RightOption: return KeyEvent.VK_WINDOWS;
+ case kVK_RightOption: return KeyEvent.VK_ALT;
case kVK_RightControl: return KeyEvent.VK_CONTROL;
// case kVK_Function: return KeyEvent.VK_F;
case kVK_F17: return KeyEvent.VK_F17;
@@ -179,78 +206,73 @@ public class MacKeyUtil {
case kVK_UpArrow: return KeyEvent.VK_UP;
}
- if (keyChar == '\r') {
- // Turn these into \n
- return KeyEvent.VK_ENTER;
- }
-
- if (keyChar >= NSUpArrowFunctionKey && keyChar <= NSModeSwitchFunctionKey) {
- switch (keyChar) {
- case NSUpArrowFunctionKey: return KeyEvent.VK_UP;
- case NSDownArrowFunctionKey: return KeyEvent.VK_DOWN;
- case NSLeftArrowFunctionKey: return KeyEvent.VK_LEFT;
- case NSRightArrowFunctionKey: return KeyEvent.VK_RIGHT;
- case NSF1FunctionKey: return KeyEvent.VK_F1;
- case NSF2FunctionKey: return KeyEvent.VK_F2;
- case NSF3FunctionKey: return KeyEvent.VK_F3;
- case NSF4FunctionKey: return KeyEvent.VK_F4;
- case NSF5FunctionKey: return KeyEvent.VK_F5;
- case NSF6FunctionKey: return KeyEvent.VK_F6;
- case NSF7FunctionKey: return KeyEvent.VK_F7;
- case NSF8FunctionKey: return KeyEvent.VK_F8;
- case NSF9FunctionKey: return KeyEvent.VK_F9;
- case NSF10FunctionKey: return KeyEvent.VK_F10;
- case NSF11FunctionKey: return KeyEvent.VK_F11;
- case NSF12FunctionKey: return KeyEvent.VK_F12;
- case NSF13FunctionKey: return KeyEvent.VK_F13;
- case NSF14FunctionKey: return KeyEvent.VK_F14;
- case NSF15FunctionKey: return KeyEvent.VK_F15;
- case NSF16FunctionKey: return KeyEvent.VK_F16;
- case NSF17FunctionKey: return KeyEvent.VK_F17;
- case NSF18FunctionKey: return KeyEvent.VK_F18;
- case NSF19FunctionKey: return KeyEvent.VK_F19;
- case NSF20FunctionKey: return KeyEvent.VK_F20;
- case NSF21FunctionKey: return KeyEvent.VK_F21;
- case NSF22FunctionKey: return KeyEvent.VK_F22;
- case NSF23FunctionKey: return KeyEvent.VK_F23;
- case NSF24FunctionKey: return KeyEvent.VK_F24;
- case NSInsertFunctionKey: return KeyEvent.VK_INSERT;
- case NSDeleteFunctionKey: return KeyEvent.VK_DELETE;
- case NSHomeFunctionKey: return KeyEvent.VK_HOME;
- case NSBeginFunctionKey: return KeyEvent.VK_BEGIN;
- case NSEndFunctionKey: return KeyEvent.VK_END;
- case NSPageUpFunctionKey: return KeyEvent.VK_PAGE_UP;
- case NSPageDownFunctionKey: return KeyEvent.VK_PAGE_DOWN;
- case NSPrintScreenFunctionKey: return KeyEvent.VK_PRINTSCREEN;
- case NSScrollLockFunctionKey: return KeyEvent.VK_SCROLL_LOCK;
- case NSPauseFunctionKey: return KeyEvent.VK_PAUSE;
- // Not handled:
- // NSSysReqFunctionKey
- // NSBreakFunctionKey
- // NSResetFunctionKey
- case NSStopFunctionKey: return KeyEvent.VK_STOP;
- // Not handled:
- // NSMenuFunctionKey
- // NSUserFunctionKey
- // NSSystemFunctionKey
- // NSPrintFunctionKey
- // NSClearLineFunctionKey
- // NSClearDisplayFunctionKey
- // NSInsertLineFunctionKey
- // NSDeleteLineFunctionKey
- // NSInsertCharFunctionKey
- // NSDeleteCharFunctionKey
- // NSPrevFunctionKey
- // NSNextFunctionKey
- // NSSelectFunctionKey
- // NSExecuteFunctionKey
- // NSUndoFunctionKey
- // NSRedoFunctionKey
- // NSFindFunctionKey
- // NSHelpFunctionKey
- // NSModeSwitchFunctionKey
- default: break;
- }
+ switch (keyChar) {
+ case NSUpArrowFunctionKey: return KeyEvent.VK_UP;
+ case NSDownArrowFunctionKey: return KeyEvent.VK_DOWN;
+ case NSLeftArrowFunctionKey: return KeyEvent.VK_LEFT;
+ case NSRightArrowFunctionKey: return KeyEvent.VK_RIGHT;
+ case NSF1FunctionKey: return KeyEvent.VK_F1;
+ case NSF2FunctionKey: return KeyEvent.VK_F2;
+ case NSF3FunctionKey: return KeyEvent.VK_F3;
+ case NSF4FunctionKey: return KeyEvent.VK_F4;
+ case NSF5FunctionKey: return KeyEvent.VK_F5;
+ case NSF6FunctionKey: return KeyEvent.VK_F6;
+ case NSF7FunctionKey: return KeyEvent.VK_F7;
+ case NSF8FunctionKey: return KeyEvent.VK_F8;
+ case NSF9FunctionKey: return KeyEvent.VK_F9;
+ case NSF10FunctionKey: return KeyEvent.VK_F10;
+ case NSF11FunctionKey: return KeyEvent.VK_F11;
+ case NSF12FunctionKey: return KeyEvent.VK_F12;
+ case NSF13FunctionKey: return KeyEvent.VK_F13;
+ case NSF14FunctionKey: return KeyEvent.VK_F14;
+ case NSF15FunctionKey: return KeyEvent.VK_F15;
+ case NSF16FunctionKey: return KeyEvent.VK_F16;
+ case NSF17FunctionKey: return KeyEvent.VK_F17;
+ case NSF18FunctionKey: return KeyEvent.VK_F18;
+ case NSF19FunctionKey: return KeyEvent.VK_F19;
+ case NSF20FunctionKey: return KeyEvent.VK_F20;
+ case NSF21FunctionKey: return KeyEvent.VK_F21;
+ case NSF22FunctionKey: return KeyEvent.VK_F22;
+ case NSF23FunctionKey: return KeyEvent.VK_F23;
+ case NSF24FunctionKey: return KeyEvent.VK_F24;
+ case NSInsertFunctionKey: return KeyEvent.VK_INSERT;
+ case NSDeleteFunctionKey: return KeyEvent.VK_DELETE;
+ case NSHomeFunctionKey: return KeyEvent.VK_HOME;
+ case NSBeginFunctionKey: return KeyEvent.VK_BEGIN;
+ case NSEndFunctionKey: return KeyEvent.VK_END;
+ case NSPageUpFunctionKey: return KeyEvent.VK_PAGE_UP;
+ case NSPageDownFunctionKey: return KeyEvent.VK_PAGE_DOWN;
+ case NSPrintScreenFunctionKey: return KeyEvent.VK_PRINTSCREEN;
+ case NSScrollLockFunctionKey: return KeyEvent.VK_SCROLL_LOCK;
+ case NSPauseFunctionKey: return KeyEvent.VK_PAUSE;
+ // Not handled:
+ // NSSysReqFunctionKey
+ // NSBreakFunctionKey
+ // NSResetFunctionKey
+ case NSStopFunctionKey: return KeyEvent.VK_STOP;
+ // Not handled:
+ // NSMenuFunctionKey
+ // NSUserFunctionKey
+ // NSSystemFunctionKey
+ // NSPrintFunctionKey
+ // NSClearLineFunctionKey
+ // NSClearDisplayFunctionKey
+ // NSInsertLineFunctionKey
+ // NSDeleteLineFunctionKey
+ // NSInsertCharFunctionKey
+ // NSDeleteCharFunctionKey
+ // NSPrevFunctionKey
+ // NSNextFunctionKey
+ // NSSelectFunctionKey
+ // NSExecuteFunctionKey
+ // NSUndoFunctionKey
+ // NSRedoFunctionKey
+ // NSFindFunctionKey
+ // NSHelpFunctionKey
+ // NSModeSwitchFunctionKey
+ case 0x60: return KeyEvent.VK_BACK_QUOTE; // `
+ case 0x27: return KeyEvent.VK_QUOTE; // '
+ case '\r': return KeyEvent.VK_ENTER;
}
if ('a' <= keyChar && keyChar <= 'z') {
diff --git a/src/newt/classes/jogamp/newt/driver/macosx/MacScreen.java b/src/newt/classes/jogamp/newt/driver/macosx/ScreenDriver.java
similarity index 97%
rename from src/newt/classes/jogamp/newt/driver/macosx/MacScreen.java
rename to src/newt/classes/jogamp/newt/driver/macosx/ScreenDriver.java
index b9c725f..24e60ba 100644
--- a/src/newt/classes/jogamp/newt/driver/macosx/MacScreen.java
+++ b/src/newt/classes/jogamp/newt/driver/macosx/ScreenDriver.java
@@ -47,18 +47,18 @@ import com.jogamp.common.util.IntObjectHashMap;
import com.jogamp.newt.ScreenMode;
import com.jogamp.newt.util.ScreenModeUtil;
-public class MacScreen extends ScreenImpl {
+public class ScreenDriver extends ScreenImpl {
// caching native CGDisplayScreenSize() results, since it's ridiculous slow (~6 ms each call)
private static IntObjectHashMap/*<int, DimensionImmutable>*/ scrnIdx2Dimension;
static {
- MacDisplay.initSingleton();
+ DisplayDriver.initSingleton();
scrnIdx2Dimension = new IntObjectHashMap();
scrnIdx2Dimension.setKeyNotFoundValue(null);
}
- public MacScreen() {
+ public ScreenDriver() {
}
protected void createNativeImpl() {
diff --git a/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java
similarity index 79%
rename from src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java
rename to src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java
index 27d7a16..5755bdf 100644
--- a/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java
+++ b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java
@@ -45,19 +45,21 @@ import javax.media.nativewindow.util.InsetsImmutable;
import javax.media.nativewindow.util.Point;
import javax.media.nativewindow.util.PointImmutable;
+import jogamp.nativewindow.macosx.OSXUtil;
import jogamp.newt.WindowImpl;
import jogamp.newt.driver.DriverClearFocus;
import jogamp.newt.driver.DriverUpdatePosition;
+import com.jogamp.newt.event.InputEvent;
import com.jogamp.newt.event.KeyEvent;
-public class MacWindow extends WindowImpl implements MutableSurface, DriverClearFocus, DriverUpdatePosition {
+public class WindowDriver extends WindowImpl implements MutableSurface, DriverClearFocus, DriverUpdatePosition {
static {
- MacDisplay.initSingleton();
+ DisplayDriver.initSingleton();
}
- public MacWindow() {
+ public WindowDriver() {
}
@Override
@@ -117,6 +119,7 @@ public class MacWindow extends WindowImpl implements MutableSurface, DriverClear
return 0 != sscSurfaceHandle ? sscSurfaceHandle : surfaceHandle;
}
+ @Override
public void setSurfaceHandle(long surfaceHandle) {
if(DEBUG_IMPLEMENTATION) {
System.err.println("MacWindow.setSurfaceHandle(): 0x"+Long.toHexString(surfaceHandle));
@@ -147,7 +150,7 @@ public class MacWindow extends WindowImpl implements MutableSurface, DriverClear
public final void clearFocus() {
if(DEBUG_IMPLEMENTATION) {
- System.err.println("MacWindow: clearFocus() - requestFocusParent, isOffscreenInstance "+isOffscreenInstance);
+ System.err.println("MacWindow: clearFocus(), isOffscreenInstance "+isOffscreenInstance);
}
if(!isOffscreenInstance) {
resignFocus0(getWindowHandle());
@@ -170,13 +173,22 @@ public class MacWindow extends WindowImpl implements MutableSurface, DriverClear
protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) {
- final Point pS = getTopLevelLocationOnScreen(x, y);
- isOffscreenInstance = 0 != sscSurfaceHandle || isOffscreenInstance(this, this.getParent());
+ final boolean _isOffscreenInstance = isOffscreenInstance(this, this.getParent());
+ isOffscreenInstance = 0 != sscSurfaceHandle || _isOffscreenInstance;
+ final PointImmutable pS = isOffscreenInstance ? new Point(0, 0) : getTopLevelLocationOnScreen(x, y);
if(DEBUG_IMPLEMENTATION) {
+ final AbstractGraphicsConfiguration cWinCfg = this.getGraphicsConfiguration();
+ final NativeWindow pWin = getParent();
+ final AbstractGraphicsConfiguration pWinCfg = null != pWin ? pWin.getGraphicsConfiguration() : null;
System.err.println("MacWindow reconfig: "+x+"/"+y+" -> "+pS+" - "+width+"x"+height+
- ", offscreenInstance "+isOffscreenInstance+
- ", "+getReconfigureFlagsAsString(null, flags));
+ ",\n\t parent type "+(null != pWin ? pWin.getClass().getName() : null)+
+ ",\n\t this-chosenCaps "+(null != cWinCfg ? cWinCfg.getChosenCapabilities() : null)+
+ ",\n\t parent-chosenCaps "+(null != pWinCfg ? pWinCfg.getChosenCapabilities() : null)+
+ ", isOffscreenInstance(sscSurfaceHandle "+toHexString(sscSurfaceHandle)+
+ ", ioi: "+_isOffscreenInstance+
+ ") -> "+isOffscreenInstance+
+ "\n\t, "+getReconfigureFlagsAsString(null, flags));
}
if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) && 0 == ( FLAG_IS_VISIBLE & flags) ) {
@@ -190,7 +202,11 @@ public class MacWindow extends WindowImpl implements MutableSurface, DriverClear
0 != ( FLAG_CHANGE_DECORATION & flags) ||
0 != ( FLAG_CHANGE_PARENTING & flags) ||
0 != ( FLAG_CHANGE_FULLSCREEN & flags) ) {
- createWindow(isOffscreenInstance, 0 != getWindowHandle(), pS, width, height, 0 != ( FLAG_IS_FULLSCREEN & flags));
+ if(isOffscreenInstance) {
+ createWindow(true, 0 != getWindowHandle(), pS, 64, 64, false);
+ } else {
+ createWindow(false, 0 != getWindowHandle(), pS, width, height, 0 != ( FLAG_IS_FULLSCREEN & flags));
+ }
if(isVisible()) { flags |= FLAG_CHANGE_VISIBILITY; }
}
if(x>=0 && y>=0) {
@@ -221,16 +237,21 @@ public class MacWindow extends WindowImpl implements MutableSurface, DriverClear
}
protected Point getLocationOnScreenImpl(int x, int y) {
- Point p = new Point(x, y);
+ final NativeWindow parent = getParent();
+ final boolean useParent = null != parent && 0 != parent.getWindowHandle() ;
+
+ if( !useParent && !isOffscreenInstance && 0 != surfaceHandle) {
+ return OSXUtil.GetLocationOnScreen(surfaceHandle, true, x, y);
+ }
+
+ final Point p = new Point(x, y);
// min val is 0
p.setX(Math.max(p.getX(), 0));
p.setY(Math.max(p.getY(), 0));
-
- final NativeWindow parent = getParent();
- if( null != parent && 0 != parent.getWindowHandle() ) {
+ if( useParent ) {
p.translate(parent.getLocationOnScreen(null));
}
- return p;
+ return p;
}
private Point getTopLevelLocationOnScreen(int x, int y) {
@@ -291,55 +312,56 @@ public class MacWindow extends WindowImpl implements MutableSurface, DriverClear
} // else may need offscreen solution ? FIXME
}
- @Override
- public void sendKeyEvent(int eventType, int modifiers, int keyCode, char keyChar) {
- // 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
- final int keyCode2 = MacKeyUtil.validateKeyCode(keyCode, keyChar);
- final boolean valid = validateKeyEvent(eventType, modifiers, keyCode);
- if(DEBUG_IMPLEMENTATION) System.err.println("MacWindow.sendKeyEvent "+Thread.currentThread().getName()+" char: 0x"+Integer.toHexString(keyChar)+", code 0x"+Integer.toHexString(keyCode)+" -> 0x"+Integer.toHexString(keyCode2)+", valid "+valid);
- if(valid) {
- // only deliver keyChar on key Typed events, harmonizing platform behavior
- keyChar = KeyEvent.EVENT_KEY_TYPED == eventType ? keyChar : (char)-1;
- super.sendKeyEvent(eventType, modifiers, keyCode2, keyChar);
+ private final void emitKeyEvent(boolean send, boolean wait, int eventType, int modifiers, int keyCode, char keyChar) {
+ if( send ) {
+ super.sendKeyEvent(eventType, modifiers, keyCode, keyChar);
+ } else {
+ super.enqueueKeyEvent(wait, eventType, modifiers, keyCode, keyChar);
}
}
-
- @Override
- public void enqueueKeyEvent(boolean wait, int eventType, int modifiers, int keyCode, char keyChar) {
+
+ private final void handleKeyEvent(boolean send, boolean wait, int eventType, int modifiers, int _keyCode, char keyChar) {
// 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
- final int keyCode2 = MacKeyUtil.validateKeyCode(keyCode, keyChar);
- final boolean valid = validateKeyEvent(eventType, modifiers, keyCode);
- if(DEBUG_IMPLEMENTATION) System.err.println("MacWindow.enqueueKeyEvent "+Thread.currentThread().getName()+" char: 0x"+Integer.toHexString(keyChar)+", code 0x"+Integer.toHexString(keyCode)+" -> 0x"+Integer.toHexString(keyCode2)+", valid "+valid);
- if(valid) {
- // only deliver keyChar on key Typed events, harmonizing platform behavior
- keyChar = KeyEvent.EVENT_KEY_TYPED == eventType ? keyChar : (char)-1;
- super.enqueueKeyEvent(wait, eventType, modifiers, keyCode2, keyChar);
- }
- }
-
- private int keyDownModifiers = 0;
- private int keyDownCode = 0;
-
- private boolean validateKeyEvent(int eventType, int modifiers, int keyCode) {
+ final int keyCode = MacKeyUtil.validateKeyCode(_keyCode, keyChar);
+ // final boolean isModifierKeyCode = KeyEvent.isModifierKey(keyCode);
+ // System.err.println("*** handleKeyEvent: event "+KeyEvent.getEventTypeString(eventType)+", key 0x"+Integer.toHexString(_keyCode)+" -> 0x"+Integer.toHexString(keyCode)+", mods "+toHexString(modifiers)+", was: pressed "+isKeyPressed(keyCode)+", repeat "+isKeyInAutoRepeat(keyCode)+", isModifierKeyCode "+isModifierKeyCode);
+
+ // 1:1 Order: OSX and NEWT delivery order is PRESSED, RELEASED and TYPED
+ // Auto-Repeat: OSX delivers only PRESSED, inject auto-repeat RELEASE and TYPED keys _before_ PRESSED
switch(eventType) {
- case KeyEvent.EVENT_KEY_PRESSED:
- keyDownModifiers = modifiers;
- keyDownCode = keyCode;
- return true;
case KeyEvent.EVENT_KEY_RELEASED:
- return keyDownModifiers == modifiers && keyDownCode == keyCode;
+ if( isKeyCodeTracked(keyCode) ) {
+ keyRepeatState.put(keyCode, false); // prev == true -> AR out
+ keyPressedState.put(keyCode, false);
+ }
+ break;
+ case KeyEvent.EVENT_KEY_PRESSED:
+ if( isKeyCodeTracked(keyCode) ) {
+ if( keyPressedState.put(keyCode, true) ) {
+ // key was already pressed
+ keyRepeatState.put(keyCode, true); // prev == false -> AR in
+ modifiers |= InputEvent.AUTOREPEAT_MASK;
+ emitKeyEvent(send, wait, KeyEvent.EVENT_KEY_RELEASED, modifiers, keyCode, keyChar); // RELEASED
+ emitKeyEvent(send, wait, KeyEvent.EVENT_KEY_TYPED, modifiers, keyCode, keyChar); // TYPED
+ }
+ }
+ break;
case KeyEvent.EVENT_KEY_TYPED:
- final boolean matchKeyDown = keyDownModifiers == modifiers && keyDownCode == keyCode;
- keyDownModifiers = 0;
- keyDownCode = 0;
- return matchKeyDown;
- default:
- throw new NativeWindowException("Unexpected key event type " + eventType);
+ break;
}
+ emitKeyEvent(send, wait, eventType, modifiers, keyCode, keyChar);
+ }
+
+ @Override
+ public void sendKeyEvent(int eventType, int modifiers, int keyCode, char keyChar) {
+ handleKeyEvent(true, false, eventType, modifiers, keyCode, keyChar);
}
+ @Override
+ public void enqueueKeyEvent(boolean wait, int eventType, int modifiers, int keyCode, char keyChar) {
+ handleKeyEvent(false, wait, eventType, modifiers, keyCode, keyChar);
+ }
//----------------------------------------------------------------------
// Internals only
diff --git a/src/newt/classes/jogamp/newt/driver/windows/WindowsDisplay.java b/src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java
similarity index 94%
rename from src/newt/classes/jogamp/newt/driver/windows/WindowsDisplay.java
rename to src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java
index 225b115..615f9e6 100644
--- a/src/newt/classes/jogamp/newt/driver/windows/WindowsDisplay.java
+++ b/src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java
@@ -43,7 +43,7 @@ import javax.media.nativewindow.NativeWindowException;
import com.jogamp.nativewindow.windows.WindowsGraphicsDevice;
-public class WindowsDisplay extends DisplayImpl {
+public class DisplayDriver extends DisplayImpl {
private static final String newtClassBaseName = "_newt_clazz" ;
private static RegisteredClassFactory sharedClassFactory;
@@ -51,10 +51,10 @@ public class WindowsDisplay extends DisplayImpl {
static {
NEWTJNILibLoader.loadNEWT();
- if (!WindowsWindow.initIDs0()) {
+ if (!WindowDriver.initIDs0()) {
throw new NativeWindowException("Failed to initialize WindowsWindow jmethodIDs");
}
- sharedClassFactory = new RegisteredClassFactory(newtClassBaseName, WindowsWindow.getNewtWndProc0());
+ sharedClassFactory = new RegisteredClassFactory(newtClassBaseName, WindowDriver.getNewtWndProc0());
}
public static void initSingleton() {
@@ -63,7 +63,7 @@ public class WindowsDisplay extends DisplayImpl {
private RegisteredClass sharedClass;
- public WindowsDisplay() {
+ public DisplayDriver() {
}
protected void createNativeImpl() {
@@ -73,6 +73,7 @@ public class WindowsDisplay extends DisplayImpl {
protected void closeNativeImpl() {
sharedClassFactory.releaseSharedClass();
+ aDevice.close();
}
protected void dispatchMessagesNative() {
diff --git a/src/newt/classes/jogamp/newt/driver/windows/WindowsScreen.java b/src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java
similarity index 97%
rename from src/newt/classes/jogamp/newt/driver/windows/WindowsScreen.java
rename to src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java
index f8bce9d..948b294 100644
--- a/src/newt/classes/jogamp/newt/driver/windows/WindowsScreen.java
+++ b/src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java
@@ -42,13 +42,13 @@ import jogamp.newt.ScreenImpl;
import com.jogamp.newt.ScreenMode;
import com.jogamp.newt.util.ScreenModeUtil;
-public class WindowsScreen extends ScreenImpl {
+public class ScreenDriver extends ScreenImpl {
static {
- WindowsDisplay.initSingleton();
+ DisplayDriver.initSingleton();
}
- public WindowsScreen() {
+ public ScreenDriver() {
}
protected void createNativeImpl() {
diff --git a/src/newt/classes/jogamp/newt/driver/windows/WindowsWindow.java b/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java
similarity index 74%
rename from src/newt/classes/jogamp/newt/driver/windows/WindowsWindow.java
rename to src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java
index 6a8c81f..6aac861 100644
--- a/src/newt/classes/jogamp/newt/driver/windows/WindowsWindow.java
+++ b/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java
@@ -46,11 +46,13 @@ import javax.media.nativewindow.util.Insets;
import javax.media.nativewindow.util.InsetsImmutable;
import javax.media.nativewindow.util.Point;
+import com.jogamp.common.util.IntIntHashMap;
+import com.jogamp.newt.event.InputEvent;
import com.jogamp.newt.event.KeyEvent;
import com.jogamp.newt.event.MouseAdapter;
import com.jogamp.newt.event.MouseEvent;
-public class WindowsWindow extends WindowImpl {
+public class WindowDriver extends WindowImpl {
private long hmon;
private long hdc;
@@ -58,10 +60,10 @@ public class WindowsWindow extends WindowImpl {
private long windowHandleClose;
static {
- WindowsDisplay.initSingleton();
+ DisplayDriver.initSingleton();
}
- public WindowsWindow() {
+ public WindowDriver() {
}
@Override
@@ -118,8 +120,8 @@ public class WindowsWindow extends WindowImpl {
}
protected void createNativeImpl() {
- final WindowsScreen screen = (WindowsScreen) getScreen();
- final WindowsDisplay display = (WindowsDisplay) screen.getDisplay();
+ final ScreenDriver screen = (ScreenDriver) getScreen();
+ final DisplayDriver display = (DisplayDriver) screen.getDisplay();
final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(display.getGraphicsDevice(), capsRequested).chooseGraphicsConfiguration(
capsRequested, capsRequested, capabilitiesChooser, screen.getGraphicsScreen(), VisualIDHolder.VID_UNDEFINED);
if (null == cfg) {
@@ -146,7 +148,7 @@ public class WindowsWindow extends WindowImpl {
class MouseTracker extends MouseAdapter {
public void mouseEntered(MouseEvent e) {
- WindowsWindow.trackPointerLeave0(WindowsWindow.this.getWindowHandle());
+ WindowDriver.trackPointerLeave0(WindowDriver.this.getWindowHandle());
}
}
@@ -163,7 +165,6 @@ public class WindowsWindow extends WindowImpl {
}
}
try {
- GDI.SetParent(windowHandleClose, 0); // detach first, experience hang w/ SWT parent
GDI.DestroyWindow(windowHandleClose);
} catch (Throwable t) {
if(DEBUG_IMPLEMENTATION) {
@@ -259,34 +260,73 @@ public class WindowsWindow extends WindowImpl {
// nop - using event driven insetsChange(..)
}
- private final int validateKeyCode(int eventType, int keyCode) {
+ private final void emitKeyEvent(boolean send, boolean wait, int eventType, int modifiers, int keyCode, char keyChar) {
+ if( send ) {
+ super.sendKeyEvent(eventType, modifiers, keyCode, keyChar);
+ } else {
+ super.enqueueKeyEvent(wait, eventType, modifiers, keyCode, keyChar);
+ }
+ }
+
+ /** FIXME: We have to store the keyChar for typed events, since keyChar from pressed/released may be wrong (Uppercase: SHIFT-1, etc ..). */
+ private IntIntHashMap typedKeyCode2KeyChar = new IntIntHashMap(KeyEvent.VK_CONTEXT_MENU+1);
+
+ private final void handleKeyEvent(boolean send, boolean wait, int eventType, int modifiers, int keyCode, char keyChar) {
+ final boolean isModifierKeyCode = KeyEvent.isModifierKey(keyCode);
+ // System.err.println("*** handleKeyEvent: event "+KeyEvent.getEventTypeString(eventType)+", keyCode "+toHexString(keyCode)+", keyChar <"+keyChar+">, mods "+toHexString(modifiers)+", was: pressed "+isKeyPressed(keyCode)+", repeat "+isKeyInAutoRepeat(keyCode)+", isModifierKeyCode "+isModifierKeyCode);
+
+ // Reorder: WINDOWS delivery order is PRESSED, TYPED and RELEASED -> NEWT order: PRESSED, RELEASED and TYPED
+ // Auto-Repeat: WINDOWS delivers only PRESSED and TYPED.
switch(eventType) {
+ case KeyEvent.EVENT_KEY_RELEASED:
+ if( isKeyCodeTracked(keyCode) ) {
+ if( keyRepeatState.put(keyCode, false) && !isModifierKeyCode ) {
+ // AR out - send out missing PRESSED
+ emitKeyEvent(send, wait, KeyEvent.EVENT_KEY_PRESSED, modifiers | InputEvent.AUTOREPEAT_MASK, keyCode, keyChar);
+ }
+ keyPressedState.put(keyCode, false);
+ }
+ final int keyCharTyped = typedKeyCode2KeyChar.put(keyCode, 0);
+ if( 0 != keyCharTyped ) {
+ keyChar = (char)keyCharTyped;
+ }
+ emitKeyEvent(send, wait, eventType, modifiers, keyCode, keyChar);
+ emitKeyEvent(send, wait, KeyEvent.EVENT_KEY_TYPED, modifiers, keyCode, keyChar);
+ break;
case KeyEvent.EVENT_KEY_PRESSED:
- lastPressedKeyCode = keyCode;
+ if( isKeyCodeTracked(keyCode) ) {
+ if( keyPressedState.put(keyCode, true) ) {
+ // key was already pressed
+ if( keyRepeatState.put(keyCode, true) && !isModifierKeyCode ) {
+ emitKeyEvent(send, wait, eventType, modifiers | InputEvent.AUTOREPEAT_MASK, keyCode, keyChar);
+ } // else AR in - skip already send PRESSED ; or ALT
+ } else {
+ emitKeyEvent(send, wait, eventType, modifiers, keyCode, keyChar);
+ }
+ } else {
+ emitKeyEvent(send, wait, eventType, modifiers, keyCode, keyChar);
+ }
break;
case KeyEvent.EVENT_KEY_TYPED:
- if(-1==keyCode) {
- keyCode = lastPressedKeyCode;
+ if( 1 == isKeyInAutoRepeat(keyCode) ) {
+ modifiers |= InputEvent.AUTOREPEAT_MASK;
+ emitKeyEvent(send, wait, KeyEvent.EVENT_KEY_RELEASED, modifiers, keyCode, keyChar);
+ emitKeyEvent(send, wait, eventType, modifiers, keyCode, keyChar);
+ } else if( 0 != keyCode ) {
+ typedKeyCode2KeyChar.put(keyCode, keyChar);
}
- lastPressedKeyCode = -1;
break;
}
- return keyCode;
}
- private int lastPressedKeyCode = 0;
@Override
public void sendKeyEvent(int eventType, int modifiers, int keyCode, char keyChar) {
- // Note that we have to regenerate the keyCode for EVENT_KEY_TYPED on this platform
- keyCode = validateKeyCode(eventType, keyCode);
- super.sendKeyEvent(eventType, modifiers, keyCode, keyChar);
+ handleKeyEvent(true, false, eventType, modifiers, keyCode, keyChar);
}
@Override
public void enqueueKeyEvent(boolean wait, int eventType, int modifiers, int keyCode, char keyChar) {
- // Note that we have to regenerate the keyCode for EVENT_KEY_TYPED on this platform
- keyCode = validateKeyCode(eventType, keyCode);
- super.enqueueKeyEvent(wait, eventType, modifiers, keyCode, keyChar);
+ handleKeyEvent(false, wait, eventType, modifiers, keyCode, keyChar);
}
//----------------------------------------------------------------------
diff --git a/src/newt/classes/jogamp/newt/driver/x11/X11Display.java b/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java
similarity index 61%
rename from src/newt/classes/jogamp/newt/driver/x11/X11Display.java
rename to src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java
index 8243fcf..f3a548a 100644
--- a/src/newt/classes/jogamp/newt/driver/x11/X11Display.java
+++ b/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java
@@ -36,7 +36,6 @@ package jogamp.newt.driver.x11;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeWindowException;
-import javax.media.nativewindow.NativeWindowFactory;
import com.jogamp.nativewindow.x11.X11GraphicsDevice;
@@ -44,7 +43,7 @@ import jogamp.nativewindow.x11.X11Util;
import jogamp.newt.DisplayImpl;
import jogamp.newt.NEWTJNILibLoader;
-public class X11Display extends DisplayImpl {
+public class DisplayDriver extends DisplayImpl {
static {
NEWTJNILibLoader.loadNEWT();
@@ -53,7 +52,7 @@ public class X11Display extends DisplayImpl {
throw new NativeWindowException("Failed to initialize X11Display jmethodIDs");
}
- if (!X11Window.initIDs0()) {
+ if (!WindowDriver.initIDs0()) {
throw new NativeWindowException("Failed to initialize X11Window jmethodIDs");
}
}
@@ -63,7 +62,7 @@ public class X11Display extends DisplayImpl {
}
- public X11Display() {
+ public DisplayDriver() {
}
public String validateDisplayName(String name, long handle) {
@@ -74,71 +73,55 @@ public class X11Display extends DisplayImpl {
* {@inheritDoc}
*
* We use a private non-shared X11 Display instance for EDT window operations and one for exposed animation, eg. OpenGL.
- * <p>
- * In case {@link X11Util#HAS_XLOCKDISPLAY_BUG} and {@link X11Util#XINITTHREADS_ALWAYS_ENABLED},
- * we use null locking. Even though this seems not to be rational, it gives most stable results on all platforms.
- * </p>
- * <p>
- * Otherwise we use basic locking via the constructor {@link X11GraphicsDevice#X11GraphicsDevice(long, int, boolean)},
- * since it is possible to share this device via {@link com.jogamp.newt.NewtFactory#createDisplay(String, boolean)}.
- * </p>
*/
- @SuppressWarnings("unused")
protected void createNativeImpl() {
+ X11Util.setX11ErrorHandler(true, DEBUG ? false : true); // make sure X11 error handler is set
long handle = X11Util.openDisplay(name);
if( 0 == handle ) {
throw new RuntimeException("Error creating display(Win): "+name);
}
- if(USE_SEPARATE_DISPLAY_FOR_EDT) {
- edtDisplayHandle = X11Util.openDisplay(name);
- if( 0 == edtDisplayHandle ) {
- X11Util.closeDisplay(handle);
- throw new RuntimeException("Error creating display(EDT): "+name);
- }
- } else {
- edtDisplayHandle = handle;
- }
+ aDevice = new X11GraphicsDevice(handle, AbstractGraphicsDevice.DEFAULT_UNIT, true /* owner */);
try {
- CompleteDisplay0(edtDisplayHandle);
+ CompleteDisplay0(aDevice.getHandle());
} catch(RuntimeException e) {
closeNativeImpl();
- throw e;
- }
-
- // see API doc above!
- if(X11Util.XINITTHREADS_ALWAYS_ENABLED && X11Util.HAS_XLOCKDISPLAY_BUG) {
- aDevice = new X11GraphicsDevice(handle, AbstractGraphicsDevice.DEFAULT_UNIT, NativeWindowFactory.getNullToolkitLock(), false);
- } else {
- aDevice = new X11GraphicsDevice(handle, AbstractGraphicsDevice.DEFAULT_UNIT, false);
+ throw e;
}
}
+ @Override
protected void closeNativeImpl() {
- DisplayRelease0(edtDisplayHandle, javaObjectAtom, windowDeleteAtom);
+ DisplayRelease0(aDevice.getHandle(), javaObjectAtom, windowDeleteAtom);
javaObjectAtom = 0;
windowDeleteAtom = 0;
- // closing using ATI driver bug 'same order'
- final long handle = getHandle();
- X11Util.closeDisplay(handle);
- if(handle != edtDisplayHandle) {
- X11Util.closeDisplay(edtDisplayHandle);
- }
- edtDisplayHandle = 0;
+ aDevice.close(); // closes X11 display
}
+ @Override
protected void dispatchMessagesNative() {
- if(0 != edtDisplayHandle) {
- DispatchMessages0(edtDisplayHandle, javaObjectAtom, windowDeleteAtom);
+ aDevice.lock();
+ try {
+ final long handle = aDevice.getHandle();
+ if(0 != handle) {
+ DispatchMessages0(handle, javaObjectAtom, windowDeleteAtom);
+ }
+ } finally {
+ if(null != aDevice) { // could be pulled by destroy event
+ aDevice.unlock();
+ }
}
}
- protected long getEDTHandle() { return edtDisplayHandle; }
protected long getJavaObjectAtom() { return javaObjectAtom; }
protected long getWindowDeleteAtom() { return windowDeleteAtom; }
+ /** Returns <code>null</code> if !{@link #isNativeValid()}, otherwise the Boolean value of {@link X11GraphicsDevice#isXineramaEnabled()}. */
+ protected Boolean isXineramaEnabled() { return isNativeValid() ? Boolean.valueOf(((X11GraphicsDevice)aDevice).isXineramaEnabled()) : null; }
+
//----------------------------------------------------------------------
// Internals only
//
+
private static native boolean initIDs0(boolean debug);
private native void CompleteDisplay0(long handle);
@@ -151,21 +134,10 @@ public class X11Display extends DisplayImpl {
private native void DispatchMessages0(long display, long javaObjectAtom, long windowDeleteAtom);
- /**
- * 2011/06/14 libX11 1.4.2 and libxcb 1.7 bug 20708 - Multithreading Issues w/ OpenGL, ..
- * https://bugs.freedesktop.org/show_bug.cgi?id=20708
- * https://jogamp.org/bugzilla/show_bug.cgi?id=502
- * Affects: Ubuntu 11.04, OpenSuSE 11, ..
- * Workaround: Using a separate X11 Display connection for event dispatching (EDT)
- */
- private final boolean USE_SEPARATE_DISPLAY_FOR_EDT = true;
-
- private long edtDisplayHandle;
-
/** X11 Window delete atom marker used on EDT */
private long windowDeleteAtom;
/** X11 Window java object property used on EDT */
- private long javaObjectAtom;
+ private long javaObjectAtom;
}
diff --git a/src/newt/classes/jogamp/newt/driver/x11/X11Screen.java b/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java
similarity index 91%
rename from src/newt/classes/jogamp/newt/driver/x11/X11Screen.java
rename to src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java
index 93db854..7a3c718 100644
--- a/src/newt/classes/jogamp/newt/driver/x11/X11Screen.java
+++ b/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java
@@ -48,18 +48,18 @@ import com.jogamp.nativewindow.x11.X11GraphicsScreen;
import com.jogamp.newt.ScreenMode;
import com.jogamp.newt.util.ScreenModeUtil;
-public class X11Screen extends ScreenImpl {
+public class ScreenDriver extends ScreenImpl {
static {
- X11Display.initSingleton();
+ DisplayDriver.initSingleton();
}
- public X11Screen() {
+ public ScreenDriver() {
}
protected void createNativeImpl() {
// validate screen index
- Long handle = display.runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable<Long>() {
+ Long handle = runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Long>() {
public Long run(long dpy) {
return new Long(GetScreen0(dpy, screen_idx));
} } );
@@ -81,7 +81,7 @@ public class X11Screen extends ScreenImpl {
private int nmode_number;
protected int[] getScreenModeFirstImpl() {
- return runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable<int[]>() {
+ return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<int[]>() {
public int[] run(long dpy) {
// initialize iterators and static data
nrotations = getAvailableScreenModeRotations0(dpy, screen_idx);
@@ -110,7 +110,7 @@ public class X11Screen extends ScreenImpl {
protected int[] getScreenModeNextImpl() {
// assemble: w x h x bpp x f x r
- return runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable<int[]>() {
+ return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<int[]>() {
public int[] run(long dpy) {
/**
System.err.println("******** mode: "+nmode_number);
@@ -176,7 +176,7 @@ public class X11Screen extends ScreenImpl {
}
protected ScreenMode getCurrentScreenModeImpl() {
- return runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable<ScreenMode>() {
+ return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<ScreenMode>() {
public ScreenMode run(long dpy) {
long screenConfigHandle = getScreenConfiguration0(dpy, screen_idx);
if(0 == screenConfigHandle) {
@@ -237,7 +237,7 @@ public class X11Screen extends ScreenImpl {
throw new RuntimeException("ScreenMode not element of ScreenMode list: "+screenMode);
}
final long t0 = System.currentTimeMillis();
- boolean done = runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable<Boolean>() {
+ boolean done = runWithTempDisplayHandle( new DisplayImpl.DisplayRunnable<Boolean>() {
public Boolean run(long dpy) {
boolean done = false;
long screenConfigHandle = getScreenConfiguration0(dpy, screen_idx);
@@ -276,23 +276,23 @@ public class X11Screen extends ScreenImpl {
return done;
}
- private class XineramaEnabledQuery implements DisplayImpl.DisplayRunnable<Boolean> {
+ private DisplayImpl.DisplayRunnable<Boolean> xineramaEnabledQueryWithTemp = new DisplayImpl.DisplayRunnable<Boolean>() {
public Boolean run(long dpy) {
return new Boolean(X11Util.XineramaIsEnabled(dpy));
- }
- }
- private XineramaEnabledQuery xineramaEnabledQuery = new XineramaEnabledQuery();
+ } };
protected int validateScreenIndex(final int idx) {
- if(getDisplay().isNativeValid()) {
- return runWithLockedDisplayHandle( xineramaEnabledQuery ).booleanValue() ? 0 : idx;
+ final DisplayDriver x11Display = (DisplayDriver) getDisplay();
+ final Boolean r = x11Display.isXineramaEnabled();
+ if( null != r ) {
+ return r.booleanValue() ? 0 : idx;
} else {
- return runWithTempDisplayHandle( xineramaEnabledQuery ).booleanValue() ? 0 : idx;
+ return runWithTempDisplayHandle( xineramaEnabledQueryWithTemp ).booleanValue() ? 0 : idx;
}
}
protected void getVirtualScreenOriginAndSize(final Point virtualOrigin, final Dimension virtualSize) {
- display.runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable<Object>() {
+ runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Object>() {
public Object run(long dpy) {
virtualOrigin.setX(0);
virtualOrigin.setY(0);
@@ -305,10 +305,8 @@ public class X11Screen extends ScreenImpl {
//----------------------------------------------------------------------
// Internals only
//
- private final <T> T runWithLockedDisplayHandle(DisplayRunnable<T> action) {
- return display.runWithLockedDisplayHandle(action);
- // return runWithTempDisplayHandle(action);
- // return runWithoutLock(action);
+ private final <T> T runWithLockedDisplayDevice(DisplayRunnable<T> action) {
+ return display.runWithLockedDisplayDevice(action);
}
private final <T> T runWithTempDisplayHandle(DisplayRunnable<T> action) {
@@ -324,9 +322,6 @@ public class X11Screen extends ScreenImpl {
}
return res;
}
- private final <T> T runWithoutLock(DisplayRunnable<T> action) {
- return action.run(display.getHandle());
- }
private static native long GetScreen0(long dpy, int scrn_idx);
diff --git a/src/newt/classes/jogamp/newt/driver/x11/X11Window.java b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java
similarity index 68%
rename from src/newt/classes/jogamp/newt/driver/x11/X11Window.java
rename to src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java
index 5501f5a..c21cb4b 100644
--- a/src/newt/classes/jogamp/newt/driver/x11/X11Window.java
+++ b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java
@@ -35,6 +35,7 @@
package jogamp.newt.driver.x11;
import jogamp.nativewindow.x11.X11Lib;
+import jogamp.nativewindow.x11.X11Util;
import jogamp.newt.DisplayImpl;
import jogamp.newt.DisplayImpl.DisplayRunnable;
import jogamp.newt.WindowImpl;
@@ -44,28 +45,40 @@ import javax.media.nativewindow.util.Insets;
import javax.media.nativewindow.util.InsetsImmutable;
import javax.media.nativewindow.util.Point;
+import com.jogamp.nativewindow.x11.X11GraphicsDevice;
+import com.jogamp.nativewindow.x11.X11GraphicsScreen;
import com.jogamp.newt.event.MouseEvent;
-public class X11Window extends WindowImpl {
+public class WindowDriver extends WindowImpl {
private static final String WINDOW_CLASS_NAME = "NewtWindow";
- private static final int X11_WHEEL_ONE_UP_BUTTON = 4;
+ private static final int X11_WHEEL_ONE_UP_BUTTON = 4;
private static final int X11_WHEEL_ONE_DOWN_BUTTON = 5;
- private static final int X11_WHEEL_TWO_UP_BUTTON = 6;
+ private static final int X11_WHEEL_TWO_UP_BUTTON = 6;
private static final int X11_WHEEL_TWO_DOWN_BUTTON = 7;
static {
- X11Display.initSingleton();
+ DisplayDriver.initSingleton();
}
- public X11Window() {
+ public WindowDriver() {
}
protected void createNativeImpl() {
- final X11Screen screen = (X11Screen) getScreen();
- final X11Display display = (X11Display) screen.getDisplay();
+ final ScreenDriver screen = (ScreenDriver) getScreen();
+ final DisplayDriver display = (DisplayDriver) screen.getDisplay();
+ final AbstractGraphicsDevice edtDevice = display.getGraphicsDevice();
+
+ // Decoupled X11 Device/Screen allowing X11 display lock-free off-thread rendering
+ final long renderDeviceHandle = X11Util.openDisplay(edtDevice.getConnection());
+ if( 0 == renderDeviceHandle ) {
+ throw new RuntimeException("Error creating display(EDT): "+edtDevice.getConnection());
+ }
+ renderDevice = new X11GraphicsDevice(renderDeviceHandle, AbstractGraphicsDevice.DEFAULT_UNIT, true /* owner */);
+ final AbstractGraphicsScreen renderScreen = new X11GraphicsScreen(renderDevice, screen.getIndex());
+
final GraphicsConfigurationFactory factory = GraphicsConfigurationFactory.getFactory(display.getGraphicsDevice(), capsRequested);
final AbstractGraphicsConfiguration cfg = factory.chooseGraphicsConfiguration(
- capsRequested, capsRequested, capabilitiesChooser, screen.getGraphicsScreen(), VisualIDHolder.VID_UNDEFINED);
+ capsRequested, capsRequested, capabilitiesChooser, renderScreen, VisualIDHolder.VID_UNDEFINED);
if(DEBUG_IMPLEMENTATION) {
System.err.println("X11Window.createNativeImpl() factory: "+factory+", chosen config: "+cfg);
}
@@ -78,11 +91,16 @@ public class X11Window extends WindowImpl {
}
setGraphicsConfiguration(cfg);
final int flags = getReconfigureFlags(0, true) &
- ( FLAG_IS_ALWAYSONTOP | FLAG_IS_UNDECORATED ) ;
- setWindowHandle(CreateWindow0(getParentWindowHandle(),
- display.getEDTHandle(), screen.getIndex(), visualID,
- display.getJavaObjectAtom(), display.getWindowDeleteAtom(),
- getX(), getY(), getWidth(), getHeight(), autoPosition(), flags));
+ ( FLAG_IS_ALWAYSONTOP | FLAG_IS_UNDECORATED ) ;
+ edtDevice.lock();
+ try {
+ setWindowHandle(CreateWindow0(getParentWindowHandle(),
+ edtDevice.getHandle(), screen.getIndex(), visualID,
+ display.getJavaObjectAtom(), display.getWindowDeleteAtom(),
+ getX(), getY(), getWidth(), getHeight(), autoPosition(), flags));
+ } finally {
+ edtDevice.unlock();
+ }
windowHandleClose = getWindowHandle();
if (0 == windowHandleClose) {
throw new NativeWindowException("Error creating window");
@@ -91,9 +109,11 @@ public class X11Window extends WindowImpl {
protected void closeNativeImpl() {
if(0!=windowHandleClose && null!=getScreen() ) {
- X11Display display = (X11Display) getScreen().getDisplay();
+ DisplayDriver display = (DisplayDriver) getScreen().getDisplay();
+ final AbstractGraphicsDevice edtDevice = display.getGraphicsDevice();
+ edtDevice.lock();
try {
- CloseWindow0(display.getEDTHandle(), windowHandleClose,
+ CloseWindow0(edtDevice.getHandle(), windowHandleClose,
display.getJavaObjectAtom(), display.getWindowDeleteAtom());
} catch (Throwable t) {
if(DEBUG_IMPLEMENTATION) {
@@ -101,28 +121,47 @@ public class X11Window extends WindowImpl {
e.printStackTrace();
}
} finally {
+ edtDevice.unlock();
windowHandleClose = 0;
}
}
+ if(null != renderDevice) {
+ renderDevice.close(); // closes X11 display
+ renderDevice = null;
+ }
}
- protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) {
+ @Override
+ public long getDisplayHandle() {
+ // Actually: return getGraphicsConfiguration().getScreen().getDevice().getHandle();
+ return renderDevice.getHandle(); // shortcut
+ }
+
+ protected boolean reconfigureWindowImpl(final int x, final int y, final int width, final int height, final int flags) {
if(DEBUG_IMPLEMENTATION) {
System.err.println("X11Window reconfig: "+x+"/"+y+" "+width+"x"+height+", "+
getReconfigureFlagsAsString(null, flags));
}
+ final int _x, _y;
if(0 == ( FLAG_IS_UNDECORATED & flags)) {
final InsetsImmutable i = getInsets();
// client position -> top-level window position
- x -= i.getLeftWidth() ;
- y -= i.getTopHeight() ;
+ _x = x - i.getLeftWidth() ;
+ _y = y - i.getTopHeight() ;
+ } else {
+ _x = x;
+ _y = y;
}
- final X11Display display = (X11Display) getScreen().getDisplay();
- reconfigureWindow0( getDisplayEDTHandle(), getScreenIndex(),
- getParentWindowHandle(), getWindowHandle(), display.getWindowDeleteAtom(),
- x, y, width, height, flags);
-
+ final DisplayDriver display = (DisplayDriver) getScreen().getDisplay();
+ runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Object>() {
+ public Object run(long dpy) {
+ reconfigureWindow0( dpy, getScreenIndex(),
+ getParentWindowHandle(), getWindowHandle(), display.getWindowDeleteAtom(),
+ _x, _y, width, height, flags);
+ return null;
+ }
+ });
return true;
}
@@ -133,13 +172,18 @@ public class X11Window extends WindowImpl {
}
}
- protected void requestFocusImpl(boolean force) {
- requestFocus0(getDisplayEDTHandle(), getWindowHandle(), force);
+ protected void requestFocusImpl(final boolean force) {
+ runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Object>() {
+ public Object run(long dpy) {
+ requestFocus0(dpy, getWindowHandle(), force);
+ return null;
+ }
+ });
}
@Override
protected void setTitleImpl(final String title) {
- runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable<Object>() {
+ runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Object>() {
public Object run(long dpy) {
setTitle0(dpy, getWindowHandle(), title);
return null;
@@ -149,35 +193,38 @@ public class X11Window extends WindowImpl {
@Override
protected boolean setPointerVisibleImpl(final boolean pointerVisible) {
- return runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable<Boolean>() {
+ return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Boolean>() {
public Boolean run(long dpy) {
- return Boolean.valueOf(setPointerVisible0(getDisplayEDTHandle(), getWindowHandle(), pointerVisible));
+ return Boolean.valueOf(setPointerVisible0(dpy, getWindowHandle(), pointerVisible));
}
}).booleanValue();
}
@Override
protected boolean confinePointerImpl(final boolean confine) {
- return runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable<Boolean>() {
+ return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Boolean>() {
public Boolean run(long dpy) {
- return Boolean.valueOf(confinePointer0(getDisplayEDTHandle(), getWindowHandle(), confine));
+ return Boolean.valueOf(confinePointer0(dpy, getWindowHandle(), confine));
}
}).booleanValue();
}
@Override
protected void warpPointerImpl(final int x, final int y) {
- runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable<Object>() {
+ runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Object>() {
public Object run(long dpy) {
- warpPointer0(getDisplayEDTHandle(), getWindowHandle(), x, y);
+ warpPointer0(dpy, getWindowHandle(), x, y);
return null;
}
});
}
protected Point getLocationOnScreenImpl(final int x, final int y) {
- // X11Util.GetRelativeLocation: locks display already !
- return X11Lib.GetRelativeLocation( getScreen().getDisplay().getHandle(), getScreenIndex(), getWindowHandle(), 0 /*root win*/, x, y);
+ return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Point>() {
+ public Point run(long dpy) {
+ return X11Lib.GetRelativeLocation(dpy, getScreenIndex(), getWindowHandle(), 0 /*root win*/, x, y);
+ }
+ } );
}
protected void updateInsetsImpl(Insets insets) {
@@ -229,16 +276,11 @@ public class X11Window extends WindowImpl {
//----------------------------------------------------------------------
// Internals only
//
-
private static final String getCurrentThreadName() { return Thread.currentThread().getName(); } // Callback for JNI
private static final void dumpStack() { Thread.dumpStack(); } // Callback for JNI
- private final long getDisplayEDTHandle() {
- return ((X11Display) getScreen().getDisplay()).getEDTHandle();
- }
- private final <T> T runWithLockedDisplayHandle(DisplayRunnable<T> action) {
- return ((DisplayImpl) getScreen().getDisplay()).runWithLockedDisplayHandle(action);
- // return runWithTempDisplayHandle(action);
+ private final <T> T runWithLockedDisplayDevice(DisplayRunnable<T> action) {
+ return ((DisplayDriver) getScreen().getDisplay()).runWithLockedDisplayDevice(action);
}
protected static native boolean initIDs0();
@@ -258,4 +300,5 @@ public class X11Window extends WindowImpl {
private static native void warpPointer0(long display, long windowHandle, int x, int y);
private long windowHandleClose;
+ private X11GraphicsDevice renderDevice;
}
diff --git a/src/newt/native/AndroidWindow.c b/src/newt/native/AndroidWindow.c
index fa57656..94695e1 100644
--- a/src/newt/native/AndroidWindow.c
+++ b/src/newt/native/AndroidWindow.c
@@ -9,7 +9,7 @@
#include <unistd.h>
#include <errno.h>
-#include "jogamp_newt_driver_android_AndroidWindow.h"
+#include "jogamp_newt_driver_android_WindowDriver.h"
#include <android/native_window.h>
#include <android/native_window_jni.h>
@@ -23,56 +23,56 @@
#endif
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_android_AndroidWindow_getSurfaceHandle0
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_android_WindowDriver_getSurfaceHandle0
(JNIEnv *env, jclass clazz, jobject surface)
{
ANativeWindow * anw = ANativeWindow_fromSurface(env, surface);
return (jlong) (intptr_t) anw;
}
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_android_AndroidWindow_getSurfaceVisualID0
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_android_WindowDriver_getSurfaceVisualID0
(JNIEnv *env, jclass clazz, jlong surfaceHandle)
{
ANativeWindow * anw = (ANativeWindow *) (intptr_t) surfaceHandle;
return (jint) ANativeWindow_getFormat(anw);
}
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_android_AndroidWindow_setSurfaceVisualID0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_android_WindowDriver_setSurfaceVisualID0
(JNIEnv *env, jclass clazz, jlong surfaceHandle, jint nativeVisualID)
{
ANativeWindow * anw = (ANativeWindow *) (intptr_t) surfaceHandle;
ANativeWindow_setBuffersGeometry(anw, 0, 0, nativeVisualID);
}
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_android_AndroidWindow_getWidth0
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_android_WindowDriver_getWidth0
(JNIEnv *env, jclass clazz, jlong surfaceHandle)
{
ANativeWindow * anw = (ANativeWindow *) (intptr_t) surfaceHandle;
return (jint) ANativeWindow_getWidth(anw);
}
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_android_AndroidWindow_getHeight0
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_android_WindowDriver_getHeight0
(JNIEnv *env, jclass clazz, jlong surfaceHandle)
{
ANativeWindow * anw = (ANativeWindow *) (intptr_t) surfaceHandle;
return (jint) ANativeWindow_getHeight(anw);
}
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_android_AndroidWindow_acquire0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_android_WindowDriver_acquire0
(JNIEnv *env, jclass clazz, jlong surfaceHandle)
{
ANativeWindow * anw = (ANativeWindow *) (intptr_t) surfaceHandle;
ANativeWindow_acquire(anw);
}
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_android_AndroidWindow_release0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_android_WindowDriver_release0
(JNIEnv *env, jclass clazz, jlong surfaceHandle)
{
ANativeWindow * anw = (ANativeWindow *) (intptr_t) surfaceHandle;
ANativeWindow_release(anw);
}
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_android_AndroidWindow_initIDs0
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_android_WindowDriver_initIDs0
(JNIEnv *env, jclass clazz)
{
DBG_PRINT( "initIDs ok\n" );
diff --git a/src/newt/native/InputEvent.h b/src/newt/native/InputEvent.h
index b42c06d..3fa7dbe 100644
--- a/src/newt/native/InputEvent.h
+++ b/src/newt/native/InputEvent.h
@@ -34,13 +34,24 @@
#ifndef _INPUT_EVENT_H_
#define _INPUT_EVENT_H_
-#define EVENT_SHIFT_MASK 1
-#define EVENT_CTRL_MASK 2
-#define EVENT_META_MASK 4
-#define EVENT_ALT_MASK 8
-#define EVENT_ALT_GRAPH_MASK 32
-#define EVENT_BUTTON1_MASK (1<<6)
-#define EVENT_BUTTON2_MASK (1<<7)
-#define EVENT_BUTTON3_MASK (1<<8)
+#define EVENT_SHIFT_MASK (1 << 0)
+#define EVENT_CTRL_MASK (1 << 1)
+#define EVENT_META_MASK (1 << 2)
+#define EVENT_ALT_MASK (1 << 3)
+#define EVENT_ALT_GRAPH_MASK (1 << 4)
+
+#define EVENT_BUTTON1_MASK (1 << 5)
+#define EVENT_BUTTON2_MASK (1 << 6)
+#define EVENT_BUTTON3_MASK (1 << 7)
+#define EVENT_BUTTON4_MASK (1 << 8)
+#define EVENT_BUTTON5_MASK (1 << 9)
+#define EVENT_BUTTON6_MASK (1 << 10)
+#define EVENT_BUTTON7_MASK (1 << 11)
+#define EVENT_BUTTON8_MASK (1 << 12)
+#define EVENT_BUTTON9_MASK (1 << 13)
+
+#define EVENT_AUTOREPEAT_MASK (1 << 29)
+#define EVENT_CONFINED_MASK (1 << 30)
+#define EVENT_INVISIBLE_MASK (1 << 31)
#endif
diff --git a/src/newt/native/IntelGDL.c b/src/newt/native/IntelGDL.c
index 690e112..a3bf101 100644
--- a/src/newt/native/IntelGDL.c
+++ b/src/newt/native/IntelGDL.c
@@ -37,9 +37,9 @@
#include <stdio.h>
#include <string.h>
-#include "jogamp_newt_driver_intel_gdl_Display.h"
-#include "jogamp_newt_driver_intel_gdl_Screen.h"
-#include "jogamp_newt_driver_intel_gdl_Window.h"
+#include "jogamp_newt_driver_intel_gdl_DisplayDriver.h"
+#include "jogamp_newt_driver_intel_gdl_ScreenDriver.h"
+#include "jogamp_newt_driver_intel_gdl_WindowDriver.h"
#include "MouseEvent.h"
#include "KeyEvent.h"
@@ -122,7 +122,7 @@ static void JNI_ThrowNew(JNIEnv *env, const char *throwable, const char* message
* Display
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_intel_gdl_Display_DispatchMessages
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_intel_gdl_DisplayDriver_DispatchMessages
(JNIEnv *env, jobject obj, jlong displayHandle, jobject focusedWindow)
{
// FIXME: n/a
@@ -137,7 +137,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_intel_gdl_Display_DispatchMessage
} */
}
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_intel_gdl_Display_CreateDisplay
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_intel_gdl_DisplayDriver_CreateDisplay
(JNIEnv *env, jobject obj)
{
gdl_ret_t retval;
@@ -170,7 +170,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_intel_gdl_Display_CreateDisplay
return (jlong) (intptr_t) p_driver_info;
}
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_intel_gdl_Display_DestroyDisplay
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_intel_gdl_DisplayDriver_DestroyDisplay
(JNIEnv *env, jobject obj, jlong displayHandle)
{
gdl_driver_info_t * p_driver_info = (gdl_driver_info_t *) (intptr_t) displayHandle;
@@ -189,7 +189,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_intel_gdl_Display_DestroyDisplay
* Screen
*/
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_intel_gdl_Screen_initIDs
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_intel_gdl_ScreenDriver_initIDs
(JNIEnv *env, jclass clazz)
{
screenCreatedID = (*env)->GetMethodID(env, clazz, "screenCreated", "(II)V");
@@ -201,7 +201,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_intel_gdl_Screen_initIDs
return JNI_TRUE;
}
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_intel_gdl_Screen_GetScreenInfo
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_intel_gdl_ScreenDriver_GetScreenInfo
(JNIEnv *env, jobject obj, jlong displayHandle, jint idx)
{
gdl_driver_info_t * p_driver_info = (gdl_driver_info_t *) (intptr_t) displayHandle;
@@ -233,7 +233,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_intel_gdl_Screen_GetScreenInfo
* Window
*/
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_intel_gdl_Window_initIDs
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_intel_gdl_WindowDriver_initIDs
(JNIEnv *env, jclass clazz)
{
updateBoundsID = (*env)->GetMethodID(env, clazz, "updateBounds", "(IIII)V");
@@ -245,7 +245,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_intel_gdl_Window_initIDs
return JNI_TRUE;
}
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_intel_gdl_Window_CreateSurface
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_intel_gdl_WindowDriver_CreateSurface
(JNIEnv *env, jobject obj, jlong displayHandle, jint scr_width, jint scr_height, jint x, jint y, jint width, jint height) {
gdl_driver_info_t * p_driver_info = (gdl_driver_info_t *) (intptr_t) displayHandle;
@@ -338,7 +338,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_intel_gdl_Window_CreateSurface
return (jlong) (intptr_t) plane;
}
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_intel_gdl_Window_CloseSurface
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_intel_gdl_WindowDriver_CloseSurface
(JNIEnv *env, jobject obj, jlong display, jlong surface)
{
gdl_plane_id_t plane = (gdl_plane_id_t) (intptr_t) surface ;
@@ -347,7 +347,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_intel_gdl_Window_CloseSurface
DBG_PRINT("[CloseSurface] plane %d\n", plane);
}
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_intel_gdl_Window_SetBounds0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_intel_gdl_WindowDriver_SetBounds0
(JNIEnv *env, jobject obj, jlong surface, jint scr_width, jint scr_height, jint x, jint y, jint width, jint height) {
gdl_plane_id_t plane = (gdl_plane_id_t) (intptr_t) surface ;
diff --git a/src/newt/native/KDWindow.c b/src/newt/native/KDWindow.c
index 5afe6fc..f1d6aec 100644
--- a/src/newt/native/KDWindow.c
+++ b/src/newt/native/KDWindow.c
@@ -44,7 +44,7 @@
#include <KD/kd.h>
#include <EGL/egl.h>
-#include "jogamp_newt_driver_kd_KDWindow.h"
+#include "jogamp_newt_driver_kd_WindowDriver.h"
#include "MouseEvent.h"
#include "KeyEvent.h"
@@ -82,7 +82,7 @@ static jmethodID sendKeyEventID = NULL;
* Display
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_kd_KDDisplay_DispatchMessages
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_kd_DisplayDriver_DispatchMessages
(JNIEnv *env, jobject obj)
{
const KDEvent * evt;
@@ -180,7 +180,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_kd_KDDisplay_DispatchMessages
* Window
*/
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_kd_KDWindow_initIDs
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_kd_WindowDriver_initIDs
(JNIEnv *env, jclass clazz)
{
#ifdef VERBOSE_ON
@@ -208,7 +208,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_kd_KDWindow_initIDs
return JNI_TRUE;
}
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_kd_KDWindow_CreateWindow
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_kd_WindowDriver_CreateWindow
(JNIEnv *env, jobject obj, jlong display, jlong jeglConfig)
{
EGLDisplay dpy = (EGLDisplay)(intptr_t)display;
@@ -236,7 +236,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_kd_KDWindow_CreateWindow
return (jlong) (intptr_t) window;
}
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_kd_KDWindow_RealizeWindow
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_kd_WindowDriver_RealizeWindow
(JNIEnv *env, jobject obj, jlong window)
{
KDWindow *w = (KDWindow*) (intptr_t) window;
@@ -251,7 +251,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_kd_KDWindow_RealizeWindow
return (jlong) (intptr_t) nativeWindow;
}
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_kd_KDWindow_CloseWindow
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_kd_WindowDriver_CloseWindow
(JNIEnv *env, jobject obj, jlong window, jlong juserData)
{
KDWindow *w = (KDWindow*) (intptr_t) window;
@@ -265,11 +265,11 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_kd_KDWindow_CloseWindow
}
/*
- * Class: jogamp_newt_driver_kd_KDWindow
+ * Class: jogamp_newt_driver_kd_WindowDriver
* Method: setVisible0
* Signature: (JJZ)V
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_kd_KDWindow_setVisible0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_kd_WindowDriver_setVisible0
(JNIEnv *env, jobject obj, jlong window, jboolean visible)
{
KDWindow *w = (KDWindow*) (intptr_t) window;
@@ -279,7 +279,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_kd_KDWindow_setVisible0
(*env)->CallVoidMethod(env, obj, visibleChangedID, JNI_FALSE, visible); // FIXME: or defer=true ?
}
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_kd_KDWindow_setFullScreen0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_kd_WindowDriver_setFullScreen0
(JNIEnv *env, jobject obj, jlong window, jboolean fullscreen)
{
/** not supported, due to missing NV property ..
@@ -296,7 +296,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_kd_KDWindow_setFullScreen0
(void)fullscreen;
}
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_kd_KDWindow_setSize0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_kd_WindowDriver_setSize0
(JNIEnv *env, jobject obj, jlong window, jint width, jint height)
{
KDWindow *w = (KDWindow*) (intptr_t) window;
diff --git a/src/newt/native/MacWindow.m b/src/newt/native/MacWindow.m
index bbadc9d..b9c3392 100644
--- a/src/newt/native/MacWindow.m
+++ b/src/newt/native/MacWindow.m
@@ -33,7 +33,7 @@
#import <inttypes.h>
-#import "jogamp_newt_driver_macosx_MacWindow.h"
+#import "jogamp_newt_driver_macosx_WindowDriver.h"
#import "NewtMacWindow.h"
#import "MouseEvent.h"
@@ -94,7 +94,13 @@ static void changeContentView(JNIEnv *env, jobject javaWindowObject, NSView *pvi
if(NULL!=oldNSView) {
NS_DURING
// Available >= 10.5 - Makes the menubar disapear
- if([oldNSView isInFullScreenMode]) {
+ BOOL iifs;
+ if ( [oldNSView respondsToSelector:@selector(isInFullScreenMode)] ) {
+ iifs = [oldNSView isInFullScreenMode];
+ } else {
+ iifs = NO;
+ }
+ if(iifs && [oldNSView respondsToSelector:@selector(exitFullScreenModeWithOptions:)] ) {
[oldNSView exitFullScreenModeWithOptions: NULL];
}
NS_HANDLER
@@ -155,11 +161,11 @@ NS_ENDHANDLER
}
/*
- * Class: jogamp_newt_driver_macosx_MacDisplay
+ * Class: jogamp_newt_driver_macosx_DisplayDriver
* Method: initIDs
* Signature: ()Z
*/
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacDisplay_initNSApplication0
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_DisplayDriver_initNSApplication0
(JNIEnv *env, jclass clazz)
{
static int initialized = 0;
@@ -189,11 +195,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacDisplay_initNSAppli
}
/*
- * Class: jogamp_newt_driver_macosx_MacDisplay
+ * Class: jogamp_newt_driver_macosx_DisplayDriver
* Method: runNSApplication0
* Signature: ()V
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacDisplay_runNSApplication0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_DisplayDriver_runNSApplication0
(JNIEnv *env, jclass clazz)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
@@ -206,11 +212,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacDisplay_runNSApplicatio
}
/*
- * Class: jogamp_newt_driver_macosx_MacDisplay
+ * Class: jogamp_newt_driver_macosx_DisplayDriver
* Method: stopNSApplication0
* Signature: ()V
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacDisplay_stopNSApplication0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_DisplayDriver_stopNSApplication0
(JNIEnv *env, jclass clazz)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
@@ -250,11 +256,11 @@ static NSScreen * NewtScreen_getNSScreenByIndex(int screen_idx) {
}
/*
- * Class: jogamp_newt_driver_macosx_MacScreen
+ * Class: jogamp_newt_driver_macosx_ScreenDriver
* Method: getWidthImpl
* Signature: (I)I
*/
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_macosx_MacScreen_getWidthImpl0
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getWidthImpl0
(JNIEnv *env, jclass clazz, jint screen_idx)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
@@ -268,11 +274,11 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_macosx_MacScreen_getWidthImpl0
}
/*
- * Class: jogamp_newt_driver_macosx_MacScreen
+ * Class: jogamp_newt_driver_macosx_ScreenDriver
* Method: getHeightImpl
* Signature: (I)I
*/
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_macosx_MacScreen_getHeightImpl0
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getHeightImpl0
(JNIEnv *env, jclass clazz, jint screen_idx)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
@@ -318,11 +324,11 @@ static long GetDictionaryLong(CFDictionaryRef theDict, const void* key)
#define ROTMODES_PER_REALMODE 4
/*
- * Class: jogamp_newt_driver_macosx_MacScreen
+ * Class: jogamp_newt_driver_macosx_ScreenDriver
* Method: getScreenSizeMM0
* Signature: (I)[I
*/
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_MacScreen_getScreenSizeMM0
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getScreenSizeMM0
(JNIEnv *env, jobject obj, jint scrn_idx)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
@@ -367,11 +373,11 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_MacScreen_getScreenSi
}
/*
- * Class: jogamp_newt_driver_macosx_MacScreen
+ * Class: jogamp_newt_driver_macosx_ScreenDriver
* Method: getScreenMode0
* Signature: (IIII)[I
*/
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_MacScreen_getScreenMode0
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getScreenMode0
(JNIEnv *env, jobject obj, jint scrn_idx, jint mode_idx, jint widthMM, jint heightMM)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
@@ -430,6 +436,8 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_MacScreen_getScreenMo
if( -1 < mode_idx ) {
prop[propIndex++] = mode_idx;
}
+ int refreshRate = CGDDGetModeRefreshRate(mode);
+ int fRefreshRate = ( 0 < refreshRate ) ? refreshRate : 60; // default .. (experienced on OSX 10.6.8)
prop[propIndex++] = 0; // set later for verification of iterator
propIndexRes = propIndex;
prop[propIndex++] = mWidth;
@@ -437,14 +445,14 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_MacScreen_getScreenMo
prop[propIndex++] = CGDDGetModeBitsPerPixel(mode);
prop[propIndex++] = widthMM;
prop[propIndex++] = heightMM;
- prop[propIndex++] = CGDDGetModeRefreshRate(mode);
+ prop[propIndex++] = fRefreshRate;
prop[propIndex++] = ccwRot;
prop[propIndex - NUM_SCREEN_MODE_PROPERTIES_ALL] = ( -1 < mode_idx ) ? propIndex-1 : propIndex ; // count == NUM_SCREEN_MODE_PROPERTIES_ALL
- DBG_PRINT( "getScreenMode0: Mode %d/%d (%d): %dx%d, %d bpp, %dx%d mm, %d Hz, rot %d ccw\n",
+ DBG_PRINT( "getScreenMode0: Mode %d/%d (%d): %dx%d, %d bpp, %dx%d mm, %d / %d Hz, rot %d ccw\n",
(int)mode_idx, (int)numberOfAvailableModesRots, (int)numberOfAvailableModes,
(int)prop[propIndexRes+0], (int)prop[propIndexRes+1], (int)prop[propIndexRes+2],
- (int)prop[propIndexRes+3], (int)prop[propIndexRes+4], (int)prop[propIndexRes+5], (int)prop[propIndexRes+6]);
+ (int)prop[propIndexRes+3], (int)prop[propIndexRes+4], (int)prop[propIndexRes+5], refreshRate, (int)prop[propIndexRes+6]);
jintArray properties = (*env)->NewIntArray(env, prop_num);
if (properties == NULL) {
@@ -459,11 +467,11 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_MacScreen_getScreenMo
}
/*
- * Class: jogamp_newt_driver_macosx_MacScreen
+ * Class: jogamp_newt_driver_macosx_ScreenDriver
* Method: setScreenMode0
* Signature: (II)Z
*/
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacScreen_setScreenMode0
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_setScreenMode0
(JNIEnv *env, jobject object, jint scrn_idx, jint mode_idx)
{
jboolean res = JNI_TRUE;
@@ -504,11 +512,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacScreen_setScreenMod
}
/*
- * Class: jogamp_newt_driver_macosx_MacWindow
+ * Class: jogamp_newt_driver_macosx_WindowDriver
* Method: initIDs
* Signature: ()Z
*/
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacWindow_initIDs0
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_initIDs0
(JNIEnv *env, jclass clazz)
{
static int initialized = 0;
@@ -516,19 +524,21 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacWindow_initIDs0
if(initialized) return JNI_TRUE;
initialized = 1;
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+
jclass c;
c = (*env)->FindClass(env, ClazzNamePoint);
if(NULL==c) {
- NewtCommon_FatalError(env, "FatalError Java_jogamp_newt_driver_macosx_MacWindow_initIDs0: can't find %s", ClazzNamePoint);
+ NewtCommon_FatalError(env, "FatalError Java_jogamp_newt_driver_macosx_WindowDriver_initIDs0: can't find %s", ClazzNamePoint);
}
pointClz = (jclass)(*env)->NewGlobalRef(env, c);
(*env)->DeleteLocalRef(env, c);
if(NULL==pointClz) {
- NewtCommon_FatalError(env, "FatalError Java_jogamp_newt_driver_macosx_MacWindow_initIDs0: can't use %s", ClazzNamePoint);
+ NewtCommon_FatalError(env, "FatalError Java_jogamp_newt_driver_macosx_WindowDriver_initIDs0: can't use %s", ClazzNamePoint);
}
pointCstr = (*env)->GetMethodID(env, pointClz, ClazzAnyCstrName, ClazzNamePointCstrSignature);
if(NULL==pointCstr) {
- NewtCommon_FatalError(env, "FatalError Java_jogamp_newt_driver_macosx_MacWindow_initIDs0: can't fetch %s.%s %s",
+ NewtCommon_FatalError(env, "FatalError Java_jogamp_newt_driver_macosx_WindowDriver_initIDs0: can't fetch %s.%s %s",
ClazzNamePoint, ClazzAnyCstrName, ClazzNamePointCstrSignature);
}
@@ -537,15 +547,18 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacWindow_initIDs0
// printf("Going to sleep for 10 seconds\n");
// sleep(10);
- return (jboolean) [NewtMacWindow initNatives: env forClass: clazz];
+ BOOL res = [NewtMacWindow initNatives: env forClass: clazz];
+ [pool release];
+
+ return (jboolean) res;
}
/*
- * Class: jogamp_newt_driver_macosx_MacWindow
+ * Class: jogamp_newt_driver_macosx_WindowDriver
* Method: createWindow0
* Signature: (JIIIIZIIIJ)J
*/
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_MacWindow_createWindow0
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_createWindow0
(JNIEnv *env, jobject jthis, jlong parent, jint x, jint y, jint w, jint h, jboolean opaque, jboolean fullscreen, jint styleMask,
jint bufferingType, jint screen_idx, jlong jview)
{
@@ -602,8 +615,10 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_MacWindow_createWindow0
// Remove animations for child windows
if(NULL != parentWindow) {
NS_DURING
- // Available >= 10.7 - Removes default animations
- [myWindow setAnimationBehavior: NSWindowAnimationBehaviorNone];
+ if ( [myWindow respondsToSelector:@selector(setAnimationBehavior:)] ) {
+ // Available >= 10.7 - Removes default animations
+ [myWindow setAnimationBehavior: NSWindowAnimationBehaviorNone];
+ }
NS_HANDLER
NS_ENDHANDLER
}
@@ -658,8 +673,12 @@ NS_ENDHANDLER
NS_DURING
// concurrent view rendering
// Available >= 10.6 - Makes the menubar disapear
- [myWindow setAllowsConcurrentViewDrawing: YES];
- [myView setCanDrawConcurrently: YES];
+ if ( [myWindow respondsToSelector:@selector(setAllowsConcurrentViewDrawing:)] ) {
+ [myWindow setAllowsConcurrentViewDrawing: YES];
+ }
+ if ( [myView respondsToSelector:@selector(setCanDrawConcurrently:)] ) {
+ [myView setCanDrawConcurrently: YES];
+ }
NS_HANDLER
NS_ENDHANDLER
@@ -669,7 +688,9 @@ NS_ENDHANDLER
NS_DURING
// Available >= 10.5 - Makes the menubar disapear
if(fullscreen) {
- [myView enterFullScreenMode: myScreen withOptions:NULL];
+ if ( [myView respondsToSelector:@selector(enterFullScreenMode:withOptions:)] ) {
+ [myView enterFullScreenMode: myScreen withOptions:NULL];
+ }
}
NS_HANDLER
NS_ENDHANDLER
@@ -698,11 +719,11 @@ NS_ENDHANDLER
/*
- * Class: jogamp_newt_driver_macosx_MacWindow
+ * Class: jogamp_newt_driver_macosx_WindowDriver
* Method: close0
* Signature: (J)V
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_close0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_close0
(JNIEnv *env, jobject unused, jlong window)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
@@ -730,7 +751,13 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_close0
NS_DURING
if(NULL!=mView) {
// Available >= 10.5 - Makes the menubar disapear
- if([mView isInFullScreenMode]) {
+ BOOL iifs;
+ if ( [mView respondsToSelector:@selector(isInFullScreenMode)] ) {
+ iifs = [mView isInFullScreenMode];
+ } else {
+ iifs = NO;
+ }
+ if(iifs && [mView respondsToSelector:@selector(exitFullScreenModeWithOptions:)] ) {
[mView exitFullScreenModeWithOptions: NULL];
}
// Note: mWin's release will also release it's mView!
@@ -761,11 +788,11 @@ NS_ENDHANDLER
}
/*
- * Class: Java_jogamp_newt_driver_macosx_MacWindow
+ * Class: Java_jogamp_newt_driver_macosx_WindowDriver
* Method: lockSurface0
* Signature: (J)Z
*/
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacWindow_lockSurface0
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_lockSurface0
(JNIEnv *env, jclass clazz, jlong window)
{
NewtMacWindow *mWin = (NewtMacWindow*) ((intptr_t) window);
@@ -779,11 +806,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacWindow_lockSurface0
}
/*
- * Class: Java_jogamp_newt_driver_macosx_MacWindow
+ * Class: Java_jogamp_newt_driver_macosx_WindowDriver
* Method: unlockSurface0
* Signature: (J)V
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_unlockSurface0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_unlockSurface0
(JNIEnv *env, jclass clazz, jlong window)
{
NewtMacWindow *mWin = (NewtMacWindow*) ((intptr_t) window);
@@ -794,11 +821,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_unlockSurface0
}
/*
- * Class: jogamp_newt_driver_macosx_MacWindow
+ * Class: jogamp_newt_driver_macosx_WindowDriver
* Method: requestFocus0
* Signature: (JZ)V
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_requestFocus0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_requestFocus0
(JNIEnv *env, jobject window, jlong w, jboolean force)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
@@ -819,11 +846,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_requestFocus0
}
/*
- * Class: jogamp_newt_driver_macosx_MacWindow
+ * Class: jogamp_newt_driver_macosx_WindowDriver
* Method: resignFocus0
* Signature: (J)V
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_resignFocus0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_resignFocus0
(JNIEnv *env, jobject window, jlong w)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
@@ -846,11 +873,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_resignFocus0
}
/*
- * Class: jogamp_newt_driver_macosx_MacWindow
+ * Class: jogamp_newt_driver_macosx_WindowDriver
* Method: orderFront0
* Signature: (J)V
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_orderFront0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_orderFront0
(JNIEnv *env, jobject unused, jlong window)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
@@ -866,11 +893,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_orderFront0
}
/*
- * Class: jogamp_newt_driver_macosx_MacWindow
+ * Class: jogamp_newt_driver_macosx_WindowDriver
* Method: orderOut
* Signature: (J)V
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_orderOut0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_orderOut0
(JNIEnv *env, jobject unused, jlong window)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
@@ -891,11 +918,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_orderOut0
}
/*
- * Class: jogamp_newt_driver_macosx_MacWindow
+ * Class: jogamp_newt_driver_macosx_WindowDriver
* Method: setTitle0
* Signature: (JLjava/lang/String;)V
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_setTitle0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setTitle0
(JNIEnv *env, jobject unused, jlong window, jstring title)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
@@ -913,11 +940,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_setTitle0
}
/*
- * Class: jogamp_newt_driver_macosx_MacWindow
+ * Class: jogamp_newt_driver_macosx_WindowDriver
* Method: contentView
* Signature: (J)J
*/
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_MacWindow_contentView0
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_contentView0
(JNIEnv *env, jobject unused, jlong window)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
@@ -934,11 +961,11 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_MacWindow_contentView0
}
/*
- * Class: jogamp_newt_driver_macosx_MacWindow
+ * Class: jogamp_newt_driver_macosx_WindowDriver
* Method: changeContentView
* Signature: (J)J
*/
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_MacWindow_changeContentView0
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_changeContentView0
(JNIEnv *env, jobject jthis, jlong parentWindowOrView, jlong window, jlong jview)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
@@ -977,11 +1004,11 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_MacWindow_changeContentVi
}
/*
- * Class: jogamp_newt_driver_macosx_MacWindow
+ * Class: jogamp_newt_driver_macosx_WindowDriver
* Method: setContentSize
* Signature: (JII)V
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_setContentSize0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setContentSize0
(JNIEnv *env, jobject unused, jlong window, jint w, jint h)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
@@ -998,11 +1025,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_setContentSize0
}
/*
- * Class: jogamp_newt_driver_macosx_MacWindow
+ * Class: jogamp_newt_driver_macosx_WindowDriver
* Method: setFrameTopLeftPoint
* Signature: (JJII)V
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_setFrameTopLeftPoint0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setFrameTopLeftPoint0
(JNIEnv *env, jobject unused, jlong parent, jlong window, jint x, jint y)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
@@ -1027,11 +1054,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_setFrameTopLeftP
}
/*
- * Class: jogamp_newt_driver_macosx_MacWindow
+ * Class: jogamp_newt_driver_macosx_WindowDriver
* Method: setAlwaysOnTop0
* Signature: (JZ)V
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_setAlwaysOnTop0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setAlwaysOnTop0
(JNIEnv *env, jobject unused, jlong window, jboolean atop)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
@@ -1051,11 +1078,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_setAlwaysOnTop0
}
/*
- * Class: jogamp_newt_driver_macosx_MacWindow
+ * Class: jogamp_newt_driver_macosx_WindowDriver
* Method: getLocationOnScreen0
* Signature: (JII)Ljavax/media/nativewindow/util/Point;
*/
-JNIEXPORT jobject JNICALL Java_jogamp_newt_driver_macosx_MacWindow_getLocationOnScreen0
+JNIEXPORT jobject JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_getLocationOnScreen0
(JNIEnv *env, jclass unused, jlong win, jint src_x, jint src_y)
{
NSObject *nsObj = (NSObject*) ((intptr_t) win);
@@ -1072,11 +1099,11 @@ JNIEXPORT jobject JNICALL Java_jogamp_newt_driver_macosx_MacWindow_getLocationOn
}
/*
- * Class: Java_jogamp_newt_driver_macosx_MacWindow
+ * Class: Java_jogamp_newt_driver_macosx_WindowDriver
* Method: setPointerVisible0
* Signature: (JZ)Z
*/
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacWindow_setPointerVisible0
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setPointerVisible0
(JNIEnv *env, jclass clazz, jlong window, jboolean hasFocus, jboolean mouseVisible)
{
NewtMacWindow *mWin = (NewtMacWindow*) ((intptr_t) window);
@@ -1086,11 +1113,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacWindow_setPointerVi
}
/*
- * Class: Java_jogamp_newt_driver_macosx_MacWindow
+ * Class: Java_jogamp_newt_driver_macosx_WindowDriver
* Method: confinePointer0
* Signature: (JZ)Z
*/
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacWindow_confinePointer0
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_confinePointer0
(JNIEnv *env, jclass clazz, jlong window, jboolean confine)
{
NewtMacWindow *mWin = (NewtMacWindow*) ((intptr_t) window);
@@ -1099,11 +1126,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacWindow_confinePoint
}
/*
- * Class: Java_jogamp_newt_driver_macosx_MacWindow
+ * Class: Java_jogamp_newt_driver_macosx_WindowDriver
* Method: warpPointer0
* Signature: (JJII)V
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_warpPointer0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_warpPointer0
(JNIEnv *env, jclass clazz, jlong window, jint x, jint y)
{
NewtMacWindow *mWin = (NewtMacWindow*) ((intptr_t) window);
diff --git a/src/newt/native/NewtMacWindow.h b/src/newt/native/NewtMacWindow.h
index c0912ad..29b646f 100644
--- a/src/newt/native/NewtMacWindow.h
+++ b/src/newt/native/NewtMacWindow.h
@@ -111,6 +111,7 @@
BOOL mouseInside;
BOOL cursorIsHidden;
BOOL realized;
+ BOOL modsDown[4]; // shift, ctrl, alt/option, win/command
NSPoint lastInsideMousePosition;
@public
int cachedInsets[4]; // l, r, t, b
@@ -145,6 +146,7 @@
- (void) setMousePosition:(NSPoint)p;
- (void) sendKeyEvent: (NSEvent*) event eventType: (jint) evType;
+- (void) sendKeyEvent: (jint) keyCode characters: (NSString*) chars modifiers: (NSUInteger)mods eventType: (jint) evType;
- (void) sendMouseEvent: (NSEvent*) event eventType: (jint) evType;
- (void) focusChanged: (BOOL) gained;
@@ -157,6 +159,8 @@
- (void) windowDidResignKey: (NSNotification *) notification;
- (void) keyDown: (NSEvent*) theEvent;
- (void) keyUp: (NSEvent*) theEvent;
+- (void) handleFlagsChanged:(int) keyMask keyIndex: (int) keyIdx keyCode: (int) keyCode modifiers: (NSUInteger) mods;
+- (void) flagsChanged: (NSEvent *) theEvent;
- (void) mouseEntered: (NSEvent*) theEvent;
- (void) mouseExited: (NSEvent*) theEvent;
- (void) mouseMoved: (NSEvent*) theEvent;
diff --git a/src/newt/native/NewtMacWindow.m b/src/newt/native/NewtMacWindow.m
index b58b99e..b89b5c2 100644
--- a/src/newt/native/NewtMacWindow.m
+++ b/src/newt/native/NewtMacWindow.m
@@ -368,6 +368,10 @@ static jmethodID windowRepaintID = NULL;
cachedInsets[1] = 0; // r
cachedInsets[2] = 0; // t
cachedInsets[3] = 0; // b
+ modsDown[0] = NO; // shift
+ modsDown[1] = NO; // ctrl
+ modsDown[2] = NO; // alt
+ modsDown[3] = NO; // win
mouseConfined = NO;
mouseVisible = YES;
mouseInside = NO;
@@ -597,6 +601,14 @@ static jint mods2JavaMods(NSUInteger mods)
- (void) sendKeyEvent: (NSEvent*) event eventType: (jint) evType
{
+ jint keyCode = (jint) [event keyCode];
+ NSString* chars = [event charactersIgnoringModifiers];
+ NSUInteger mods = [event modifierFlags];
+ [self sendKeyEvent: keyCode characters: chars modifiers: mods eventType: evType];
+}
+
+- (void) sendKeyEvent: (jint) keyCode characters: (NSString*) chars modifiers: (NSUInteger)mods eventType: (jint) evType
+{
NSView* nsview = [self contentView];
if( ! [nsview isMemberOfClass:[NewtView class]] ) {
return;
@@ -616,16 +628,30 @@ static jint mods2JavaMods(NSUInteger mods)
}
int i;
- jint keyCode = (jint) [event keyCode];
- NSString* chars = [event charactersIgnoringModifiers];
- int len = [chars length];
- jint javaMods = mods2JavaMods([event modifierFlags]);
-
- for (i = 0; i < len; i++) {
- // Note: the key code in the NSEvent does not map to anything we can use
- jchar keyChar = (jchar) [chars characterAtIndex: i];
+ int len = NULL != chars ? [chars length] : 0;
+ jint javaMods = mods2JavaMods(mods);
+
+ if(len > 0) {
+ // printable chars
+ for (i = 0; i < len; i++) {
+ // Note: the key code in the NSEvent does not map to anything we can use
+ jchar keyChar = (jchar) [chars characterAtIndex: i];
+
+ DBG_PRINT("sendKeyEvent: %d/%d char 0x%X, code 0x%X\n", i, len, (int)keyChar, (int)keyCode);
+
+ #ifdef USE_SENDIO_DIRECT
+ (*env)->CallVoidMethod(env, javaWindowObject, sendKeyEventID,
+ evType, javaMods, keyCode, keyChar);
+ #else
+ (*env)->CallVoidMethod(env, javaWindowObject, enqueueKeyEventID, JNI_FALSE,
+ evType, javaMods, keyCode, keyChar);
+ #endif
+ }
+ } else {
+ // non-printable chars
+ jchar keyChar = (jchar) -1;
- DBG_PRINT("sendKeyEvent: %d/%d char 0x%X, code 0x%X\n", i, len, (int)keyChar, (int)keyCode);
+ DBG_PRINT("sendKeyEvent: code 0x%X\n", (int)keyCode);
#ifdef USE_SENDIO_DIRECT
(*env)->CallVoidMethod(env, javaWindowObject, sendKeyEventID,
@@ -805,6 +831,35 @@ static jint mods2JavaMods(NSUInteger mods)
[self sendKeyEvent: theEvent eventType: EVENT_KEY_TYPED];
}
+#define kVK_Shift 0x38
+#define kVK_Option 0x3A
+#define kVK_Control 0x3B
+#define kVK_Command 0x37
+
+- (void) handleFlagsChanged:(int) keyMask keyIndex: (int) keyIdx keyCode: (int) keyCode modifiers: (NSUInteger) mods
+{
+ if ( NO == modsDown[keyIdx] && 0 != ( mods & keyMask ) ) {
+ modsDown[keyIdx] = YES;
+ [self sendKeyEvent: keyCode characters: NULL modifiers: mods|keyMask eventType: EVENT_KEY_PRESSED];
+ } else if ( YES == modsDown[keyIdx] && 0 == ( mods & keyMask ) ) {
+ modsDown[keyIdx] = NO;
+ [self sendKeyEvent: keyCode characters: NULL modifiers: mods|keyMask eventType: EVENT_KEY_RELEASED];
+ [self sendKeyEvent: keyCode characters: NULL modifiers: mods|keyMask eventType: EVENT_KEY_TYPED];
+ }
+}
+
+- (void) flagsChanged:(NSEvent *) theEvent
+{
+ NSUInteger mods = [theEvent modifierFlags];
+
+ // BOOL modsDown[4]; // shift, ctrl, alt/option, win/command
+
+ [self handleFlagsChanged: NSShiftKeyMask keyIndex: 0 keyCode: kVK_Shift modifiers: mods];
+ [self handleFlagsChanged: NSControlKeyMask keyIndex: 1 keyCode: kVK_Control modifiers: mods];
+ [self handleFlagsChanged: NSAlternateKeyMask keyIndex: 2 keyCode: kVK_Option modifiers: mods];
+ [self handleFlagsChanged: NSCommandKeyMask keyIndex: 3 keyCode: kVK_Command modifiers: mods];
+}
+
- (void) mouseEntered: (NSEvent*) theEvent
{
DBG_PRINT( "mouseEntered: confined %d, visible %d\n", mouseConfined, mouseVisible);
diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c
index 6d9c04d..e3d5cff 100644
--- a/src/newt/native/WindowsWindow.c
+++ b/src/newt/native/WindowsWindow.c
@@ -81,9 +81,9 @@
#define DISPLAY_DEVICE_ACTIVE 0x00000001
#endif
-#include "jogamp_newt_driver_windows_WindowsDisplay.h"
-#include "jogamp_newt_driver_windows_WindowsScreen.h"
-#include "jogamp_newt_driver_windows_WindowsWindow.h"
+#include "jogamp_newt_driver_windows_DisplayDriver.h"
+#include "jogamp_newt_driver_windows_ScreenDriver.h"
+#include "jogamp_newt_driver_windows_WindowDriver.h"
#include "Window.h"
#include "MouseEvent.h"
@@ -463,87 +463,108 @@ static void BuildDynamicKeyMapTable()
} // for each VK_OEM_*
}
-static jint GetModifiers() {
+static jint GetModifiers(BOOL altKeyFlagged, UINT jkey) {
jint modifiers = 0;
// have to do &0xFFFF to avoid runtime assert caused by compiling with
// /RTCcsu
- if (HIBYTE((GetKeyState(VK_CONTROL) & 0xFFFF)) != 0) {
+ if ( HIBYTE((GetKeyState(VK_CONTROL) & 0xFFFF)) != 0 || J_VK_CONTROL == jkey ) {
modifiers |= EVENT_CTRL_MASK;
}
- if (HIBYTE((GetKeyState(VK_SHIFT) & 0xFFFF)) != 0) {
+ if ( HIBYTE((GetKeyState(VK_SHIFT) & 0xFFFF)) != 0 || J_VK_SHIFT == jkey ) {
modifiers |= EVENT_SHIFT_MASK;
}
- if (HIBYTE((GetKeyState(VK_MENU) & 0xFFFF)) != 0) {
+ if ( altKeyFlagged || HIBYTE((GetKeyState(VK_MENU) & 0xFFFF)) != 0 || J_VK_ALT == jkey ) {
modifiers |= EVENT_ALT_MASK;
}
- if (HIBYTE((GetKeyState(VK_LBUTTON) & 0xFFFF)) != 0) {
+ if ( HIBYTE((GetKeyState(VK_LBUTTON) & 0xFFFF)) != 0 ) {
modifiers |= EVENT_BUTTON1_MASK;
}
- if (HIBYTE((GetKeyState(VK_MBUTTON) & 0xFFFF)) != 0) {
+ if ( HIBYTE((GetKeyState(VK_MBUTTON) & 0xFFFF)) != 0 ) {
modifiers |= EVENT_BUTTON2_MASK;
}
- if (HIBYTE((GetKeyState(VK_RBUTTON) & 0xFFFF)) != 0) {
+ if ( HIBYTE((GetKeyState(VK_RBUTTON) & 0xFFFF)) != 0 ) {
modifiers |= EVENT_BUTTON3_MASK;
}
return modifiers;
}
-static int WmChar(JNIEnv *env, jobject window, UINT character, UINT repCnt,
- UINT flags, BOOL system)
-{
+static BOOL IsAltKeyDown(BYTE flags, BOOL system) {
// The Alt modifier is reported in the 29th bit of the lParam,
- // i.e., it is the 13th bit of `flags' (which is HIWORD(lParam)).
- BOOL alt_is_down = (flags & (1<<13)) != 0;
- if (system && alt_is_down) {
- if (character == VK_SPACE) {
- return 1;
- }
- }
-
- if (character == VK_RETURN) {
- character = J_VK_ENTER;
- }
- (*env)->CallVoidMethod(env, window, sendKeyEventID,
- (jint) EVENT_KEY_TYPED,
- GetModifiers(),
- (jint) -1,
- (jchar) character);
- return 1;
+ // i.e., it is the 5th bit of `flags' (which is HIBYTE(HIWORD(lParam))).
+ return system && ( flags & (1<<5) ) != 0;
}
-UINT WindowsKeyToJavaKey(UINT windowsKey, UINT modifiers)
+UINT WindowsKeyToJavaKey(UINT windowsKey)
{
- int i, j;
+ int i, j, javaKey = J_VK_UNDEFINED;
// for the general case, use a bi-directional table
for (i = 0; keyMapTable[i].windowsKey != 0; i++) {
if (keyMapTable[i].windowsKey == windowsKey) {
- return keyMapTable[i].javaKey;
+ javaKey = keyMapTable[i].javaKey;
}
}
- for (j = 0; dynamicKeyMapTable[j].windowsKey != 0; j++) {
- if (dynamicKeyMapTable[j].windowsKey == windowsKey) {
- if (dynamicKeyMapTable[j].javaKey != J_VK_UNDEFINED) {
- return dynamicKeyMapTable[j].javaKey;
- } else {
- break;
+ if( J_VK_UNDEFINED == javaKey ) {
+ for (j = 0; dynamicKeyMapTable[j].windowsKey != 0; j++) {
+ if (dynamicKeyMapTable[j].windowsKey == windowsKey) {
+ if (dynamicKeyMapTable[j].javaKey != J_VK_UNDEFINED) {
+ javaKey = dynamicKeyMapTable[j].javaKey;
+ } else {
+ break;
+ }
}
}
}
- return J_VK_UNDEFINED;
+#ifdef DEBUG_KEYS
+ STD_PRINT("*** WindowsWindow: WindowsKeyToJavaKey 0x%X -> 0x%X\n", windowsKey, javaKey);
+#endif
+ return javaKey;
}
-static int WmKeyDown(JNIEnv *env, jobject window, UINT wkey, UINT repCnt,
- UINT flags, BOOL system)
-{
- UINT modifiers = 0, jkey = 0, character = -1;
+#ifndef MAPVK_VSC_TO_VK
+ #define MAPVK_VSC_TO_VK 1
+#endif
+#ifndef MAPVK_VK_TO_CHAR
+ #define MAPVK_VK_TO_CHAR 2
+#endif
+
+static UINT WmVKey2ShiftedChar(UINT wkey, UINT modifiers) {
+ UINT c = MapVirtualKey(wkey, MAPVK_VK_TO_CHAR);
+ if( 0 != ( modifiers & EVENT_SHIFT_MASK ) ) {
+ return islower(c) ? toupper(c) : c;
+ }
+ return isupper(c) ? tolower(c) : c;
+}
+
+static int WmChar(JNIEnv *env, jobject window, UINT character, WORD repCnt, BYTE scanCode, BYTE flags, BOOL system) {
+ UINT modifiers = 0, jkey = 0, wkey = 0;
+
+ wkey = MapVirtualKey(scanCode, MAPVK_VSC_TO_VK);
+ jkey = WindowsKeyToJavaKey(wkey);
+ modifiers = GetModifiers( IsAltKeyDown(flags, system), 0 );
+
+ if (character == VK_RETURN) {
+ character = J_VK_ENTER;
+ }
+
+ (*env)->CallVoidMethod(env, window, sendKeyEventID,
+ (jint) EVENT_KEY_TYPED,
+ modifiers,
+ (jint) jkey,
+ (jchar) character);
+ return 1;
+}
+
+static int WmKeyDown(JNIEnv *env, jobject window, UINT wkey, WORD repCnt, BYTE scanCode, BYTE flags, BOOL system) {
+ UINT modifiers = 0, jkey = 0, character = 0;
if (wkey == VK_PROCESSKEY) {
return 1;
}
- modifiers = GetModifiers();
- jkey = WindowsKeyToJavaKey(wkey, modifiers);
+ jkey = WindowsKeyToJavaKey(wkey);
+ modifiers = GetModifiers( IsAltKeyDown(flags, system), jkey );
+ character = WmVKey2ShiftedChar(wkey, modifiers);
/*
character = WindowsKeyToJavaChar(wkey, modifiers, SAVE);
@@ -562,24 +583,24 @@ static int WmKeyDown(JNIEnv *env, jobject window, UINT wkey, UINT repCnt,
if (jkey == J_VK_DELETE) {
(*env)->CallVoidMethod(env, window, sendKeyEventID,
(jint) EVENT_KEY_TYPED,
- GetModifiers(),
- (jint) -1,
+ modifiers,
+ (jint) 0,
(jchar) '\177');
}
return 0;
}
-static int WmKeyUp(JNIEnv *env, jobject window, UINT wkey, UINT repCnt,
- UINT flags, BOOL system)
-{
- UINT modifiers = 0, jkey = 0, character = -1;
+static int WmKeyUp(JNIEnv *env, jobject window, UINT wkey, WORD repCnt, BYTE scanCode, BYTE flags, BOOL system) {
+ UINT modifiers = 0, jkey = 0, character = 0;
if (wkey == VK_PROCESSKEY) {
return 1;
}
- modifiers = GetModifiers();
- jkey = WindowsKeyToJavaKey(wkey, modifiers);
+ jkey = WindowsKeyToJavaKey(wkey);
+ modifiers = GetModifiers( IsAltKeyDown(flags, system), jkey );
+ character = WmVKey2ShiftedChar(wkey, modifiers);
+
/*
character = WindowsKeyToJavaChar(wkey, modifiers, SAVE);
*/
@@ -595,20 +616,25 @@ static int WmKeyUp(JNIEnv *env, jobject window, UINT wkey, UINT repCnt,
static void NewtWindows_requestFocus (JNIEnv *env, jobject window, HWND hwnd, jboolean force) {
HWND pHwnd, current;
+ BOOL isEnabled = IsWindowEnabled(hwnd);
pHwnd = GetParent(hwnd);
current = GetFocus();
- DBG_PRINT("*** WindowsWindow: requestFocus.S parent %p, window %p, isCurrent %d\n",
- (void*) pHwnd, (void*)hwnd, current==hwnd);
+ DBG_PRINT("*** WindowsWindow: requestFocus.S force %d, parent %p, window %p, isEnabled %d, isCurrent %d\n",
+ (int)force, (void*)pHwnd, (void*)hwnd, isEnabled, current==hwnd);
- if( JNI_TRUE==force || current!=hwnd) {
+ if( JNI_TRUE==force || current!=hwnd || !isEnabled ) {
UINT flags = SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
+ if(!isEnabled) {
+ EnableWindow(hwnd, TRUE);
+ }
SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, flags);
SetForegroundWindow(hwnd); // Slightly Higher Priority
- SetFocus(hwnd);// Sets Keyboard Focus To Window
+ SetFocus(hwnd);// Sets Keyboard Focus To Window (activates parent window if exist, or this window)
if(NULL!=pHwnd) {
SetActiveWindow(hwnd);
}
- DBG_PRINT("*** WindowsWindow: requestFocus.X1\n");
+ current = GetFocus();
+ DBG_PRINT("*** WindowsWindow: requestFocus.X1 isCurrent %d\n", current==hwnd);
}
DBG_PRINT("*** WindowsWindow: requestFocus.XX\n");
}
@@ -770,21 +796,15 @@ static void WmSize(JNIEnv *env, jobject window, HWND wnd, UINT type)
(*env)->CallVoidMethod(env, window, sizeChangedID, JNI_FALSE, w, h, JNI_FALSE);
}
-static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
- WPARAM wParam, LPARAM lParam)
-{
+static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lParam) {
LRESULT res = 0;
int useDefWindowProc = 0;
JNIEnv *env = NULL;
jobject window = NULL;
BOOL isKeyDown = FALSE;
WindowUserData * wud;
-
-#ifdef DEBUG_KEYS
- if ( WM_KEYDOWN == message ) {
- STD_PRINT("*** WindowsWindow: wndProc window %p, 0x%X %d/%d\n", wnd, message, (int)LOWORD(lParam), (int)HIWORD(lParam));
- }
-#endif
+ WORD repCnt;
+ BYTE scanCode, flags;
#if !defined(__MINGW64__) && ( defined(UNDER_CE) || _MSC_VER <= 1200 )
wud = (WindowUserData *) GetWindowLong(wnd, GWL_USERDATA);
@@ -826,26 +846,57 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
break;
case WM_SYSCHAR:
- useDefWindowProc = WmChar(env, window, wParam,
- LOWORD(lParam), HIWORD(lParam), FALSE);
+ repCnt = HIWORD(lParam); scanCode = LOBYTE(repCnt); flags = HIBYTE(repCnt);
+ repCnt = LOWORD(lParam);
+#ifdef DEBUG_KEYS
+ STD_PRINT("*** WindowsWindow: windProc WM_SYSCHAR sending window %p -> %p, char 0x%X, repCnt %d, scanCode 0x%X, flags 0x%X\n", wnd, window, (int)wParam, (int)repCnt, (int)scanCode, (int)flags);
+#endif
+ useDefWindowProc = WmChar(env, window, wParam, repCnt, scanCode, flags, TRUE);
+ break;
+
+ case WM_SYSKEYDOWN:
+ repCnt = HIWORD(lParam); scanCode = LOBYTE(repCnt); flags = HIBYTE(repCnt);
+ repCnt = LOWORD(lParam);
+#ifdef DEBUG_KEYS
+ STD_PRINT("*** WindowsWindow: windProc WM_SYSKEYDOWN sending window %p -> %p, code 0x%X, repCnt %d, scanCode 0x%X, flags 0x%X\n", wnd, window, (int)wParam, (int)repCnt, (int)scanCode, (int)flags);
+#endif
+ useDefWindowProc = WmKeyDown(env, window, wParam, repCnt, scanCode, flags, TRUE);
+ break;
+
+ case WM_SYSKEYUP:
+ repCnt = HIWORD(lParam); scanCode = LOBYTE(repCnt); flags = HIBYTE(repCnt);
+ repCnt = LOWORD(lParam);
+#ifdef DEBUG_KEYS
+ STD_PRINT("*** WindowsWindow: windProc WM_SYSKEYUP sending window %p -> %p, code 0x%X, repCnt %d, scanCode 0x%X, flags 0x%X\n", wnd, window, (int)wParam, (int)repCnt, (int)scanCode, (int)flags);
+#endif
+ useDefWindowProc = WmKeyUp(env, window, wParam, repCnt, scanCode, flags, TRUE);
break;
case WM_CHAR:
- useDefWindowProc = WmChar(env, window, wParam,
- LOWORD(lParam), HIWORD(lParam), TRUE);
+ repCnt = HIWORD(lParam); scanCode = LOBYTE(repCnt); flags = HIBYTE(repCnt);
+ repCnt = LOWORD(lParam);
+#ifdef DEBUG_KEYS
+ STD_PRINT("*** WindowsWindow: windProc WM_CHAR sending window %p -> %p, char 0x%X, repCnt %d, scanCode 0x%X, flags 0x%X\n", wnd, window, (int)wParam, (int)repCnt, (int)scanCode, (int)flags);
+#endif
+ useDefWindowProc = WmChar(env, window, wParam, repCnt, scanCode, flags, FALSE);
break;
case WM_KEYDOWN:
+ repCnt = HIWORD(lParam); scanCode = LOBYTE(repCnt); flags = HIBYTE(repCnt);
+ repCnt = LOWORD(lParam);
#ifdef DEBUG_KEYS
- STD_PRINT("*** WindowsWindow: windProc sending window %p -> %p, 0x%X %d/%d\n", wnd, window, message, (int)LOWORD(lParam), (int)HIWORD(lParam));
+ STD_PRINT("*** WindowsWindow: windProc WM_KEYDOWN sending window %p -> %p, code 0x%X, repCnt %d, scanCode 0x%X, flags 0x%X\n", wnd, window, (int)wParam, (int)repCnt, (int)scanCode, (int)flags);
#endif
- useDefWindowProc = WmKeyDown(env, window, wParam,
- LOWORD(lParam), HIWORD(lParam), FALSE);
+ useDefWindowProc = WmKeyDown(env, window, wParam, repCnt, scanCode, flags, FALSE);
break;
case WM_KEYUP:
- useDefWindowProc = WmKeyUp(env, window, wParam,
- LOWORD(lParam), HIWORD(lParam), FALSE);
+ repCnt = HIWORD(lParam); scanCode = LOBYTE(repCnt); flags = HIBYTE(repCnt);
+ repCnt = LOWORD(lParam);
+#ifdef DEBUG_KEYS
+ STD_PRINT("*** WindowsWindow: windProc WM_KEYUP sending window %p -> %p, code 0x%X, repCnt %d, scanCode 0x%X, flags 0x%X\n", wnd, window, (int)wParam, (int)repCnt, (int)scanCode, (int)flags);
+#endif
+ useDefWindowProc = WmKeyUp(env, window, wParam, repCnt, scanCode, flags, FALSE);
break;
case WM_SIZE:
@@ -868,7 +919,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
(*env)->CallVoidMethod(env, window, requestFocusID, JNI_FALSE);
(*env)->CallVoidMethod(env, window, sendMouseEventID,
(jint) EVENT_MOUSE_PRESSED,
- GetModifiers(),
+ GetModifiers( FALSE, 0 ),
(jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
(jint) 1, (jint) 0);
useDefWindowProc = 1;
@@ -877,7 +928,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
case WM_LBUTTONUP:
(*env)->CallVoidMethod(env, window, sendMouseEventID,
(jint) EVENT_MOUSE_RELEASED,
- GetModifiers(),
+ GetModifiers( FALSE, 0 ),
(jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
(jint) 1, (jint) 0);
useDefWindowProc = 1;
@@ -888,7 +939,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
(*env)->CallVoidMethod(env, window, requestFocusID, JNI_FALSE);
(*env)->CallVoidMethod(env, window, sendMouseEventID,
(jint) EVENT_MOUSE_PRESSED,
- GetModifiers(),
+ GetModifiers( FALSE, 0 ),
(jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
(jint) 2, (jint) 0);
useDefWindowProc = 1;
@@ -897,7 +948,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
case WM_MBUTTONUP:
(*env)->CallVoidMethod(env, window, sendMouseEventID,
(jint) EVENT_MOUSE_RELEASED,
- GetModifiers(),
+ GetModifiers( FALSE, 0 ),
(jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
(jint) 2, (jint) 0);
useDefWindowProc = 1;
@@ -908,7 +959,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
(*env)->CallVoidMethod(env, window, requestFocusID, JNI_FALSE);
(*env)->CallVoidMethod(env, window, sendMouseEventID,
(jint) EVENT_MOUSE_PRESSED,
- GetModifiers(),
+ GetModifiers( FALSE, 0 ),
(jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
(jint) 3, (jint) 0);
useDefWindowProc = 1;
@@ -917,7 +968,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
case WM_RBUTTONUP:
(*env)->CallVoidMethod(env, window, sendMouseEventID,
(jint) EVENT_MOUSE_RELEASED,
- GetModifiers(),
+ GetModifiers( FALSE, 0 ),
(jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
(jint) 3, (jint) 0);
useDefWindowProc = 1;
@@ -926,7 +977,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
case WM_MOUSEMOVE:
(*env)->CallVoidMethod(env, window, sendMouseEventID,
(jint) EVENT_MOUSE_MOVED,
- GetModifiers(),
+ GetModifiers( FALSE, 0 ),
(jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
(jint) 0, (jint) 0);
useDefWindowProc = 1;
@@ -951,7 +1002,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
ScreenToClient(wnd, &eventPt);
(*env)->CallVoidMethod(env, window, sendMouseEventID,
(jint) EVENT_MOUSE_WHEEL_MOVED,
- GetModifiers(),
+ GetModifiers( FALSE, 0 ),
(jint) eventPt.x, (jint) eventPt.y,
(jint) 1, (jint) (GET_WHEEL_DELTA_WPARAM(wParam)/120.0f));
useDefWindowProc = 1;
@@ -959,11 +1010,13 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
}
case WM_SETFOCUS:
+ DBG_PRINT("*** WindowsWindow: WM_SETFOCUS window %p, lost %p\n", wnd, (HWND)wParam);
(*env)->CallVoidMethod(env, window, focusChangedID, JNI_FALSE, JNI_TRUE);
useDefWindowProc = 1;
break;
case WM_KILLFOCUS:
+ DBG_PRINT("*** WindowsWindow: WM_KILLFOCUS window %p, received %p\n", wnd, (HWND)wParam);
(*env)->CallVoidMethod(env, window, focusChangedID, JNI_FALSE, JNI_FALSE);
useDefWindowProc = 1;
break;
@@ -1011,11 +1064,11 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
}
/*
- * Class: jogamp_newt_driver_windows_WindowsDisplay
+ * Class: jogamp_newt_driver_windows_DisplayDriver
* Method: DispatchMessages
* Signature: ()V
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsDisplay_DispatchMessages0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_DisplayDriver_DispatchMessages0
(JNIEnv *env, jclass clazz)
{
int i = 0;
@@ -1028,11 +1081,6 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsDisplay_DispatchMe
// DBG_PRINT("*** WindowsWindow.DispatchMessages0: thread 0x%X - gotOne %d\n", (int)GetCurrentThreadId(), (int)gotOne);
if (gotOne) {
++i;
-#ifdef DEBUG_KEYS
- if(WM_KEYDOWN == msg.message) {
- STD_PRINT("*** WindowsWindow: DispatchMessages window %p, 0x%X %d/%d\n", msg.hwnd, msg.message, (int)LOWORD(msg.lParam), (int)HIWORD(msg.lParam));
- }
-#endif
TranslateMessage(&msg);
DispatchMessage(&msg);
}
@@ -1040,11 +1088,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsDisplay_DispatchMe
}
/*
- * Class: jogamp_newt_driver_windows_WindowsScreen
+ * Class: jogamp_newt_driver_windows_ScreenDriver
* Method: getOriginX0
* Signature: (I)I
*/
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_getOriginX0
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getOriginX0
(JNIEnv *env, jobject obj, jint scrn_idx)
{
if( GetSystemMetrics( SM_CMONITORS) > 1) {
@@ -1055,11 +1103,11 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_getOriginX0
}
/*
- * Class: jogamp_newt_driver_windows_WindowsScreen
+ * Class: jogamp_newt_driver_windows_ScreenDriver
* Method: getOriginY0
* Signature: (I)I
*/
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_getOriginY0
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getOriginY0
(JNIEnv *env, jobject obj, jint scrn_idx)
{
if( GetSystemMetrics( SM_CMONITORS ) > 1) {
@@ -1070,11 +1118,11 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_getOriginY0
}
/*
- * Class: jogamp_newt_driver_windows_WindowsScreen
+ * Class: jogamp_newt_driver_windows_ScreenDriver
* Method: getWidthImpl
* Signature: (I)I
*/
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_getWidthImpl0
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getWidthImpl0
(JNIEnv *env, jobject obj, jint scrn_idx)
{
if( GetSystemMetrics( SM_CMONITORS) > 1) {
@@ -1085,11 +1133,11 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_getWidthImp
}
/*
- * Class: jogamp_newt_driver_windows_WindowsScreen
+ * Class: jogamp_newt_driver_windows_ScreenDriver
* Method: getHeightImpl
* Signature: (I)I
*/
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_getHeightImpl0
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getHeightImpl0
(JNIEnv *env, jobject obj, jint scrn_idx)
{
if( GetSystemMetrics( SM_CMONITORS ) > 1) {
@@ -1173,11 +1221,11 @@ static HDC NewtScreen_createDisplayDC(LPCTSTR displayDeviceName) {
}
/*
- * Class: jogamp_newt_driver_windows_WindowsScreen
+ * Class: jogamp_newt_driver_windows_ScreenDriver
* Method: getScreenMode0
* Signature: (II)[I
*/
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_getScreenMode0
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getScreenMode0
(JNIEnv *env, jobject obj, jint scrn_idx, jint mode_idx)
{
DISPLAY_DEVICE device;
@@ -1246,11 +1294,11 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_getScr
}
/*
- * Class: jogamp_newt_driver_windows_WindowsScreen
+ * Class: jogamp_newt_driver_windows_ScreenDriver
* Method: setScreenMode0
* Signature: (IIIIII)Z
*/
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_setScreenMode0
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_setScreenMode0
(JNIEnv *env, jobject object, jint scrn_idx, jint width, jint height, jint bits, jint rate, jint rot)
{
DISPLAY_DEVICE device;
@@ -1283,11 +1331,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_setScre
}
/*
- * Class: jogamp_newt_driver_windows_WindowsWindow
+ * Class: jogamp_newt_driver_windows_WindowDriver
* Method: initIDs0
* Signature: ()Z
*/
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_initIDs0
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowDriver_initIDs0
(JNIEnv *env, jclass clazz)
{
NewtCommon_init(env);
@@ -1324,11 +1372,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_initIDs
}
/*
- * Class: jogamp_newt_driver_windows_WindowsWindow
+ * Class: jogamp_newt_driver_windows_WindowDriver
* Method: getNewtWndProc0
* Signature: ()J
*/
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_getNewtWndProc0
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowDriver_getNewtWndProc0
(JNIEnv *env, jclass clazz)
{
return (jlong) (intptr_t) wndProc;
@@ -1366,10 +1414,10 @@ static void NewtWindow_setVisiblePosSize(HWND hwnd, BOOL atop, BOOL visible,
}
/*
- * Class: jogamp_newt_driver_windows_WindowsWindow
+ * Class: jogamp_newt_driver_windows_WindowDriver
* Method: CreateWindow
*/
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_CreateWindow0
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowDriver_CreateWindow0
(JNIEnv *env, jobject obj,
jlong hInstance, jstring jWndClassName, jstring jWndName,
jlong parent,
@@ -1473,11 +1521,11 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_CreateWind
}
/*
- * Class: jogamp_newt_driver_windows_WindowsWindow
+ * Class: jogamp_newt_driver_windows_WindowDriver
* Method: MonitorFromWindow
* Signature: (J)J
*/
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_MonitorFromWindow0
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowDriver_MonitorFromWindow0
(JNIEnv *env, jobject obj, jlong window)
{
#if (_WIN32_WINNT >= 0x0500 || _WIN32_WINDOWS >= 0x0410 || WINVER >= 0x0500) && !defined(_WIN32_WCE)
@@ -1506,11 +1554,11 @@ static jboolean NewtWindows_setFullScreen(jboolean fullscreen)
}
/*
- * Class: jogamp_newt_driver_windows_WindowsWindow
+ * Class: jogamp_newt_driver_windows_WindowDriver
* Method: reconfigureWindow0
* Signature: (JJIIIII)V
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_reconfigureWindow0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowDriver_reconfigureWindow0
(JNIEnv *env, jobject obj, jlong parent, jlong window,
jint x, jint y, jint width, jint height, jint flags)
{
@@ -1591,11 +1639,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_reconfigure
}
/*
- * Class: jogamp_newt_driver_windows_WindowsWindow
+ * Class: jogamp_newt_driver_windows_WindowDriver
* Method: setTitle
* Signature: (JLjava/lang/String;)V
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_setTitle0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowDriver_setTitle0
(JNIEnv *env, jclass clazz, jlong window, jstring title)
{
HWND hwnd = (HWND) (intptr_t) window;
@@ -1609,11 +1657,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_setTitle0
}
/*
- * Class: jogamp_newt_driver_windows_WindowsWindow
+ * Class: jogamp_newt_driver_windows_WindowDriver
* Method: requestFocus
* Signature: (JZ)V
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_requestFocus0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowDriver_requestFocus0
(JNIEnv *env, jobject obj, jlong window, jboolean force)
{
DBG_PRINT("*** WindowsWindow: RequestFocus0\n");
@@ -1621,11 +1669,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_requestFocu
}
/*
- * Class: Java_jogamp_newt_driver_windows_WindowsWindow
+ * Class: Java_jogamp_newt_driver_windows_WindowDriver
* Method: setPointerVisible0
* Signature: (JJZ)Z
*/
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_setPointerVisible0
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowDriver_setPointerVisible0
(JNIEnv *env, jclass clazz, jlong window, jboolean mouseVisible)
{
HWND hwnd = (HWND) (intptr_t) window;
@@ -1660,11 +1708,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_setPoin
}
/*
- * Class: Java_jogamp_newt_driver_windows_WindowsWindow
+ * Class: Java_jogamp_newt_driver_windows_WindowDriver
* Method: confinePointer0
* Signature: (JJZIIII)Z
*/
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_confinePointer0
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowDriver_confinePointer0
(JNIEnv *env, jclass clazz, jlong window, jboolean confine, jint l, jint t, jint r, jint b)
{
HWND hwnd = (HWND) (intptr_t) window;
@@ -1686,11 +1734,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_confine
}
/*
- * Class: Java_jogamp_newt_driver_windows_WindowsWindow
+ * Class: Java_jogamp_newt_driver_windows_WindowDriver
* Method: warpPointer0
* Signature: (JJII)V
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_warpPointer0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowDriver_warpPointer0
(JNIEnv *env, jclass clazz, jlong window, jint x, jint y)
{
DBG_PRINT( "*** WindowsWindow: warpPointer0: %d/%d\n", x, y);
@@ -1698,11 +1746,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_warpPointer
}
/*
- * Class: Java_jogamp_newt_driver_windows_WindowsWindow
+ * Class: Java_jogamp_newt_driver_windows_WindowDriver
* Method: trackPointerLeave0
* Signature: (J)V
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_trackPointerLeave0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowDriver_trackPointerLeave0
(JNIEnv *env, jclass clazz, jlong window)
{
HWND hwnd = (HWND) (intptr_t) window;
diff --git a/src/newt/native/X11Common.h b/src/newt/native/X11Common.h
index 982255b..4d1a7b5 100644
--- a/src/newt/native/X11Common.h
+++ b/src/newt/native/X11Common.h
@@ -45,9 +45,9 @@
#include <X11/extensions/Xrandr.h>
-#include "jogamp_newt_driver_x11_X11Screen.h"
-#include "jogamp_newt_driver_x11_X11Display.h"
-#include "jogamp_newt_driver_x11_X11Window.h"
+#include "jogamp_newt_driver_x11_ScreenDriver.h"
+#include "jogamp_newt_driver_x11_DisplayDriver.h"
+#include "jogamp_newt_driver_x11_WindowDriver.h"
#include "Window.h"
#include "MouseEvent.h"
@@ -70,7 +70,6 @@ extern jclass X11NewtWindowClazz;
extern jmethodID insetsChangedID;
extern jmethodID visibleChangedID;
-void NewtDisplay_x11ErrorHandlerEnable(JNIEnv * env, Display *dpy, int onoff, int quiet, int sync);
jobject getJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, jlong javaObjectAtom, Bool showWarning);
Status NewtWindows_getRootAndParent (Display *dpy, Window w, Window * root_return, Window * parent_return);
diff --git a/src/newt/native/X11Display.c b/src/newt/native/X11Display.c
index ce7d9a0..3f34a16 100644
--- a/src/newt/native/X11Display.c
+++ b/src/newt/native/X11Display.c
@@ -34,7 +34,7 @@ jclass X11NewtWindowClazz = NULL;
jmethodID insetsChangedID = NULL;
jmethodID visibleChangedID = NULL;
-static const char * const ClazzNameX11NewtWindow = "jogamp/newt/driver/x11/X11Window";
+static const char * const ClazzNameX11NewtWindow = "jogamp/newt/driver/x11/WindowDriver";
static jmethodID displayCompletedID = NULL;
@@ -52,90 +52,6 @@ static jmethodID enqueueKeyEventID = NULL;
static jmethodID sendKeyEventID = NULL;
static jmethodID requestFocusID = NULL;
-static JavaVM *jvmHandle = NULL;
-static int jvmVersion = 0;
-
-static void setupJVMVars(JNIEnv * env) {
- if(0 != (*env)->GetJavaVM(env, &jvmHandle)) {
- jvmHandle = NULL;
- }
- jvmVersion = (*env)->GetVersion(env);
-}
-
-static XErrorHandler origErrorHandler = NULL ;
-static int errorHandlerQuiet = 0 ;
-static int errorHandlerDebug = 0 ;
-static int errorHandlerThrowException = 0;
-
-static int x11ErrorHandler(Display *dpy, XErrorEvent *e)
-{
- if(!errorHandlerQuiet) {
- const char * errnoStr = strerror(errno);
- char threadName[80];
- char errCodeStr[80];
- char reqCodeStr[80];
-
- int shallBeDetached = 0;
- JNIEnv *jniEnv = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
-
- (void) NewtCommon_GetStaticStringMethod(jniEnv, X11NewtWindowClazz, getCurrentThreadNameID, threadName, sizeof(threadName), "n/a");
- snprintf(errCodeStr, sizeof(errCodeStr), "%d", e->request_code);
- XGetErrorDatabaseText(dpy, "XRequest", errCodeStr, "Unknown", reqCodeStr, sizeof(reqCodeStr));
- XGetErrorText(dpy, e->error_code, errCodeStr, sizeof(errCodeStr));
-
- fprintf(stderr, "Info: Newt X11 Error (Thread: %s): %d - %s, dpy %p, id %x, # %d: %d:%d %s\n",
- threadName, e->error_code, errCodeStr, e->display, (int)e->resourceid, (int)e->serial,
- (int)e->request_code, (int)e->minor_code, reqCodeStr);
-
- if( errorHandlerDebug ) {
- (*jniEnv)->CallStaticVoidMethod(jniEnv, X11NewtWindowClazz, dumpStackID);
- }
-
- if(errorHandlerThrowException) {
- if(NULL != jniEnv) {
- NewtCommon_throwNewRuntimeException(jniEnv, "Newt X11 Error (Thread: %s): %d - %s, dpy %p, id %x, # %d: %d:%d %s\n",
- threadName, e->error_code, errCodeStr, e->display, (int)e->resourceid, (int)e->serial,
- (int)e->request_code, (int)e->minor_code, reqCodeStr);
- } else {
- fprintf(stderr, "Nativewindow X11 Error: null JNIEnv");
- #if 0
- if(NULL!=origErrorHandler) {
- origErrorHandler(dpy, e);
- }
- #endif
- }
- }
- fflush(stderr);
-
- if (NULL != jniEnv && shallBeDetached) {
- (*jvmHandle)->DetachCurrentThread(jvmHandle);
- }
- }
-
- return 0;
-}
-
-void NewtDisplay_x11ErrorHandlerEnable(JNIEnv * env, Display *dpy, int onoff, int quiet, int sync) {
- errorHandlerQuiet = quiet;
- if(onoff) {
- if(NULL==origErrorHandler) {
- setupJVMVars(env);
- origErrorHandler = XSetErrorHandler(x11ErrorHandler);
- if(sync && NULL!=dpy) {
- XSync(dpy, False);
- }
- }
- } else {
- if(NULL!=origErrorHandler) {
- if(sync && NULL!=dpy) {
- XSync(dpy, False);
- }
- XSetErrorHandler(origErrorHandler);
- origErrorHandler = NULL;
- }
- }
-}
-
/**
* Keycode
*/
@@ -230,28 +146,32 @@ static jint X11KeySym2NewtVKey(KeySym keySym) {
return J_VK_INSERT;
case XK_Help:
return J_VK_HELP;
+ case XK_grave:
+ return J_VK_BACK_QUOTE;
+ case XK_apostrophe:
+ return J_VK_QUOTE;
}
return keySym;
}
-static jint X11InputState2NewtModifiers(unsigned int xstate) {
+static jint X11InputState2NewtModifiers(unsigned int xstate, KeySym keySym) {
jint modifiers = 0;
- if ((ControlMask & xstate) != 0) {
+ if ( (ControlMask & xstate) != 0 || J_VK_CONTROL == keySym ) {
modifiers |= EVENT_CTRL_MASK;
}
- if ((ShiftMask & xstate) != 0) {
+ if ( (ShiftMask & xstate) != 0 || J_VK_SHIFT == keySym ) {
modifiers |= EVENT_SHIFT_MASK;
}
- if ((Mod1Mask & xstate) != 0) {
+ if ( (Mod1Mask & xstate) != 0 || J_VK_ALT == keySym ) {
modifiers |= EVENT_ALT_MASK;
}
- if ((Button1Mask & xstate) != 0) {
+ if ( (Button1Mask & xstate) != 0 ) {
modifiers |= EVENT_BUTTON1_MASK;
}
- if ((Button2Mask & xstate) != 0) {
+ if ( (Button2Mask & xstate) != 0 ) {
modifiers |= EVENT_BUTTON2_MASK;
}
- if ((Button3Mask & xstate) != 0) {
+ if ( (Button3Mask & xstate) != 0 ) {
modifiers |= EVENT_BUTTON3_MASK;
}
@@ -264,29 +184,26 @@ static jint X11InputState2NewtModifiers(unsigned int xstate) {
*/
/*
- * Class: jogamp_newt_driver_x11_X11Display
+ * Class: jogamp_newt_driver_x11_DisplayDriver
* Method: initIDs
* Signature: (Z)Z
*/
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Display_initIDs0
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_initIDs0
(JNIEnv *env, jclass clazz, jboolean debug)
{
jclass c;
- if(debug) {
- errorHandlerDebug = 1 ;
- }
NewtCommon_init(env);
if(NULL==X11NewtWindowClazz) {
c = (*env)->FindClass(env, ClazzNameX11NewtWindow);
if(NULL==c) {
- NewtCommon_FatalError(env, "NEWT X11Window: can't find %s", ClazzNameX11NewtWindow);
+ NewtCommon_FatalError(env, "NEWT X11Display: can't find %s", ClazzNameX11NewtWindow);
}
X11NewtWindowClazz = (jclass)(*env)->NewGlobalRef(env, c);
(*env)->DeleteLocalRef(env, c);
if(NULL==X11NewtWindowClazz) {
- NewtCommon_FatalError(env, "NEWT X11Window: can't use %s", ClazzNameX11NewtWindow);
+ NewtCommon_FatalError(env, "NEWT X11Display: can't use %s", ClazzNameX11NewtWindow);
}
}
@@ -331,11 +248,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Display_initIDs0
}
/*
- * Class: jogamp_newt_driver_x11_X11Display
+ * Class: jogamp_newt_driver_x11_DisplayDriver
* Method: CompleteDisplay
* Signature: (J)V
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_CompleteDisplay0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_CompleteDisplay0
(JNIEnv *env, jobject obj, jlong display)
{
Display * dpy = (Display *)(intptr_t)display;
@@ -366,11 +283,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_CompleteDisplay0
}
/*
- * Class: jogamp_newt_driver_x11_X11Display
+ * Class: jogamp_newt_driver_x11_DisplayDriver
* Method: DisplayRelease0
* Signature: (JJJ)V
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DisplayRelease0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DisplayRelease0
(JNIEnv *env, jobject obj, jlong display, jlong javaObjectAtom, jlong windowDeleteAtom)
{
Display * dpy = (Display *)(intptr_t)display;
@@ -390,16 +307,17 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DisplayRelease0
}
/*
- * Class: jogamp_newt_driver_x11_X11Display
+ * Class: jogamp_newt_driver_x11_DisplayDriver
* Method: DispatchMessages
* Signature: (JIJJ)V
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessages0
(JNIEnv *env, jobject obj, jlong display, jlong javaObjectAtom, jlong windowDeleteAtom)
{
Display * dpy = (Display *) (intptr_t) display;
Atom wm_delete_atom = (Atom)windowDeleteAtom;
int num_events = 100;
+ int autoRepeatModifiers = 0;
if ( NULL == dpy ) {
return;
@@ -415,10 +333,10 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0
char text[255];
// XEventsQueued(dpy, X):
- // QueuedAlready : No I/O Flush or system call doesn't work on some cards (eg ATI) ?)
+ // QueuedAlready == XQLength(): No I/O Flush or system call doesn't work on some cards (eg ATI) ?)
// QueuedAfterFlush == XPending(): I/O Flush only if no already queued events are available
// QueuedAfterReading : QueuedAlready + if queue==0, attempt to read more ..
- if ( 0 >= XPending(dpy) ) {
+ if ( 0 >= XEventsQueued(dpy, QueuedAfterFlush) ) {
// DBG_PRINT( "X11: DispatchMessages 0x%X - Leave 1\n", dpy);
return;
}
@@ -426,19 +344,17 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0
XNextEvent(dpy, &evt);
num_events--;
- if( 0==evt.xany.window ) {
- NewtCommon_throwNewRuntimeException(env, "event window NULL, bail out!");
- return ;
- }
-
if(dpy!=evt.xany.display) {
NewtCommon_throwNewRuntimeException(env, "wrong display, bail out!");
return ;
}
- // DBG_PRINT( "X11: DispatchMessages dpy %p, win %p, Event %d\n", (void*)dpy, (void*)evt.xany.window, (int)evt.type);
+ if( 0==evt.xany.window ) {
+ DBG_PRINT( "X11: DispatchMessages dpy %p, Event %d - Window NULL, ignoring\n", (void*)dpy, (int)evt.type);
+ continue;
+ }
- NewtDisplay_x11ErrorHandlerEnable(env, dpy, 1, 0, 0);
+ // DBG_PRINT( "X11: DispatchMessages dpy %p, win %p, Event %d\n", (void*)dpy, (void*)evt.xany.window, (int)evt.type);
jwindow = getJavaWindowProperty(env, dpy, evt.xany.window, javaObjectAtom,
#ifdef VERBOSE_ON
@@ -448,16 +364,28 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0
#endif
);
- NewtDisplay_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
-
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);
+ 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);
continue;
}
switch(evt.type) {
case KeyRelease:
+ if (XEventsQueued(dpy, QueuedAfterReading)) {
+ XEvent nevt;
+ XPeekEvent(dpy, &nevt);
+
+ if (nevt.type == KeyPress && nevt.xkey.time == evt.xkey.time &&
+ nevt.xkey.keycode == evt.xkey.keycode)
+ {
+ autoRepeatModifiers |= EVENT_AUTOREPEAT_MASK;
+ } else {
+ autoRepeatModifiers &= ~EVENT_AUTOREPEAT_MASK;
+ }
+ } else {
+ autoRepeatModifiers &= ~EVENT_AUTOREPEAT_MASK;
+ }
+ // fall through intended
case KeyPress:
if(XLookupString(&evt.xkey,text,255,&keySym,0)==1) {
KeySym lower_return = 0, upper_return = 0;
@@ -469,13 +397,13 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0
keyChar=0;
keySym = X11KeySym2NewtVKey(keySym);
}
- modifiers = X11InputState2NewtModifiers(evt.xkey.state);
+ modifiers |= X11InputState2NewtModifiers(evt.xkey.state, keySym) | autoRepeatModifiers;
break;
case ButtonPress:
case ButtonRelease:
case MotionNotify:
- modifiers = X11InputState2NewtModifiers(evt.xbutton.state);
+ modifiers |= X11InputState2NewtModifiers(evt.xbutton.state, 0);
break;
default:
@@ -544,23 +472,23 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0
case KeyPress:
#ifdef USE_SENDIO_DIRECT
(*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_PRESSED,
- modifiers, keySym, (jchar) -1);
+ modifiers, keySym, (jchar) keyChar);
#else
(*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, JNI_FALSE, (jint) EVENT_KEY_PRESSED,
- modifiers, keySym, (jchar) -1);
+ modifiers, keySym, (jchar) keyChar);
#endif
break;
case KeyRelease:
#ifdef USE_SENDIO_DIRECT
(*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_RELEASED,
- modifiers, keySym, (jchar) -1);
+ modifiers, keySym, (jchar) keyChar);
(*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_TYPED,
modifiers, keySym, (jchar) keyChar);
#else
(*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, JNI_FALSE, (jint) EVENT_KEY_RELEASED,
- modifiers, keySym, (jchar) -1);
+ modifiers, keySym, (jchar) keyChar);
(*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, JNI_FALSE, (jint) EVENT_KEY_TYPED,
modifiers, keySym, (jchar) keyChar);
diff --git a/src/newt/native/X11Display.c b/src/newt/native/X11Event.c
similarity index 50%
copy from src/newt/native/X11Display.c
copy to src/newt/native/X11Event.c
index ce7d9a0..0792034 100644
--- a/src/newt/native/X11Display.c
+++ b/src/newt/native/X11Event.c
@@ -1,405 +1,10 @@
-/**
- * Copyright 2011 JogAmp Community. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are
- * permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- *
- * 2. 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.
- *
- * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community OR
- * CONTRIBUTORS 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.
- *
- * The views and conclusions contained in the software and documentation are those of the
- * authors and should not be interpreted as representing official policies, either expressed
- * or implied, of JogAmp Community.
- */
-#include "X11Common.h"
+#include "X11Event.h"
-#define USE_SENDIO_DIRECT 1
-
-jclass X11NewtWindowClazz = NULL;
-jmethodID insetsChangedID = NULL;
-jmethodID visibleChangedID = NULL;
-
-static const char * const ClazzNameX11NewtWindow = "jogamp/newt/driver/x11/X11Window";
-
-static jmethodID displayCompletedID = NULL;
-
-static jmethodID getCurrentThreadNameID = NULL;
-static jmethodID dumpStackID = NULL;
-static jmethodID sizeChangedID = NULL;
-static jmethodID positionChangedID = NULL;
-static jmethodID focusChangedID = NULL;
-static jmethodID reparentNotifyID = NULL;
-static jmethodID windowDestroyNotifyID = NULL;
-static jmethodID windowRepaintID = NULL;
-static jmethodID enqueueMouseEventID = NULL;
-static jmethodID sendMouseEventID = NULL;
-static jmethodID enqueueKeyEventID = NULL;
-static jmethodID sendKeyEventID = NULL;
-static jmethodID requestFocusID = NULL;
-
-static JavaVM *jvmHandle = NULL;
-static int jvmVersion = 0;
-
-static void setupJVMVars(JNIEnv * env) {
- if(0 != (*env)->GetJavaVM(env, &jvmHandle)) {
- jvmHandle = NULL;
- }
- jvmVersion = (*env)->GetVersion(env);
-}
-
-static XErrorHandler origErrorHandler = NULL ;
-static int errorHandlerQuiet = 0 ;
-static int errorHandlerDebug = 0 ;
-static int errorHandlerThrowException = 0;
-
-static int x11ErrorHandler(Display *dpy, XErrorEvent *e)
-{
- if(!errorHandlerQuiet) {
- const char * errnoStr = strerror(errno);
- char threadName[80];
- char errCodeStr[80];
- char reqCodeStr[80];
-
- int shallBeDetached = 0;
- JNIEnv *jniEnv = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
-
- (void) NewtCommon_GetStaticStringMethod(jniEnv, X11NewtWindowClazz, getCurrentThreadNameID, threadName, sizeof(threadName), "n/a");
- snprintf(errCodeStr, sizeof(errCodeStr), "%d", e->request_code);
- XGetErrorDatabaseText(dpy, "XRequest", errCodeStr, "Unknown", reqCodeStr, sizeof(reqCodeStr));
- XGetErrorText(dpy, e->error_code, errCodeStr, sizeof(errCodeStr));
-
- fprintf(stderr, "Info: Newt X11 Error (Thread: %s): %d - %s, dpy %p, id %x, # %d: %d:%d %s\n",
- threadName, e->error_code, errCodeStr, e->display, (int)e->resourceid, (int)e->serial,
- (int)e->request_code, (int)e->minor_code, reqCodeStr);
-
- if( errorHandlerDebug ) {
- (*jniEnv)->CallStaticVoidMethod(jniEnv, X11NewtWindowClazz, dumpStackID);
- }
-
- if(errorHandlerThrowException) {
- if(NULL != jniEnv) {
- NewtCommon_throwNewRuntimeException(jniEnv, "Newt X11 Error (Thread: %s): %d - %s, dpy %p, id %x, # %d: %d:%d %s\n",
- threadName, e->error_code, errCodeStr, e->display, (int)e->resourceid, (int)e->serial,
- (int)e->request_code, (int)e->minor_code, reqCodeStr);
- } else {
- fprintf(stderr, "Nativewindow X11 Error: null JNIEnv");
- #if 0
- if(NULL!=origErrorHandler) {
- origErrorHandler(dpy, e);
- }
- #endif
- }
- }
- fflush(stderr);
-
- if (NULL != jniEnv && shallBeDetached) {
- (*jvmHandle)->DetachCurrentThread(jvmHandle);
- }
- }
-
- return 0;
-}
-
-void NewtDisplay_x11ErrorHandlerEnable(JNIEnv * env, Display *dpy, int onoff, int quiet, int sync) {
- errorHandlerQuiet = quiet;
- if(onoff) {
- if(NULL==origErrorHandler) {
- setupJVMVars(env);
- origErrorHandler = XSetErrorHandler(x11ErrorHandler);
- if(sync && NULL!=dpy) {
- XSync(dpy, False);
- }
- }
- } else {
- if(NULL!=origErrorHandler) {
- if(sync && NULL!=dpy) {
- XSync(dpy, False);
- }
- XSetErrorHandler(origErrorHandler);
- origErrorHandler = NULL;
- }
- }
-}
-
-/**
- * Keycode
- */
-
-#define IS_WITHIN(k,a,b) ((a)<=(k)&&(k)<=(b))
-
-static jint X11KeySym2NewtVKey(KeySym keySym) {
- if(IS_WITHIN(keySym,XK_F1,XK_F12))
- return (keySym-XK_F1)+J_VK_F1;
- if(IS_WITHIN(keySym,XK_KP_0,XK_KP_9))
- return (keySym-XK_KP_0)+J_VK_NUMPAD0;
-
- switch(keySym) {
- case XK_Return:
- case XK_KP_Enter:
- return J_VK_ENTER;
- case XK_BackSpace:
- return J_VK_BACK_SPACE;
- case XK_Tab:
- case XK_KP_Tab:
- case XK_ISO_Left_Tab:
- return J_VK_TAB;
- case XK_Cancel:
- return J_VK_CANCEL;
- case XK_Clear:
- return J_VK_CLEAR;
- case XK_Shift_L:
- case XK_Shift_R:
- return J_VK_SHIFT;
- case XK_Control_L:
- case XK_Control_R:
- return J_VK_CONTROL;
- case XK_Alt_L:
- case XK_Alt_R:
- return J_VK_ALT;
- case XK_Pause:
- return J_VK_PAUSE;
- case XK_Caps_Lock:
- return J_VK_CAPS_LOCK;
- case XK_Escape:
- return J_VK_ESCAPE;
- case XK_space:
- case XK_KP_Space:
- return J_VK_SPACE;
- case XK_Page_Up:
- case XK_KP_Page_Up:
- return J_VK_PAGE_UP;
- case XK_Page_Down:
- case XK_KP_Page_Down:
- return J_VK_PAGE_DOWN;
- case XK_End:
- case XK_KP_End:
- return J_VK_END;
- case XK_Home:
- case XK_KP_Home:
- return J_VK_HOME;
- case XK_Left:
- case XK_KP_Left:
- return J_VK_LEFT;
- case XK_Up:
- case XK_KP_Up:
- return J_VK_UP;
- case XK_Right:
- case XK_KP_Right:
- return J_VK_RIGHT;
- case XK_Down:
- case XK_KP_Down:
- return J_VK_DOWN;
- case XK_KP_Multiply:
- return J_VK_MULTIPLY;
- case XK_KP_Add:
- return J_VK_ADD;
- case XK_KP_Separator:
- return J_VK_SEPARATOR;
- case XK_KP_Subtract:
- return J_VK_SUBTRACT;
- case XK_KP_Decimal:
- return J_VK_DECIMAL;
- case XK_KP_Divide:
- return J_VK_DIVIDE;
- case XK_Delete:
- case XK_KP_Delete:
- return J_VK_DELETE;
- case XK_Num_Lock:
- return J_VK_NUM_LOCK;
- case XK_Scroll_Lock:
- return J_VK_SCROLL_LOCK;
- case XK_Print:
- return J_VK_PRINTSCREEN;
- case XK_Insert:
- case XK_KP_Insert:
- return J_VK_INSERT;
- case XK_Help:
- return J_VK_HELP;
- }
- return keySym;
-}
-
-static jint X11InputState2NewtModifiers(unsigned int xstate) {
- jint modifiers = 0;
- if ((ControlMask & xstate) != 0) {
- modifiers |= EVENT_CTRL_MASK;
- }
- if ((ShiftMask & xstate) != 0) {
- modifiers |= EVENT_SHIFT_MASK;
- }
- if ((Mod1Mask & xstate) != 0) {
- modifiers |= EVENT_ALT_MASK;
- }
- if ((Button1Mask & xstate) != 0) {
- modifiers |= EVENT_BUTTON1_MASK;
- }
- if ((Button2Mask & xstate) != 0) {
- modifiers |= EVENT_BUTTON2_MASK;
- }
- if ((Button3Mask & xstate) != 0) {
- modifiers |= EVENT_BUTTON3_MASK;
- }
-
- return modifiers;
-}
-
-
-/**
- * Keycode
- */
-
-/*
- * Class: jogamp_newt_driver_x11_X11Display
- * Method: initIDs
- * Signature: (Z)Z
- */
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Display_initIDs0
- (JNIEnv *env, jclass clazz, jboolean debug)
-{
- jclass c;
-
- if(debug) {
- errorHandlerDebug = 1 ;
- }
- NewtCommon_init(env);
-
- if(NULL==X11NewtWindowClazz) {
- c = (*env)->FindClass(env, ClazzNameX11NewtWindow);
- if(NULL==c) {
- NewtCommon_FatalError(env, "NEWT X11Window: can't find %s", ClazzNameX11NewtWindow);
- }
- X11NewtWindowClazz = (jclass)(*env)->NewGlobalRef(env, c);
- (*env)->DeleteLocalRef(env, c);
- if(NULL==X11NewtWindowClazz) {
- NewtCommon_FatalError(env, "NEWT X11Window: can't use %s", ClazzNameX11NewtWindow);
- }
- }
-
- displayCompletedID = (*env)->GetMethodID(env, clazz, "displayCompleted", "(JJ)V");
- getCurrentThreadNameID = (*env)->GetStaticMethodID(env, X11NewtWindowClazz, "getCurrentThreadName", "()Ljava/lang/String;");
- dumpStackID = (*env)->GetStaticMethodID(env, X11NewtWindowClazz, "dumpStack", "()V");
- insetsChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "insetsChanged", "(ZIIII)V");
- sizeChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sizeChanged", "(ZIIZ)V");
- positionChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "positionChanged", "(ZII)V");
- focusChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "focusChanged", "(ZZ)V");
- visibleChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "visibleChanged", "(ZZ)V");
- reparentNotifyID = (*env)->GetMethodID(env, X11NewtWindowClazz, "reparentNotify", "(J)V");
- windowDestroyNotifyID = (*env)->GetMethodID(env, X11NewtWindowClazz, "windowDestroyNotify", "(Z)Z");
- windowRepaintID = (*env)->GetMethodID(env, X11NewtWindowClazz, "windowRepaint", "(ZIIII)V");
- enqueueMouseEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "enqueueMouseEvent", "(ZIIIIII)V");
- sendMouseEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendMouseEvent", "(IIIIII)V");
- enqueueKeyEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "enqueueKeyEvent", "(ZIIIC)V");
- sendKeyEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendKeyEvent", "(IIIC)V");
- requestFocusID = (*env)->GetMethodID(env, X11NewtWindowClazz, "requestFocus", "(Z)V");
-
- if (displayCompletedID == NULL ||
- getCurrentThreadNameID == NULL ||
- dumpStackID == NULL ||
- insetsChangedID == NULL ||
- sizeChangedID == NULL ||
- positionChangedID == NULL ||
- focusChangedID == NULL ||
- visibleChangedID == NULL ||
- reparentNotifyID == NULL ||
- windowDestroyNotifyID == NULL ||
- windowRepaintID == NULL ||
- enqueueMouseEventID == NULL ||
- sendMouseEventID == NULL ||
- enqueueKeyEventID == NULL ||
- sendKeyEventID == NULL ||
- requestFocusID == NULL) {
- return JNI_FALSE;
- }
-
-
- return JNI_TRUE;
-}
-
-/*
- * Class: jogamp_newt_driver_x11_X11Display
- * Method: CompleteDisplay
- * Signature: (J)V
- */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_CompleteDisplay0
- (JNIEnv *env, jobject obj, jlong display)
-{
- Display * dpy = (Display *)(intptr_t)display;
- jlong javaObjectAtom;
- jlong windowDeleteAtom;
-
- if(dpy==NULL) {
- NewtCommon_FatalError(env, "invalid display connection..");
- }
-
- javaObjectAtom = (jlong) XInternAtom(dpy, "NEWT_JAVA_OBJECT", False);
- if(None==javaObjectAtom) {
- NewtCommon_throwNewRuntimeException(env, "could not create Atom NEWT_JAVA_OBJECT, bail out!");
- return;
- }
-
- windowDeleteAtom = (jlong) XInternAtom(dpy, "WM_DELETE_WINDOW", False);
- if(None==windowDeleteAtom) {
- NewtCommon_throwNewRuntimeException(env, "could not create Atom WM_DELETE_WINDOW, bail out!");
- return;
- }
-
- // XSetCloseDownMode(dpy, RetainTemporary); // Just a try ..
-
- DBG_PRINT("X11: X11Display_completeDisplay dpy %p\n", dpy);
-
- (*env)->CallVoidMethod(env, obj, displayCompletedID, javaObjectAtom, windowDeleteAtom);
-}
-
-/*
- * Class: jogamp_newt_driver_x11_X11Display
- * Method: DisplayRelease0
- * Signature: (JJJ)V
- */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DisplayRelease0
- (JNIEnv *env, jobject obj, jlong display, jlong javaObjectAtom, jlong windowDeleteAtom)
-{
- Display * dpy = (Display *)(intptr_t)display;
- Atom wm_javaobject_atom = (Atom)javaObjectAtom;
- Atom wm_delete_atom = (Atom)windowDeleteAtom;
-
- if(dpy==NULL) {
- NewtCommon_FatalError(env, "invalid display connection..");
- }
-
- // nothing to do to free the atoms !
- (void) wm_javaobject_atom;
- (void) wm_delete_atom;
-
- XSync(dpy, True); // discard all pending events
- DBG_PRINT("X11: X11Display_DisplayRelease dpy %p\n", dpy);
-}
-
-/*
- * Class: jogamp_newt_driver_x11_X11Display
- * Method: DispatchMessages
- * Signature: (JIJJ)V
- */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0
- (JNIEnv *env, jobject obj, jlong display, jlong javaObjectAtom, jlong windowDeleteAtom)
-{
- Display * dpy = (Display *) (intptr_t) display;
+void X11EventPoll(JNIEnv *env, jobject obj, Display *dpy, jlong javaObjectAtom, jlong windowDeleteAtom) {
Atom wm_delete_atom = (Atom)windowDeleteAtom;
int num_events = 100;
+ int autoRepeatModifiers = 0;
if ( NULL == dpy ) {
return;
@@ -415,10 +20,12 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0
char text[255];
// XEventsQueued(dpy, X):
- // QueuedAlready : No I/O Flush or system call doesn't work on some cards (eg ATI) ?)
+ // QueuedAlready == XQLength(): No I/O Flush or system call doesn't work on some cards (eg ATI) ?)
// QueuedAfterFlush == XPending(): I/O Flush only if no already queued events are available
// QueuedAfterReading : QueuedAlready + if queue==0, attempt to read more ..
- if ( 0 >= XPending(dpy) ) {
+ // if ( 0 >= XPending(dpy) )
+ if ( 0 >= XEventsQueued(dpy, QueuedAfterFlush) )
+ {
// DBG_PRINT( "X11: DispatchMessages 0x%X - Leave 1\n", dpy);
return;
}
@@ -426,19 +33,17 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0
XNextEvent(dpy, &evt);
num_events--;
- if( 0==evt.xany.window ) {
- NewtCommon_throwNewRuntimeException(env, "event window NULL, bail out!");
- return ;
- }
-
if(dpy!=evt.xany.display) {
NewtCommon_throwNewRuntimeException(env, "wrong display, bail out!");
return ;
}
- // DBG_PRINT( "X11: DispatchMessages dpy %p, win %p, Event %d\n", (void*)dpy, (void*)evt.xany.window, (int)evt.type);
+ if( 0==evt.xany.window ) {
+ DBG_PRINT( "X11: DispatchMessages dpy %p, Event %d - Window NULL, ignoring\n", (void*)dpy, (int)evt.type);
+ continue;
+ }
- NewtDisplay_x11ErrorHandlerEnable(env, dpy, 1, 0, 0);
+ // DBG_PRINT( "X11: DispatchMessages dpy %p, win %p, Event %d\n", (void*)dpy, (void*)evt.xany.window, (int)evt.type);
jwindow = getJavaWindowProperty(env, dpy, evt.xany.window, javaObjectAtom,
#ifdef VERBOSE_ON
@@ -448,16 +53,26 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0
#endif
);
- NewtDisplay_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
-
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);
+ 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);
continue;
}
switch(evt.type) {
case KeyRelease:
+ if (XEventsQueued(dpy, QueuedAfterReading)) {
+ XEvent nevt;
+ XPeekEvent(dpy, &nevt);
+
+ if (nevt.type == KeyPress && nevt.xkey.time == evt.xkey.time &&
+ nevt.xkey.keycode == evt.xkey.keycode)
+ {
+ autoRepeatModifiers |= EVENT_AUTOREPEAT_MASK;
+ } else {
+ autoRepeatModifiers &= ~EVENT_AUTOREPEAT_MASK;
+ }
+ }
+ // fall through intended
case KeyPress:
if(XLookupString(&evt.xkey,text,255,&keySym,0)==1) {
KeySym lower_return = 0, upper_return = 0;
@@ -469,13 +84,13 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0
keyChar=0;
keySym = X11KeySym2NewtVKey(keySym);
}
- modifiers = X11InputState2NewtModifiers(evt.xkey.state);
+ modifiers |= X11InputState2NewtModifiers(evt.xkey.state) | autoRepeatModifiers;
break;
case ButtonPress:
case ButtonRelease:
case MotionNotify:
- modifiers = X11InputState2NewtModifiers(evt.xbutton.state);
+ modifiers |= X11InputState2NewtModifiers(evt.xbutton.state);
break;
default:
@@ -694,5 +309,3 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0
}
}
}
-
-
diff --git a/src/newt/native/X11Event.h b/src/newt/native/X11Event.h
new file mode 100644
index 0000000..969bcde
--- /dev/null
+++ b/src/newt/native/X11Event.h
@@ -0,0 +1,9 @@
+
+#ifndef _X11Event_h
+#define _X11Event_h
+
+#include "X11Common.h"
+
+extern void X11EventPoll(JNIEnv *env, jobject obj, Display *dpy, jlong javaObjectAtom, jlong wmDeleteAtom);
+
+#endif /* _X11Event_h */
diff --git a/src/newt/native/X11Screen.c b/src/newt/native/X11Screen.c
index 698eed8..e8a3ca6 100644
--- a/src/newt/native/X11Screen.c
+++ b/src/newt/native/X11Screen.c
@@ -36,11 +36,11 @@
#endif
/*
- * Class: jogamp_newt_driver_x11_X11Screen
+ * Class: jogamp_newt_driver_x11_ScreenDriver
* Method: GetScreen
* Signature: (JI)J
*/
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Screen_GetScreen0
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_GetScreen0
(JNIEnv *env, jclass clazz, jlong display, jint screen_index)
{
Display * dpy = (Display *)(intptr_t)display;
@@ -60,14 +60,14 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Screen_GetScreen0
return (jlong) (intptr_t) scrn;
}
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getWidth0
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getWidth0
(JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
{
Display * dpy = (Display *) (intptr_t) display;
return (jint) DisplayWidth( dpy, scrn_idx);
}
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getHeight0
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getHeight0
(JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
{
Display * dpy = (Display *) (intptr_t) display;
@@ -112,11 +112,11 @@ static int NewtScreen_XRotation2Degree(JNIEnv *env, int xrotation) {
}
/*
- * Class: jogamp_newt_driver_x11_X11Screen
+ * Class: jogamp_newt_driver_x11_ScreenDriver
* Method: getAvailableScreenModeRotations0
* Signature: (JI)I
*/
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getAvailableScreenModeRotations0
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getAvailableScreenModeRotations0
(JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
{
Display *dpy = (Display *) (intptr_t) display;
@@ -162,11 +162,11 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getAvailableSc
}
/*
- * Class: jogamp_newt_driver_x11_X11Screen
+ * Class: jogamp_newt_driver_x11_ScreenDriver
* Method: getNumScreenModeResolution0
* Signature: (JI)I
*/
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getNumScreenModeResolutions0
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getNumScreenModeResolutions0
(JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
{
Display *dpy = (Display *) (intptr_t) display;
@@ -177,7 +177,7 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getNumScreenModeRes
#endif
if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getNumScreenModeResolutions0: RANDR not available\n");
+ DBG_PRINT("Java_jogamp_newt_driver_x11_ScreenDriver_getNumScreenModeResolutions0: RANDR not available\n");
return 0;
}
@@ -200,17 +200,17 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getNumScreenModeRes
}
/*
- * Class: jogamp_newt_driver_x11_X11Screen
+ * Class: jogamp_newt_driver_x11_ScreenDriver
* Method: getScreenModeResolutions0
* Signature: (JII)[I
*/
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenModeResolution0
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getScreenModeResolution0
(JNIEnv *env, jclass clazz, jlong display, jint scrn_idx, jint resMode_idx)
{
Display *dpy = (Display *) (intptr_t) display;
if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getScreenModeResolution0: RANDR not available\n");
+ DBG_PRINT("Java_jogamp_newt_driver_x11_ScreenDriver_getScreenModeResolution0: RANDR not available\n");
return (*env)->NewIntArray(env, 0);
}
@@ -242,17 +242,17 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenModeR
}
/*
- * Class: jogamp_newt_driver_x11_X11Screen
+ * Class: jogamp_newt_driver_x11_ScreenDriver
* Method: getScreenModeRates0
* Signature: (JII)[I
*/
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenModeRates0
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getScreenModeRates0
(JNIEnv *env, jclass clazz, jlong display, jint scrn_idx, jint resMode_idx)
{
Display *dpy = (Display *) (intptr_t) display;
if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getScreenModeRates0: RANDR not available\n");
+ DBG_PRINT("Java_jogamp_newt_driver_x11_ScreenDriver_getScreenModeRates0: RANDR not available\n");
return (*env)->NewIntArray(env, 0);
}
@@ -285,11 +285,11 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenModeR
}
/*
- * Class: jogamp_newt_driver_x11_X11Screen
+ * Class: jogamp_newt_driver_x11_ScreenDriver
* Method: getScreenConfiguration0
* Signature: (JI)J
*/
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenConfiguration0
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getScreenConfiguration0
(JNIEnv *env, jclass clazz, jlong display, jint screen_idx)
{
Display *dpy = (Display *) (intptr_t) display;
@@ -301,7 +301,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenConfigura
#endif
if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getScreenConfiguration0: RANDR not available\n");
+ DBG_PRINT("Java_jogamp_newt_driver_x11_ScreenDriver_getScreenConfiguration0: RANDR not available\n");
return 0;
}
#ifdef DBG_PERF
@@ -320,22 +320,22 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenConfigura
}
/*
- * Class: jogamp_newt_driver_x11_X11Screen
+ * Class: jogamp_newt_driver_x11_ScreenDriver
* Method: freeScreenConfiguration0
* Signature: (J)V
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Screen_freeScreenConfiguration0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_freeScreenConfiguration0
(JNIEnv *env, jclass clazz, jlong screenConfiguration)
{
XRRFreeScreenConfigInfo( (XRRScreenConfiguration *) (intptr_t) screenConfiguration );
}
/*
- * Class: jogamp_newt_driver_x11_X11Screen
+ * Class: jogamp_newt_driver_x11_ScreenDriver
* Method: getCurrentScreenRate0
* Signature: (J)I
*/
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRate0
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getCurrentScreenRate0
(JNIEnv *env, jclass clazz, jlong screenConfiguration)
{
XRRScreenConfiguration *conf = (XRRScreenConfiguration *) (intptr_t) screenConfiguration;
@@ -347,11 +347,11 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRat
}
/*
- * Class: jogamp_newt_driver_x11_X11Screen
+ * Class: jogamp_newt_driver_x11_ScreenDriver
* Method: getCurrentScreenRotation0
* Signature: (J)I
*/
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRotation0
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getCurrentScreenRotation0
(JNIEnv *env, jclass clazz, jlong screenConfiguration)
{
XRRScreenConfiguration *conf = (XRRScreenConfiguration *) (intptr_t) screenConfiguration;
@@ -364,11 +364,11 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRot
/*
- * Class: jogamp_newt_driver_x11_X11Screen
+ * Class: jogamp_newt_driver_x11_ScreenDriver
* Method: getCurrentScreenResolutionIndex0
* Signature: (J)I
*/
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenResolutionIndex0
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getCurrentScreenResolutionIndex0
(JNIEnv *env, jclass clazz, jlong screenConfiguration)
{
XRRScreenConfiguration *conf = (XRRScreenConfiguration *) (intptr_t) screenConfiguration;
@@ -383,11 +383,11 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRes
}
/*
- * Class: jogamp_newt_driver_x11_X11Screen
+ * Class: jogamp_newt_driver_x11_ScreenDriver
* Method: setCurrentScreenModeStart0
* Signature: (JIJIII)Z
*/
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScreenModeStart0
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_setCurrentScreenModeStart0
(JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jlong screenConfiguration, jint resMode_idx, jint freq, jint rotation)
{
Display *dpy = (Display *) (intptr_t) display;
@@ -432,11 +432,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScree
}
/*
- * Class: jogamp_newt_driver_x11_X11Screen
+ * Class: jogamp_newt_driver_x11_ScreenDriver
* Method: setCurrentScreenModePollEnd0
* Signature: (J)Z
*/
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScreenModePollEnd0
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_setCurrentScreenModePollEnd0
(JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jint resMode_idx, jint freq, jint rotation)
{
Display *dpy = (Display *) (intptr_t) display;
@@ -445,7 +445,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScree
XRRScreenChangeNotifyEvent * scn_event = (XRRScreenChangeNotifyEvent *) &evt;
if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_setCurrentScreenModePollEnd0: RANDR not available\n");
+ DBG_PRINT("Java_jogamp_newt_driver_x11_ScreenDriver_setCurrentScreenModePollEnd0: RANDR not available\n");
return JNI_FALSE;
}
@@ -469,15 +469,22 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScree
switch (evt.type - randr_event_base) {
case RRScreenChangeNotify:
- rot = NewtScreen_XRotation2Degree(env, (int)scn_event->rotation);
- DBG_PRINT( "XRANDR: event . RRScreenChangeNotify call %p (root %p) resIdx %d rot %d %dx%d\n",
- (void*)scn_event->window, (void*)scn_event->root,
- (int)scn_event->size_index, rot,
- scn_event->width, scn_event->height);
- // done = scn_event->size_index == resMode_idx; // not reliable ..
- done = rot == rotation &&
- scn_event->width == xrrs[resMode_idx].width &&
- scn_event->height == xrrs[resMode_idx].height;
+ if(0 < scn_event->rotation ) {
+ rot = NewtScreen_XRotation2Degree(env, (int)scn_event->rotation);
+ DBG_PRINT( "XRANDR: event . RRScreenChangeNotify call(1) %p (root %p) resIdx %d rot %d %dx%d\n",
+ (void*)scn_event->window, (void*)scn_event->root,
+ (int)scn_event->size_index, rot,
+ scn_event->width, scn_event->height);
+ // done = scn_event->size_index == resMode_idx; // not reliable ..
+ done = rot == rotation &&
+ scn_event->width == xrrs[resMode_idx].width &&
+ scn_event->height == xrrs[resMode_idx].height;
+ } else {
+ DBG_PRINT( "XRANDR: event . RRScreenChangeNotify call(0) %p (root %p) resIdx %d %dx%d\n",
+ (void*)scn_event->window, (void*)scn_event->root,
+ (int)scn_event->size_index,
+ scn_event->width, scn_event->height);
+ }
break;
default:
DBG_PRINT("RANDR: event . unhandled %d 0x%X call %p\n", (int)evt.type, (int)evt.type, (void*)evt.xany.window);
diff --git a/src/newt/native/X11Screen.c b/src/newt/native/X11ScreenRandR11.c
similarity index 54%
copy from src/newt/native/X11Screen.c
copy to src/newt/native/X11ScreenRandR11.c
index 698eed8..bc7d91d 100644
--- a/src/newt/native/X11Screen.c
+++ b/src/newt/native/X11ScreenRandR11.c
@@ -26,97 +26,9 @@
* or implied, of JogAmp Community.
*/
-// #define VERBOSE_ON 1
-// #define DBG_PERF 1
-
#include "X11Common.h"
-#ifdef DBG_PERF
- #include "timespec.h"
-#endif
-
-/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: GetScreen
- * Signature: (JI)J
- */
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Screen_GetScreen0
- (JNIEnv *env, jclass clazz, jlong display, jint screen_index)
-{
- Display * dpy = (Display *)(intptr_t)display;
- Screen * scrn= NULL;
-
- DBG_PRINT("X11: X11Screen_GetScreen0 dpy %p START\n", dpy);
-
- if(dpy==NULL) {
- NewtCommon_FatalError(env, "invalid display connection..");
- }
-
- scrn = ScreenOfDisplay(dpy, screen_index);
- if(scrn==NULL) {
- fprintf(stderr, "couldn't get screen idx %d\n", screen_index);
- }
- DBG_PRINT("X11: X11Screen_GetScreen0 idx %d -> scrn %p DONE\n", screen_index, scrn);
- return (jlong) (intptr_t) scrn;
-}
-
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getWidth0
- (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
-{
- Display * dpy = (Display *) (intptr_t) display;
- return (jint) DisplayWidth( dpy, scrn_idx);
-}
-
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getHeight0
- (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
-{
- Display * dpy = (Display *) (intptr_t) display;
- return (jint) DisplayHeight( dpy, scrn_idx);
-}
-
-static int showedRandRVersion = 0;
-
-static Bool NewtScreen_getRANDRVersion(Display *dpy, int *major, int *minor) {
- if( 0 == XRRQueryVersion(dpy, major, minor) ) {
- return False;
- }
- if(0 == showedRandRVersion) {
- DBG_PRINT("X11 RandR Version %d.%d\n", *major, *minor);
- showedRandRVersion = 1;
- }
- return True;
-}
-
-static Bool NewtScreen_hasRANDR(Display *dpy) {
- int major, minor;
- return NewtScreen_getRANDRVersion(dpy, &major, &minor);
-}
-
-static int NewtScreen_XRotation2Degree(JNIEnv *env, int xrotation) {
- int rot;
- if(xrotation == RR_Rotate_0) {
- rot = 0;
- }
- else if(xrotation == RR_Rotate_90) {
- rot = 90;
- }
- else if(xrotation == RR_Rotate_180) {
- rot = 180;
- }
- else if(xrotation == RR_Rotate_270) {
- rot = 270;
- } else {
- NewtCommon_throwNewRuntimeException(env, "invalid native rotation: %d", xrotation);
- }
- return rot;
-}
-
-/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: getAvailableScreenModeRotations0
- * Signature: (JI)I
- */
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getAvailableScreenModeRotations0
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getAvailableScreenModeRotations0_RandR11
(JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
{
Display *dpy = (Display *) (intptr_t) display;
@@ -161,59 +73,30 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getAvailableSc
return properties;
}
-/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: getNumScreenModeResolution0
- * Signature: (JI)I
- */
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getNumScreenModeResolutions0
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getNumScreenModeResolutions0_RandR11
(JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
{
Display *dpy = (Display *) (intptr_t) display;
-#ifdef DBG_PERF
- struct timespec t0, t1, td;
- long td_ms;
- timespec_now(&t0);
-#endif
+ Window root = RootWindow(dpy, (int)scrn_idx);
- if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getNumScreenModeResolutions0: RANDR not available\n");
- return 0;
- }
-
-#ifdef DBG_PERF
- timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td);
- fprintf(stderr, "X11Screen_getNumScreenModeResolution0.1: %ld ms\n", td_ms); fflush(NULL);
-#endif
-
int num_sizes;
XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions
-#ifdef DBG_PERF
- timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td);
- fprintf(stderr, "X11Screen_getNumScreenModeResolution0.2 (XRRSizes): %ld ms\n", td_ms); fflush(NULL);
-#endif
-
- DBG_PRINT("getNumScreenModeResolutions0: %p:%d -> %d\n", dpy, (int)scrn_idx, num_sizes);
+ DBG_PRINT("getNumScreenModeResolutions0: %d\n", num_sizes);
return num_sizes;
}
/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: getScreenModeResolutions0
+ * Class: jogamp_newt_driver_x11_ScreenDriver
+ * Method: getScreenModeResolutions0_RandR11
* Signature: (JII)[I
*/
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenModeResolution0
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getScreenModeResolution0_RandR11
(JNIEnv *env, jclass clazz, jlong display, jint scrn_idx, jint resMode_idx)
{
Display *dpy = (Display *) (intptr_t) display;
- if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getScreenModeResolution0: RANDR not available\n");
- return (*env)->NewIntArray(env, 0);
- }
-
int num_sizes;
XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions
@@ -242,20 +125,15 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenModeR
}
/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: getScreenModeRates0
+ * Class: jogamp_newt_driver_x11_ScreenDriver
+ * Method: getScreenModeRates0_RandR11
* Signature: (JII)[I
*/
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenModeRates0
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getScreenModeRates0_RandR11
(JNIEnv *env, jclass clazz, jlong display, jint scrn_idx, jint resMode_idx)
{
Display *dpy = (Display *) (intptr_t) display;
- if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getScreenModeRates0: RANDR not available\n");
- return (*env)->NewIntArray(env, 0);
- }
-
int num_sizes;
XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions
@@ -285,139 +163,100 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenModeR
}
/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: getScreenConfiguration0
- * Signature: (JI)J
+ * Class: jogamp_newt_driver_x11_ScreenDriver
+ * Method: getCurrentScreenRate0_RandR11
+ * Signature: (JI)I
*/
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenConfiguration0
- (JNIEnv *env, jclass clazz, jlong display, jint screen_idx)
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getCurrentScreenRate0_RandR11
+ (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
{
Display *dpy = (Display *) (intptr_t) display;
- Window root = RootWindow(dpy, (int)screen_idx);
-#ifdef DBG_PERF
- struct timespec t0, t1, td;
- long td_ms;
- timespec_now(&t0);
-#endif
-
- if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getScreenConfiguration0: RANDR not available\n");
- return 0;
- }
-#ifdef DBG_PERF
- timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td);
- fprintf(stderr, "X11Screen_getScreenConfiguration0.1: %ld ms\n", td_ms); fflush(NULL);
-#endif
-
+ Window root = RootWindow(dpy, (int)scrn_idx);
+
// get current resolutions and frequencies
XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root);
-#ifdef DBG_PERF
- timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td);
- fprintf(stderr, "X11Screen_getScreenConfiguration0.2 (XRRGetScreenInfo): %ld ms\n", td_ms); fflush(NULL);
-#endif
-
- return (jlong) (intptr_t) conf;
-}
-
-/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: freeScreenConfiguration0
- * Signature: (J)V
- */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Screen_freeScreenConfiguration0
- (JNIEnv *env, jclass clazz, jlong screenConfiguration)
-{
- XRRFreeScreenConfigInfo( (XRRScreenConfiguration *) (intptr_t) screenConfiguration );
-}
+ short original_rate = XRRConfigCurrentRate(conf);
-/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: getCurrentScreenRate0
- * Signature: (J)I
- */
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRate0
- (JNIEnv *env, jclass clazz, jlong screenConfiguration)
-{
- XRRScreenConfiguration *conf = (XRRScreenConfiguration *) (intptr_t) screenConfiguration;
+ //free
+ XRRFreeScreenConfigInfo(conf);
- short original_rate = XRRConfigCurrentRate(conf);
DBG_PRINT("getCurrentScreenRate0: %d\n", (int)original_rate);
return (jint) original_rate;
}
/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: getCurrentScreenRotation0
- * Signature: (J)I
+ * Class: jogamp_newt_driver_x11_ScreenDriver
+ * Method: getCurrentScreenRotation0_RandR11
+ * Signature: (JI)I
*/
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRotation0
- (JNIEnv *env, jclass clazz, jlong screenConfiguration)
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getCurrentScreenRotation0_RandR11
+ (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
{
- XRRScreenConfiguration *conf = (XRRScreenConfiguration *) (intptr_t) screenConfiguration;
+ Display *dpy = (Display *) (intptr_t) display;
+ Window root = RootWindow(dpy, (int)scrn_idx);
+
+ //get current resolutions and frequencies
+ XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root);
+
Rotation rotation;
-
XRRConfigCurrentConfiguration(conf, &rotation);
+ //free
+ XRRFreeScreenConfigInfo(conf);
+
return NewtScreen_XRotation2Degree(env, rotation);
}
/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: getCurrentScreenResolutionIndex0
- * Signature: (J)I
+ * Class: jogamp_newt_driver_x11_ScreenDriver
+ * Method: getCurrentScreenResolutionIndex0_RandR11
+ * Signature: (JI)I
*/
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenResolutionIndex0
- (JNIEnv *env, jclass clazz, jlong screenConfiguration)
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getCurrentScreenResolutionIndex0_RandR11
+ (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
{
- XRRScreenConfiguration *conf = (XRRScreenConfiguration *) (intptr_t) screenConfiguration;
+ Display *dpy = (Display *) (intptr_t) display;
+ Window root = RootWindow(dpy, (int)scrn_idx);
+ // get current resolutions and frequency configuration
+ XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root);
short original_rate = XRRConfigCurrentRate(conf);
Rotation original_rotation;
SizeID original_size_id = XRRConfigCurrentConfiguration(conf, &original_rotation);
+ //free
+ XRRFreeScreenConfigInfo(conf);
+
DBG_PRINT("getCurrentScreenResolutionIndex0: %d\n", (int)original_size_id);
- return (jint)original_size_id;
+ return (jint)original_size_id;
}
/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: setCurrentScreenModeStart0
- * Signature: (JIJIII)Z
+ * Class: jogamp_newt_driver_x11_ScreenDriver
+ * Method: setCurrentScreenModeStart0_RandR11
+ * Signature: (JIIII)Z
*/
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScreenModeStart0
- (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jlong screenConfiguration, jint resMode_idx, jint freq, jint rotation)
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_setCurrentScreenModeStart0_RandR11
+ (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jint resMode_idx, jint freq, jint rotation)
{
Display *dpy = (Display *) (intptr_t) display;
- XRRScreenConfiguration *conf = (XRRScreenConfiguration *) (intptr_t) screenConfiguration;
Window root = RootWindow(dpy, (int)screen_idx);
int num_sizes;
XRRScreenSize *xrrs = XRRSizes(dpy, (int)screen_idx, &num_sizes); //get possible screen resolutions
+ XRRScreenConfiguration *conf;
int rot;
if( 0 > resMode_idx || resMode_idx >= num_sizes ) {
NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes);
}
- switch(rotation) {
- case 0:
- rot = RR_Rotate_0;
- break;
- case 90:
- rot = RR_Rotate_90;
- break;
- case 180:
- rot = RR_Rotate_180;
- break;
- case 270:
- rot = RR_Rotate_270;
- break;
- default:
- NewtCommon_throwNewRuntimeException(env, "Invalid rotation: %d", rotation);
- }
+ conf = XRRGetScreenInfo(dpy, root);
+
+ rot = int NewtScreen_Degree2XRotation(env, rotation);
DBG_PRINT("X11Screen.setCurrentScreenMode0: CHANGED TO %d: %d x %d PIXELS, %d Hz, %d degree\n",
resMode_idx, xrrs[resMode_idx].width, xrrs[resMode_idx].height, (int)freq, rotation);
@@ -428,15 +267,19 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScree
XRRSetScreenConfigAndRate(dpy, conf, root, (int)resMode_idx, rot, (short)freq, CurrentTime);
XSync(dpy, False);
+ //free
+ XRRFreeScreenConfigInfo(conf);
+ XSync(dpy, False);
+
return JNI_TRUE;
}
/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: setCurrentScreenModePollEnd0
+ * Class: jogamp_newt_driver_x11_ScreenDriver
+ * Method: setCurrentScreenModePollEnd0_RandR11
* Signature: (J)Z
*/
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScreenModePollEnd0
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_setCurrentScreenModePollEnd0_RandR11
(JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jint resMode_idx, jint freq, jint rotation)
{
Display *dpy = (Display *) (intptr_t) display;
@@ -444,11 +287,6 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScree
XEvent evt;
XRRScreenChangeNotifyEvent * scn_event = (XRRScreenChangeNotifyEvent *) &evt;
- if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_setCurrentScreenModePollEnd0: RANDR not available\n");
- return JNI_FALSE;
- }
-
int num_sizes;
XRRScreenSize *xrrs = XRRSizes(dpy, (int)screen_idx, &num_sizes); //get possible screen resolutions
XRRScreenConfiguration *conf;
diff --git a/src/newt/native/X11Screen.c b/src/newt/native/X11ScreenRandR13.c
similarity index 55%
copy from src/newt/native/X11Screen.c
copy to src/newt/native/X11ScreenRandR13.c
index 698eed8..da90d15 100644
--- a/src/newt/native/X11Screen.c
+++ b/src/newt/native/X11ScreenRandR13.c
@@ -26,97 +26,36 @@
* or implied, of JogAmp Community.
*/
-// #define VERBOSE_ON 1
-// #define DBG_PERF 1
-
#include "X11Common.h"
-#ifdef DBG_PERF
- #include "timespec.h"
-#endif
-
-/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: GetScreen
- * Signature: (JI)J
- */
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Screen_GetScreen0
- (JNIEnv *env, jclass clazz, jlong display, jint screen_index)
-{
- Display * dpy = (Display *)(intptr_t)display;
- Screen * scrn= NULL;
-
- DBG_PRINT("X11: X11Screen_GetScreen0 dpy %p START\n", dpy);
-
- if(dpy==NULL) {
- NewtCommon_FatalError(env, "invalid display connection..");
- }
-
- scrn = ScreenOfDisplay(dpy, screen_index);
- if(scrn==NULL) {
- fprintf(stderr, "couldn't get screen idx %d\n", screen_index);
- }
- DBG_PRINT("X11: X11Screen_GetScreen0 idx %d -> scrn %p DONE\n", screen_index, scrn);
- return (jlong) (intptr_t) scrn;
-}
-
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getWidth0
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getOrigin0_RandR13
(JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
{
Display * dpy = (Display *) (intptr_t) display;
- return (jint) DisplayWidth( dpy, scrn_idx);
-}
-
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getHeight0
- (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
-{
- Display * dpy = (Display *) (intptr_t) display;
- return (jint) DisplayHeight( dpy, scrn_idx);
-}
-
-static int showedRandRVersion = 0;
+ Window root = RootWindow(dpy, (int)scrn_idx);
+ int pos[] = { 0, 0 } ;
-static Bool NewtScreen_getRANDRVersion(Display *dpy, int *major, int *minor) {
- if( 0 == XRRQueryVersion(dpy, major, minor) ) {
- return False;
- }
- if(0 == showedRandRVersion) {
- DBG_PRINT("X11 RandR Version %d.%d\n", *major, *minor);
- showedRandRVersion = 1;
+ int i;
+ XRRScreenResources *xrrScreenResources = XRRGetScreenResources(dpy, root);
+ fprintf(stderr, "XRRScreenResources %p: RRCrtc crtcs %d\n", xrrScreenResources, xrrScreenResources->ncrtc);
+ for(i=0; i<xrrScreenResources->ncrtc; i++) {
+ RRCrtc crtc = xrrScreenResources->crtcs[i];
+ XRRCrtcInfo *xrrCrtcInfo = XRRGetCrtcInfo (dpy, xrrScreenResources, crtc);
+ fprintf(stderr, "RRCrtc %d: %d/%d %dx%d\n", i, xrrCrtcInfo->x, xrrCrtcInfo->y, xrrCrtcInfo->width, xrrCrtcInfo->height);
+ XRRFreeCrtcInfo(xrrCrtcInfo);
}
- return True;
-}
-static Bool NewtScreen_hasRANDR(Display *dpy) {
- int major, minor;
- return NewtScreen_getRANDRVersion(dpy, &major, &minor);
-}
-
-static int NewtScreen_XRotation2Degree(JNIEnv *env, int xrotation) {
- int rot;
- if(xrotation == RR_Rotate_0) {
- rot = 0;
- }
- else if(xrotation == RR_Rotate_90) {
- rot = 90;
- }
- else if(xrotation == RR_Rotate_180) {
- rot = 180;
- }
- else if(xrotation == RR_Rotate_270) {
- rot = 270;
- } else {
- NewtCommon_throwNewRuntimeException(env, "invalid native rotation: %d", xrotation);
+ jintArray jpos = (*env)->NewIntArray(env, num_rotations);
+ if (properties == NULL) {
+ NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", 2);
}
- return rot;
+
+ // move from the temp structure to the java structure
+ (*env)->SetIntArrayRegion(env, jpos, 0, 2, pos);
+ return jpos;
}
-/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: getAvailableScreenModeRotations0
- * Signature: (JI)I
- */
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getAvailableScreenModeRotations0
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getAvailableScreenModeRotations0_RandR13
(JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
{
Display *dpy = (Display *) (intptr_t) display;
@@ -161,59 +100,46 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getAvailableSc
return properties;
}
-/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: getNumScreenModeResolution0
- * Signature: (JI)I
- */
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getNumScreenModeResolutions0
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getNumScreenModeResolutions0_RandR13
(JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
{
Display *dpy = (Display *) (intptr_t) display;
-#ifdef DBG_PERF
- struct timespec t0, t1, td;
- long td_ms;
- timespec_now(&t0);
-#endif
+ Window root = RootWindow(dpy, (int)scrn_idx);
- if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getNumScreenModeResolutions0: RANDR not available\n");
- return 0;
- }
-
-#ifdef DBG_PERF
- timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td);
- fprintf(stderr, "X11Screen_getNumScreenModeResolution0.1: %ld ms\n", td_ms); fflush(NULL);
-#endif
-
int num_sizes;
XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions
-#ifdef DBG_PERF
- timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td);
- fprintf(stderr, "X11Screen_getNumScreenModeResolution0.2 (XRRSizes): %ld ms\n", td_ms); fflush(NULL);
-#endif
+ DBG_PRINT("getNumScreenModeResolutions0: %d\n", num_sizes);
- DBG_PRINT("getNumScreenModeResolutions0: %p:%d -> %d\n", dpy, (int)scrn_idx, num_sizes);
+ int i;
+ XRRScreenResources *xrrScreenResources = XRRGetScreenResources(dpy, root);
+ fprintf(stderr, "XRRScreenResources %p: RRCrtc crtcs %d\n", xrrScreenResources, xrrScreenResources->ncrtc);
+ for(i=0; i<xrrScreenResources->ncrtc; i++) {
+ RRCrtc crtc = xrrScreenResources->crtcs[i];
+ XRRCrtcInfo *xrrCrtcInfo = XRRGetCrtcInfo (dpy, xrrScreenResources, crtc);
+ fprintf(stderr, "RRCrtc %d: %d/%d %dx%d\n", i, xrrCrtcInfo->x, xrrCrtcInfo->y, xrrCrtcInfo->width, xrrCrtcInfo->height);
+ XRRFreeCrtcInfo(xrrCrtcInfo);
+ }
+ fprintf(stderr, "XRRScreenResources %p: XRRModeInfo modes %d\n", xrrScreenResources, xrrScreenResources->nmode);
+ for(i=0; i<xrrScreenResources->nmode; i++) {
+ XRRModeInfo xrrModeInfo = xrrScreenResources->modes[i];
+ fprintf(stderr, "XRRModeInfo %d: %dx%d, %s, %X\n", i, xrrModeInfo.width, xrrModeInfo.height, xrrModeInfo.name, xrrModeInfo.id);
+ }
+ XRRFreeScreenResources(xrrScreenResources);
return num_sizes;
}
/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: getScreenModeResolutions0
+ * Class: jogamp_newt_driver_x11_ScreenDriver
+ * Method: getScreenModeResolutions0_RandR13
* Signature: (JII)[I
*/
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenModeResolution0
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getScreenModeResolution0_RandR13
(JNIEnv *env, jclass clazz, jlong display, jint scrn_idx, jint resMode_idx)
{
Display *dpy = (Display *) (intptr_t) display;
- if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getScreenModeResolution0: RANDR not available\n");
- return (*env)->NewIntArray(env, 0);
- }
-
int num_sizes;
XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions
@@ -242,20 +168,15 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenModeR
}
/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: getScreenModeRates0
+ * Class: jogamp_newt_driver_x11_ScreenDriver
+ * Method: getScreenModeRates0_RandR13
* Signature: (JII)[I
*/
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenModeRates0
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getScreenModeRates0_RandR13
(JNIEnv *env, jclass clazz, jlong display, jint scrn_idx, jint resMode_idx)
{
Display *dpy = (Display *) (intptr_t) display;
- if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getScreenModeRates0: RANDR not available\n");
- return (*env)->NewIntArray(env, 0);
- }
-
int num_sizes;
XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions
@@ -285,139 +206,100 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenModeR
}
/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: getScreenConfiguration0
- * Signature: (JI)J
+ * Class: jogamp_newt_driver_x11_ScreenDriver
+ * Method: getCurrentScreenRate0_RandR13
+ * Signature: (JI)I
*/
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenConfiguration0
- (JNIEnv *env, jclass clazz, jlong display, jint screen_idx)
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getCurrentScreenRate0_RandR13
+ (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
{
Display *dpy = (Display *) (intptr_t) display;
- Window root = RootWindow(dpy, (int)screen_idx);
-#ifdef DBG_PERF
- struct timespec t0, t1, td;
- long td_ms;
- timespec_now(&t0);
-#endif
-
- if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getScreenConfiguration0: RANDR not available\n");
- return 0;
- }
-#ifdef DBG_PERF
- timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td);
- fprintf(stderr, "X11Screen_getScreenConfiguration0.1: %ld ms\n", td_ms); fflush(NULL);
-#endif
-
+ Window root = RootWindow(dpy, (int)scrn_idx);
+
// get current resolutions and frequencies
XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root);
-#ifdef DBG_PERF
- timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td);
- fprintf(stderr, "X11Screen_getScreenConfiguration0.2 (XRRGetScreenInfo): %ld ms\n", td_ms); fflush(NULL);
-#endif
-
- return (jlong) (intptr_t) conf;
-}
-
-/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: freeScreenConfiguration0
- * Signature: (J)V
- */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Screen_freeScreenConfiguration0
- (JNIEnv *env, jclass clazz, jlong screenConfiguration)
-{
- XRRFreeScreenConfigInfo( (XRRScreenConfiguration *) (intptr_t) screenConfiguration );
-}
+ short original_rate = XRRConfigCurrentRate(conf);
-/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: getCurrentScreenRate0
- * Signature: (J)I
- */
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRate0
- (JNIEnv *env, jclass clazz, jlong screenConfiguration)
-{
- XRRScreenConfiguration *conf = (XRRScreenConfiguration *) (intptr_t) screenConfiguration;
+ //free
+ XRRFreeScreenConfigInfo(conf);
- short original_rate = XRRConfigCurrentRate(conf);
DBG_PRINT("getCurrentScreenRate0: %d\n", (int)original_rate);
return (jint) original_rate;
}
/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: getCurrentScreenRotation0
- * Signature: (J)I
+ * Class: jogamp_newt_driver_x11_ScreenDriver
+ * Method: getCurrentScreenRotation0_RandR13
+ * Signature: (JI)I
*/
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRotation0
- (JNIEnv *env, jclass clazz, jlong screenConfiguration)
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getCurrentScreenRotation0_RandR13
+ (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
{
- XRRScreenConfiguration *conf = (XRRScreenConfiguration *) (intptr_t) screenConfiguration;
+ Display *dpy = (Display *) (intptr_t) display;
+ Window root = RootWindow(dpy, (int)scrn_idx);
+
+ //get current resolutions and frequencies
+ XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root);
+
Rotation rotation;
-
XRRConfigCurrentConfiguration(conf, &rotation);
+ //free
+ XRRFreeScreenConfigInfo(conf);
+
return NewtScreen_XRotation2Degree(env, rotation);
}
/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: getCurrentScreenResolutionIndex0
- * Signature: (J)I
+ * Class: jogamp_newt_driver_x11_ScreenDriver
+ * Method: getCurrentScreenResolutionIndex0_RandR13
+ * Signature: (JI)I
*/
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenResolutionIndex0
- (JNIEnv *env, jclass clazz, jlong screenConfiguration)
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getCurrentScreenResolutionIndex0_RandR13
+ (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
{
- XRRScreenConfiguration *conf = (XRRScreenConfiguration *) (intptr_t) screenConfiguration;
+ Display *dpy = (Display *) (intptr_t) display;
+ Window root = RootWindow(dpy, (int)scrn_idx);
+ // get current resolutions and frequency configuration
+ XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root);
short original_rate = XRRConfigCurrentRate(conf);
Rotation original_rotation;
SizeID original_size_id = XRRConfigCurrentConfiguration(conf, &original_rotation);
+ //free
+ XRRFreeScreenConfigInfo(conf);
+
DBG_PRINT("getCurrentScreenResolutionIndex0: %d\n", (int)original_size_id);
- return (jint)original_size_id;
+ return (jint)original_size_id;
}
/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: setCurrentScreenModeStart0
- * Signature: (JIJIII)Z
+ * Class: jogamp_newt_driver_x11_ScreenDriver
+ * Method: setCurrentScreenModeStart0_RandR13
+ * Signature: (JIIII)Z
*/
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScreenModeStart0
- (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jlong screenConfiguration, jint resMode_idx, jint freq, jint rotation)
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_setCurrentScreenModeStart0_RandR13
+ (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jint resMode_idx, jint freq, jint rotation)
{
Display *dpy = (Display *) (intptr_t) display;
- XRRScreenConfiguration *conf = (XRRScreenConfiguration *) (intptr_t) screenConfiguration;
Window root = RootWindow(dpy, (int)screen_idx);
int num_sizes;
XRRScreenSize *xrrs = XRRSizes(dpy, (int)screen_idx, &num_sizes); //get possible screen resolutions
+ XRRScreenConfiguration *conf;
int rot;
if( 0 > resMode_idx || resMode_idx >= num_sizes ) {
NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes);
}
- switch(rotation) {
- case 0:
- rot = RR_Rotate_0;
- break;
- case 90:
- rot = RR_Rotate_90;
- break;
- case 180:
- rot = RR_Rotate_180;
- break;
- case 270:
- rot = RR_Rotate_270;
- break;
- default:
- NewtCommon_throwNewRuntimeException(env, "Invalid rotation: %d", rotation);
- }
+ conf = XRRGetScreenInfo(dpy, root);
+
+ rot = int NewtScreen_Degree2XRotation(env, rotation);
DBG_PRINT("X11Screen.setCurrentScreenMode0: CHANGED TO %d: %d x %d PIXELS, %d Hz, %d degree\n",
resMode_idx, xrrs[resMode_idx].width, xrrs[resMode_idx].height, (int)freq, rotation);
@@ -428,15 +310,19 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScree
XRRSetScreenConfigAndRate(dpy, conf, root, (int)resMode_idx, rot, (short)freq, CurrentTime);
XSync(dpy, False);
+ //free
+ XRRFreeScreenConfigInfo(conf);
+ XSync(dpy, False);
+
return JNI_TRUE;
}
/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: setCurrentScreenModePollEnd0
+ * Class: jogamp_newt_driver_x11_ScreenDriver
+ * Method: setCurrentScreenModePollEnd0_RandR13
* Signature: (J)Z
*/
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScreenModePollEnd0
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_setCurrentScreenModePollEnd0_RandR13
(JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jint resMode_idx, jint freq, jint rotation)
{
Display *dpy = (Display *) (intptr_t) display;
@@ -444,11 +330,6 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScree
XEvent evt;
XRRScreenChangeNotifyEvent * scn_event = (XRRScreenChangeNotifyEvent *) &evt;
- if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_setCurrentScreenModePollEnd0: RANDR not available\n");
- return JNI_FALSE;
- }
-
int num_sizes;
XRRScreenSize *xrrs = XRRSizes(dpy, (int)screen_idx, &num_sizes); //get possible screen resolutions
XRRScreenConfiguration *conf;
diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c
index daf9f2b..202ad6f 100644
--- a/src/newt/native/X11Window.c
+++ b/src/newt/native/X11Window.c
@@ -467,11 +467,11 @@ static void NewtWindows_requestFocus (JNIEnv *env, jobject window, Display *dpy,
*/
/*
- * Class: jogamp_newt_driver_x11_X11Window
+ * Class: jogamp_newt_driver_x11_WindowDriver
* Method: initIDs
* Signature: ()Z
*/
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Window_initIDs0
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_WindowDriver_initIDs0
(JNIEnv *env, jclass clazz)
{
return JNI_TRUE;
@@ -505,10 +505,10 @@ static void NewtWindows_setPosSize(Display *dpy, Window w, jint x, jint y, jint
}
/*
- * Class: jogamp_newt_driver_x11_X11Window
+ * Class: jogamp_newt_driver_x11_WindowDriver
* Method: CreateWindow
*/
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Window_CreateWindow0
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CreateWindow0
(JNIEnv *env, jobject obj, jlong parent, jlong display, jint screen_index,
jint visualID,
jlong javaObjectAtom, jlong windowDeleteAtom,
@@ -666,11 +666,11 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Window_CreateWindow0
}
/*
- * Class: jogamp_newt_driver_x11_X11Window
+ * Class: jogamp_newt_driver_x11_WindowDriver
* Method: CloseWindow
* Signature: (JJ)V
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_CloseWindow0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CloseWindow0
(JNIEnv *env, jobject obj, jlong display, jlong window, jlong javaObjectAtom, jlong windowDeleteAtom)
{
Display * dpy = (Display *) (intptr_t) display;
@@ -683,16 +683,12 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_CloseWindow0
DBG_PRINT( "X11: CloseWindow START dpy %p, win %p\n", (void*)dpy, (void*)w);
- NewtDisplay_x11ErrorHandlerEnable(env, dpy, 1, 0, 0);
-
jwindow = getJavaWindowProperty(env, dpy, w, javaObjectAtom, True);
if(NULL==jwindow) {
- NewtDisplay_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
NewtCommon_throwNewRuntimeException(env, "could not fetch Java Window object, bail out!");
return;
}
if ( JNI_FALSE == (*env)->IsSameObject(env, jwindow, obj) ) {
- NewtDisplay_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
NewtCommon_throwNewRuntimeException(env, "Internal Error .. Window global ref not the same!");
return;
}
@@ -700,13 +696,12 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_CloseWindow0
XSync(dpy, False);
XSelectInput(dpy, w, 0);
XUnmapWindow(dpy, w);
- NewtDisplay_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
// Drain all events related to this window ..
- Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0(env, obj, display, javaObjectAtom, windowDeleteAtom);
+ Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessages0(env, obj, display, javaObjectAtom, windowDeleteAtom);
XDestroyWindow(dpy, w);
- XSync(dpy, False);
+ XSync(dpy, True); // discard all events now, no more handler
(*env)->DeleteGlobalRef(env, jwindow);
@@ -729,11 +724,11 @@ static Bool WaitForReparentNotify( Display *dpy, XEvent *event, XPointer arg ) {
*/
/*
- * Class: jogamp_newt_driver_x11_X11Window
+ * Class: jogamp_newt_driver_x11_WindowDriver
* Method: reconfigureWindow0
* Signature: (JIJJIIIII)V
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_reconfigureWindow0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindow0
(JNIEnv *env, jobject obj, jlong jdisplay, jint screen_index,
jlong jparent, jlong jwindow, jlong windowDeleteAtom,
jint x, jint y, jint width, jint height, jint flags)
@@ -761,8 +756,6 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_reconfigureWindow0
fsEWMHFlags |= _NET_WM_ABOVE; // toggle above
}
- NewtDisplay_x11ErrorHandlerEnable(env, dpy, 1, 0, 0);
-
DBG_PRINT( "X11: reconfigureWindow0 dpy %p, scrn %d, parent %p/%p, win %p, %d/%d %dx%d, parentChange %d, hasParent %d, decorationChange %d, undecorated %d, fullscreenChange %d, fullscreen %d, alwaysOnTopChange %d, alwaysOnTop %d, visibleChange %d, visible %d, tempInvisible %d, fsEWMHFlags %d\n",
(void*)dpy, screen_index, (void*) jparent, (void*)parent, (void*)w,
x, y, width, height,
@@ -779,7 +772,6 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_reconfigureWindow0
( TST_FLAG_CHANGE_FULLSCREEN(flags) || TST_FLAG_CHANGE_ALWAYSONTOP(flags) ) ) {
Bool enable = TST_FLAG_CHANGE_FULLSCREEN(flags) ? TST_FLAG_IS_FULLSCREEN(flags) : TST_FLAG_IS_ALWAYSONTOP(flags) ;
if( NewtWindows_setFullscreenEWMH(dpy, root, w, fsEWMHFlags, isVisible, enable) ) {
- NewtDisplay_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
#ifdef FS_GRAB_KEYBOARD
if(TST_FLAG_CHANGE_FULLSCREEN(flags)) {
if(TST_FLAG_IS_FULLSCREEN(flags)) {
@@ -863,39 +855,37 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_reconfigureWindow0
#endif
}
- NewtDisplay_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
-
DBG_PRINT( "X11: reconfigureWindow0 X\n");
}
/*
- * Class: jogamp_newt_driver_x11_X11Window
+ * Class: jogamp_newt_driver_x11_WindowDriver
* Method: requestFocus0
* Signature: (JJZ)V
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_requestFocus0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_requestFocus0
(JNIEnv *env, jobject obj, jlong display, jlong window, jboolean force)
{
NewtWindows_requestFocus ( env, obj, (Display *) (intptr_t) display, (Window)window, force ) ;
}
/*
- * Class: jogamp_newt_driver_x11_X11Window
+ * Class: jogamp_newt_driver_x11_WindowDriver
* Method: getParentWindow0
* Signature: (JJ)J
*/
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Window_getParentWindow0
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_WindowDriver_getParentWindow0
(JNIEnv *env, jclass clazz, jlong display, jlong window)
{
return (jlong) NewtWindows_getParent ((Display *) (intptr_t) display, (Window)window);
}
/*
- * Class: Java_jogamp_newt_driver_x11_X11Window
+ * Class: Java_jogamp_newt_driver_x11_WindowDriver
* Method: setTitle0
* Signature: (JJLjava/lang/String;)V
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_setTitle0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_setTitle0
(JNIEnv *env, jclass clazz, jlong display, jlong window, jstring title)
{
Display * dpy = (Display *) (intptr_t) display;
@@ -942,11 +932,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_setTitle0
}
/*
- * Class: Java_jogamp_newt_driver_x11_X11Window
+ * Class: Java_jogamp_newt_driver_x11_WindowDriver
* Method: setPointerVisible0
* Signature: (JJZ)Z
*/
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Window_setPointerVisible0
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_WindowDriver_setPointerVisible0
(JNIEnv *env, jclass clazz, jlong display, jlong window, jboolean mouseVisible)
{
static char noData[] = { 0,0,0,0,0,0,0,0 };
@@ -976,11 +966,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Window_setPointerVisib
}
/*
- * Class: Java_jogamp_newt_driver_x11_X11Window
+ * Class: Java_jogamp_newt_driver_x11_WindowDriver
* Method: confinePointer0
* Signature: (JJZ)Z
*/
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Window_confinePointer0
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_WindowDriver_confinePointer0
(JNIEnv *env, jclass clazz, jlong display, jlong window, jboolean confine)
{
Display * dpy = (Display *) (intptr_t) display;
@@ -999,11 +989,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Window_confinePointer0
}
/*
- * Class: Java_jogamp_newt_driver_x11_X11Window
+ * Class: Java_jogamp_newt_driver_x11_WindowDriver
* Method: warpPointer0
* Signature: (JJII)V
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_warpPointer0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_warpPointer0
(JNIEnv *env, jclass clazz, jlong display, jlong window, jint x, jint y)
{
Display * dpy = (Display *) (intptr_t) display;
diff --git a/src/newt/native/XCBEvent.c b/src/newt/native/XCBEvent.c
new file mode 100644
index 0000000..77a3380
--- /dev/null
+++ b/src/newt/native/XCBEvent.c
@@ -0,0 +1,314 @@
+
+#define VERBOSE_ON 1
+
+#include "XCBEvent.h"
+
+#include <xcb/xcb.h>
+#include <xcb/xcb_event.h>
+#include <xcb/xproto.h>
+#include <xcb/xcb_keysyms.h>
+#include <X11/Xlib-xcb.h>
+
+void XCBSetEventQueueOwner(Display *dpy) {
+ XSetEventQueueOwner(dpy, XCBOwnsEventQueue);
+}
+
+void XCBEventPoll(JNIEnv *env, jobject obj, Display *dpy, jlong javaObjectAtom, jlong wmDeleteAtom) {
+ int num_events = 100;
+ xcb_connection_t *conn = NULL;
+
+ if ( NULL == dpy ) {
+ return;
+ }
+ conn = XGetXCBConnection(dpy);
+
+ // Periodically take a break
+ while( num_events > 0 ) {
+ jobject jwindow = NULL;
+ xcb_generic_event_t *evt;
+ // KeySym keySym = 0;
+ jint modifiers = 0;
+ char keyChar = 0;
+ // char text[255];
+
+ evt = xcb_poll_for_event(conn);
+ if(NULL == evt) {
+ // DBG_PRINT( "X11: DispatchMessages 0x%X - Leave 1\n", dpy);
+ return;
+ }
+ num_events--;
+
+ /*if( 0==evt.xany.window ) {
+ free(evt);
+ NewtCommon_throwNewRuntimeException(env, "event window NULL, bail out!");
+ return ;
+ }
+
+ if(dpy!=evt.xany.display) {
+ free(evt);
+ NewtCommon_throwNewRuntimeException(env, "wrong display, bail out!");
+ return ;
+ }*/
+
+ // DBG_PRINT( "X11: DispatchMessages dpy %p, win %p, Event %d\n", (void*)dpy, (void*)evt.xany.window, evt.type);
+
+ // X11WindowDisplayErrorHandlerEnable(1, env);
+
+ // jwindow = X11WindowGetJavaWindowProperty(env, dpy, evt.xany.window, javaObjectAtom, VERBOSE_BOOL);
+
+ //X11WindowDisplayErrorHandlerEnable(0, env);
+
+ /*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);
+ continue;
+ }*/
+
+ uint8_t xcb_event_type = evt->response_type & ~0x80;
+ xcb_window_t event_window = 0;
+
+ switch( xcb_event_type ) {
+ case XCB_BUTTON_PRESS:
+ case XCB_BUTTON_RELEASE:
+ event_window = ((xcb_button_press_event_t *)evt)->event;
+ modifiers = X11InputState2NewtModifiers(((xcb_button_press_event_t *)evt)->state);
+ break;
+ case XCB_MOTION_NOTIFY:
+ event_window = ((xcb_motion_notify_event_t *)evt)->event;
+ break;
+ case XCB_KEY_PRESS:
+ case XCB_KEY_RELEASE: {
+ xcb_key_press_event_t *_evt = (xcb_key_press_event_t *)evt;
+ event_window = _evt->event;
+ /*
+ xcb_keycode_t detail = _evt->detail;
+ if(XLookupString(&evt.xkey,text,255,&keySym,0)==1) {
+ KeySym lower_return = 0, upper_return = 0;
+ keyChar=text[0];
+ XConvertCase(keySym, &lower_return, &upper_return);
+ // always return upper case, set modifier masks (SHIFT, ..)
+ keySym = upper_return;
+ modifiers = X11InputState2NewtModifiers(evt.xkey.state);
+ } else {
+ keyChar=0;
+ }*/
+ }
+ break;
+ case XCB_EXPOSE:
+ event_window = ((xcb_expose_event_t *)evt)->window;
+ break;
+ case XCB_MAP_NOTIFY:
+ event_window = ((xcb_map_notify_event_t *)evt)->window;
+ break;
+ case XCB_UNMAP_NOTIFY:
+ event_window = ((xcb_unmap_notify_event_t *)evt)->window;
+ break;
+ }
+ if(0==event_window) {
+ fprintf(stderr, "Warning: NEWT X11 DisplayDispatch %p, Couldn't handle event %d, no X11 window associated\n",
+ (void*)dpy, xcb_event_type);
+ continue;
+ }
+ jwindow = getJavaWindowProperty(env, dpy, event_window, javaObjectAtom,
+ #ifdef VERBOSE_ON
+ True
+ #else
+ False
+ #endif
+ );
+ if(NULL==jwindow) {
+ fprintf(stderr, "Warning: NEWT X11 DisplayDispatch %p, Couldn't handle event %d for X11 window %p\n",
+ (void*)(intptr_t)dpy, xcb_event_type, (void*)(intptr_t)event_window);
+ continue;
+ }
+
+ switch( xcb_event_type ) {
+ case XCB_BUTTON_PRESS: {
+ xcb_button_press_event_t *_evt = (xcb_button_press_event_t *)evt;
+ (*env)->CallVoidMethod(env, jwindow, requestFocusID, JNI_FALSE);
+ #ifdef USE_SENDIO_DIRECT
+ (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_PRESSED,
+ modifiers,
+ (jint) _evt->event_x, (jint) _evt->event_y, (jint) _evt->state, 0 /*rotation*/);
+ #else
+ (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, JNI_FALSE, (jint) EVENT_MOUSE_PRESSED,
+ modifiers,
+ (jint) _evt->event_x, (jint) _evt->event_y, (jint) _evt->state, 0 /*rotation*/);
+ #endif
+ } break;
+ case XCB_BUTTON_RELEASE: {
+ xcb_button_release_event_t *_evt = (xcb_button_release_event_t *)evt;
+ #ifdef USE_SENDIO_DIRECT
+ (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_RELEASED,
+ modifiers,
+ (jint) _evt->event_x, (jint) _evt->event_y, (jint) _evt->state, 0 /*rotation*/);
+ #else
+ (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, JNI_FALSE, (jint) EVENT_MOUSE_RELEASED,
+ modifiers,
+ (jint) _evt->event_x, (jint) _evt->event_y, (jint) _evt->state, 0 /*rotation*/);
+ #endif
+ } break;
+ case XCB_MOTION_NOTIFY: {
+ xcb_motion_notify_event_t *_evt = (xcb_motion_notify_event_t *)evt;
+ #ifdef USE_SENDIO_DIRECT
+ (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_MOVED,
+ modifiers,
+ (jint) _evt->event_x, (jint) _evt->event_y, (jint)0, 0 /*rotation*/);
+ #else
+ (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, JNI_FALSE, (jint) EVENT_MOUSE_MOVED,
+ modifiers,
+ (jint) _evt->event_x, (jint) _evt->event_y, (jint)0, 0 /*rotation*/);
+ #endif
+ } break;
+ case XCB_KEY_PRESS: {
+ xcb_key_press_event_t *_evt = (xcb_key_press_event_t *)evt;
+ #ifdef USE_SENDIO_DIRECT
+ (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_PRESSED,
+ modifiers, X11KeySym2NewtVKey(_evt->state), (jchar) keyChar);
+ #else
+ (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, JNI_FALSE, (jint) EVENT_KEY_PRESSED,
+ modifiers, X11KeySym2NewtVKey(_evt->state), (jchar) keyChar);
+ #endif
+ } break;
+ case XCB_KEY_RELEASE: {
+ xcb_key_release_event_t *_evt = (xcb_key_release_event_t *)evt;
+ event_window = ((xcb_key_release_event_t *)evt)->event;
+ #ifdef USE_SENDIO_DIRECT
+ (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_RELEASED,
+ modifiers, X11KeySym2NewtVKey(_evt->state), (jchar) keyChar);
+
+ (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_TYPED,
+ modifiers, (jint) -1, (jchar) keyChar);
+ #else
+ (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, JNI_FALSE, (jint) EVENT_KEY_RELEASED,
+ modifiers, X11KeySym2NewtVKey(_evt->state), (jchar) keyChar);
+
+ (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, JNI_FALSE, (jint) EVENT_KEY_TYPED,
+ modifiers, (jint) -1, (jchar) keyChar);
+ #endif
+
+ } break;
+ /*
+ case DestroyNotify:
+ DBG_PRINT( "X11: event . DestroyNotify call %p, parent %p, child-event: %d\n",
+ (void*)evt.xdestroywindow.window, (void*)evt.xdestroywindow.event, evt.xdestroywindow.window != evt.xdestroywindow.event);
+ if ( evt.xdestroywindow.window == evt.xdestroywindow.event ) {
+ // ignore child destroy notification
+ }
+ break;
+ case CreateNotify:
+ DBG_PRINT( "X11: event . CreateNotify call %p, parent %p, child-event: 1\n",
+ (void*)evt.xcreatewindow.window, (void*) evt.xcreatewindow.parent);
+ break;
+ case ConfigureNotify:
+ DBG_PRINT( "X11: event . ConfigureNotify call %p (parent %p, above %p) %d/%d %dx%d %d, child-event: %d\n",
+ (void*)evt.xconfigure.window, (void*)evt.xconfigure.event, (void*)evt.xconfigure.above,
+ evt.xconfigure.x, evt.xconfigure.y, evt.xconfigure.width, evt.xconfigure.height,
+ evt.xconfigure.override_redirect, evt.xconfigure.window != evt.xconfigure.event);
+ if ( evt.xconfigure.window == evt.xconfigure.event ) {
+ // ignore child window change notification
+ (*env)->CallVoidMethod(env, jwindow, sizeChangedID,
+ (jint) evt.xconfigure.width, (jint) evt.xconfigure.height, JNI_FALSE);
+ (*env)->CallVoidMethod(env, jwindow, positionChangedID,
+ (jint) evt.xconfigure.x, (jint) evt.xconfigure.y);
+ }
+ break;
+ case ClientMessage:
+ if (evt.xclient.send_event==True && evt.xclient.data.l[0]==(Atom)wmDeleteAtom) {
+ DBG_PRINT( "X11: event . ClientMessage call %p type 0x%X !!!\n",
+ (void*)evt.xclient.window, (unsigned int)evt.xclient.message_type);
+ (*env)->CallVoidMethod(env, jwindow, windowDestroyNotifyID);
+ // Called by Window.java: CloseWindow();
+ num_events = 0; // end loop in case of destroyed display
+ }
+ break;
+
+ case FocusIn:
+ DBG_PRINT( "X11: event . FocusIn call %p\n", (void*)evt.xvisibility.window);
+ (*env)->CallVoidMethod(env, jwindow, focusChangedID, JNI_TRUE);
+ break;
+
+ case FocusOut:
+ DBG_PRINT( "X11: event . FocusOut call %p\n", (void*)evt.xvisibility.window);
+ (*env)->CallVoidMethod(env, jwindow, focusChangedID, JNI_FALSE);
+ break;
+ */
+
+ case XCB_EXPOSE: {
+ xcb_expose_event_t *_evt = (xcb_expose_event_t *)evt;
+ DBG_PRINT( "X11: event . Expose call %p %d/%d %dx%d count %d\n", (void*)(intptr_t)_evt->window,
+ _evt->x, _evt->y, _evt->width, _evt->height, _evt->count);
+
+ if (_evt->count == 0 && _evt->width > 0 && _evt->height > 0) {
+ (*env)->CallVoidMethod(env, jwindow, windowRepaintID,
+ _evt->x, _evt->y, _evt->width, _evt->height);
+ }
+ } break;
+
+ case XCB_MAP_NOTIFY: {
+ xcb_map_notify_event_t *_evt = (xcb_map_notify_event_t *)evt;
+ DBG_PRINT( "X11: event . MapNotify call Event %p, Window %p, override_redirect %d, child-event: %d\n",
+ (void*)(intptr_t)_evt->event, (void*)(intptr_t)_evt->window, (int)_evt->override_redirect,
+ _evt->event!=_evt->window);
+ if( _evt->event == _evt->window ) {
+ // ignore child window notification
+ (*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_TRUE);
+ }
+ } break;
+
+ case XCB_UNMAP_NOTIFY: {
+ xcb_unmap_notify_event_t *_evt = (xcb_unmap_notify_event_t *)evt;
+ DBG_PRINT( "X11: event . UnmapNotify call Event %p, Window %p, child-event: %d\n",
+ (void*)(intptr_t)_evt->event, (void*)(intptr_t)_evt->window,
+ _evt->event!=_evt->window);
+ if( _evt->event == _evt->window ) {
+ // ignore child window notification
+ (*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_FALSE);
+ }
+ } break;
+ /*
+
+ case ReparentNotify:
+ {
+ jlong parentResult; // 0 if root, otherwise proper value
+ Window winRoot, winTopParent;
+ #ifdef VERBOSE_ON
+ Window oldParentRoot, oldParentTopParent;
+ Window parentRoot, parentTopParent;
+ if( 0 == NewtWindows_getRootAndParent(dpy, evt.xreparent.event, &oldParentRoot, &oldParentTopParent) ) {
+ oldParentRoot=0; oldParentTopParent = 0;
+ }
+ if( 0 == NewtWindows_getRootAndParent(dpy, evt.xreparent.parent, &parentRoot, &parentTopParent) ) {
+ parentRoot=0; parentTopParent = 0;
+ }
+ #endif
+ if( 0 == NewtWindows_getRootAndParent(dpy, evt.xreparent.window, &winRoot, &winTopParent) ) {
+ winRoot=0; winTopParent = 0;
+ }
+ if(evt.xreparent.parent == winRoot) {
+ parentResult = 0; // our java indicator for root window
+ } else {
+ parentResult = (jlong) (intptr_t) evt.xreparent.parent;
+ }
+ #ifdef VERBOSE_ON
+ DBG_PRINT( "X11: event . ReparentNotify: call OldParent %p (root %p, top %p), NewParent %p (root %p, top %p), Window %p (root %p, top %p)\n",
+ (void*)evt.xreparent.event, (void*)oldParentRoot, (void*)oldParentTopParent,
+ (void*)evt.xreparent.parent, (void*)parentRoot, (void*)parentTopParent,
+ (void*)evt.xreparent.window, (void*)winRoot, (void*)winTopParent);
+ #endif
+
+ (*env)->CallVoidMethod(env, jwindow, windowReparentedID, parentResult);
+ }
+ break;
+ */
+
+ // unhandled events .. yet ..
+
+ default:
+ DBG_PRINT("XCB: event . unhandled %d 0x%X call %p\n", (int)xcb_event_type, (unsigned int)xcb_event_type, (void*)(intptr_t)event_window);
+ }
+ free(evt);
+ }
+}
+
+
diff --git a/src/newt/native/XCBEvent.h b/src/newt/native/XCBEvent.h
new file mode 100644
index 0000000..d707975
--- /dev/null
+++ b/src/newt/native/XCBEvent.h
@@ -0,0 +1,10 @@
+
+#ifndef _XCBEvent_h
+#define _XCBEvent_h
+
+#include "X11Common.h"
+
+extern void XCBSetEventQueueOwner(Display *dpy);
+extern void XCBEventPoll(JNIEnv *env, jobject obj, Display *dpy, jlong javaObjectAtom, jlong wmDeleteAtom);
+
+#endif /* _XCBDisplayXCBEvent_h */
diff --git a/src/newt/native/BroadcomEGL.c b/src/newt/native/bcm_egl.c
similarity index 90%
rename from src/newt/native/BroadcomEGL.c
rename to src/newt/native/bcm_egl.c
index df6aca6..9b960d2 100644
--- a/src/newt/native/BroadcomEGL.c
+++ b/src/newt/native/bcm_egl.c
@@ -37,7 +37,7 @@
#include <stdio.h>
#include <string.h>
-#include "jogamp_newt_driver_broadcom_egl_Window.h"
+#include "jogamp_newt_driver_bcm_egl_WindowDriver.h"
#include "MouseEvent.h"
#include "KeyEvent.h"
@@ -67,7 +67,7 @@ static jmethodID windowCreatedID = NULL;
* Display
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_broadcom_egl_Display_DispatchMessages
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_egl_DisplayDriver_DispatchMessages
(JNIEnv *env, jobject obj)
{
// FIXME: n/a
@@ -75,7 +75,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_broadcom_egl_Display_DispatchMess
(void) obj;
}
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_broadcom_egl_Display_CreateDisplay
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_bcm_egl_DisplayDriver_CreateDisplay
(JNIEnv *env, jobject obj, jint width, jint height)
{
(void) env;
@@ -89,7 +89,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_broadcom_egl_Display_CreateDispl
return (jlong) (intptr_t) dpy;
}
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_broadcom_egl_Display_DestroyDisplay
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_egl_DisplayDriver_DestroyDisplay
(JNIEnv *env, jobject obj, jlong display)
{
EGLDisplay dpy = (EGLDisplay)(intptr_t)display;
@@ -106,7 +106,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_broadcom_egl_Display_DestroyDispl
* Window
*/
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_broadcom_egl_Window_initIDs
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_bcm_egl_WindowDriver_initIDs
(JNIEnv *env, jclass clazz)
{
windowCreatedID = (*env)->GetMethodID(env, clazz, "windowCreated", "(III)V");
@@ -118,7 +118,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_broadcom_egl_Window_initIDs
return JNI_TRUE;
}
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_broadcom_egl_Window_CreateWindow
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_bcm_egl_WindowDriver_CreateWindow
(JNIEnv *env, jobject obj, jlong display, jboolean chromaKey, jint width, jint height)
{
EGLDisplay dpy = (EGLDisplay)(intptr_t)display;
@@ -162,7 +162,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_broadcom_egl_Window_CreateWindow
return (jlong) (intptr_t) window;
}
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_broadcom_egl_Window_CloseWindow
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_egl_WindowDriver_CloseWindow
(JNIEnv *env, jobject obj, jlong display, jlong window)
{
EGLDisplay dpy = (EGLDisplay) (intptr_t) display;
@@ -175,7 +175,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_broadcom_egl_Window_CloseWindow
DBG_PRINT( "[CloseWindow] X\n");
}
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_broadcom_egl_Window_SwapWindow
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_egl_WindowDriver_SwapWindow
(JNIEnv *env, jobject obj, jlong display, jlong window)
{
EGLDisplay dpy = (EGLDisplay) (intptr_t) display;
diff --git a/src/newt/native/bcm_vc_iv.c b/src/newt/native/bcm_vc_iv.c
new file mode 100644
index 0000000..0093da4
--- /dev/null
+++ b/src/newt/native/bcm_vc_iv.c
@@ -0,0 +1,219 @@
+/**
+ * Copyright 2012 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community OR
+ * CONTRIBUTORS 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.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "bcm_vc_iv.h"
+
+#include "jogamp_newt_driver_bcm_vc_iv_DisplayDriver.h"
+#include "jogamp_newt_driver_bcm_vc_iv_ScreenDriver.h"
+#include "jogamp_newt_driver_bcm_vc_iv_WindowDriver.h"
+
+#define VERBOSE_ON 1
+
+#ifdef VERBOSE_ON
+ #define DBG_PRINT(...) fprintf(stdout, __VA_ARGS__)
+#else
+ #define DBG_PRINT(...)
+#endif
+
+static jmethodID setScreenSizeID = NULL;
+
+static jmethodID windowCreatedID = NULL;
+static jmethodID sizeChangedID = NULL;
+static jmethodID visibleChangedID = NULL;
+static jmethodID windowDestroyNotifyID = NULL;
+static jmethodID sendMouseEventID = NULL;
+static jmethodID sendKeyEventID = NULL;
+
+/**
+ * Display
+ */
+
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_bcm_vc_iv_DisplayDriver_initIDs
+ (JNIEnv *env, jclass clazz)
+{
+ bcm_host_init();
+ // TODO: bcm_host_deinit();
+ DBG_PRINT( "BCM.Display initIDs ok\n" );
+ return JNI_TRUE;
+}
+
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_vc_iv_DisplayDriver_DispatchMessages
+ (JNIEnv *env, jobject obj)
+{
+}
+
+/**
+ * Screen
+ */
+
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_bcm_vc_iv_ScreenDriver_initIDs
+ (JNIEnv *env, jclass clazz)
+{
+ uint32_t screen_width;
+ uint32_t screen_height;
+ int32_t success = 0;
+
+ setScreenSizeID = (*env)->GetMethodID(env, clazz, "setScreenSize", "(II)V");
+ if (setScreenSizeID == NULL) {
+ DBG_PRINT( "BCM.Screen initIDs FALSE\n" );
+ return JNI_FALSE;
+ }
+ DBG_PRINT( "BCM.Screen initIDs ok\n" );
+ return JNI_TRUE;
+}
+
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_vc_iv_ScreenDriver_initNative
+ (JNIEnv *env, jobject obj)
+{
+ uint32_t screen_width;
+ uint32_t screen_height;
+ int32_t success = 0;
+
+ if( graphics_get_display_size(0 /* LCD */, &screen_width, &screen_height) >= 0 ) {
+ DBG_PRINT( "BCM.Screen initNative ok %dx%d\n", screen_width, screen_height );
+ (*env)->CallVoidMethod(env, obj, setScreenSizeID, (jint) screen_width, (jint) screen_height);
+ } else {
+ DBG_PRINT( "BCM.Screen initNative failed\n" );
+ }
+}
+
+/**
+ * Window
+ */
+
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_bcm_vc_iv_WindowDriver_initIDs
+ (JNIEnv *env, jclass clazz)
+{
+ windowCreatedID = (*env)->GetMethodID(env, clazz, "windowCreated", "(J)V");
+ sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(ZIIZ)V");
+ visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(ZZ)V");
+ windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "(Z)Z");
+ sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIIII)V");
+ sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V");
+ if (windowCreatedID == NULL ||
+ sizeChangedID == NULL ||
+ visibleChangedID == NULL ||
+ windowDestroyNotifyID == NULL ||
+ sendMouseEventID == NULL ||
+ sendKeyEventID == NULL) {
+ DBG_PRINT( "initIDs failed\n" );
+ return JNI_FALSE;
+ }
+ DBG_PRINT( "BCM.Window initIDs ok\n" );
+ return JNI_TRUE;
+}
+
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_bcm_vc_iv_WindowDriver_CreateWindow
+ (JNIEnv *env, jobject obj, jint width, jint height, jboolean opaque, jint alphaBits)
+{
+ int32_t success = 0;
+ VC_RECT_T dst_rect;
+ VC_RECT_T src_rect;
+
+ dst_rect.x = 0;
+ dst_rect.y = 0;
+ dst_rect.width = width;
+ dst_rect.height = height;
+
+ src_rect.x = 0;
+ src_rect.y = 0;
+ src_rect.width = width << 16;
+ src_rect.height = height << 16;
+
+ VC_DISPMANX_ALPHA_T dispman_alpha;
+ memset(&dispman_alpha, 0x0, sizeof(VC_DISPMANX_ALPHA_T));
+
+ if( JNI_TRUE == opaque ) {
+ dispman_alpha.flags = DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS ;
+ dispman_alpha.opacity = 0xFF;
+ dispman_alpha.mask = 0;
+ } else {
+ dispman_alpha.flags = DISPMANX_FLAGS_ALPHA_FROM_SOURCE ;
+ dispman_alpha.opacity = 0xFF;
+ dispman_alpha.mask = 0xFF;
+ }
+
+ DISPMANX_DISPLAY_HANDLE_T dispman_display = vc_dispmanx_display_open( 0 /* LCD */);
+ DISPMANX_UPDATE_HANDLE_T dispman_update = vc_dispmanx_update_start( 0 );
+ DISPMANX_ELEMENT_HANDLE_T dispman_element = vc_dispmanx_element_add ( dispman_update, dispman_display,
+ 0/*layer*/, &dst_rect, 0/*src*/,
+ &src_rect, DISPMANX_PROTECTION_NONE,
+ &dispman_alpha /*alpha */, 0/*clamp*/, 0/*transform*/);
+
+ EGL_DISPMANX_WINDOW_T * nativeWindowPtr = calloc(1, sizeof(EGL_DISPMANX_WINDOW_T));
+ nativeWindowPtr->element = dispman_element;
+ nativeWindowPtr->width = width;
+ nativeWindowPtr->height = height;
+
+ vc_dispmanx_update_submit_sync( dispman_update );
+
+ (*env)->CallVoidMethod(env, obj, visibleChangedID, JNI_FALSE, JNI_TRUE); // FIXME: or defer=true ?
+
+ return (jlong) (intptr_t) nativeWindowPtr;
+}
+
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_bcm_vc_iv_WindowDriver_RealizeWindow
+ (JNIEnv *env, jobject obj, jlong window)
+{
+ return (jlong) (intptr_t) 0;
+}
+
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_bcm_vc_iv_WindowDriver_CloseWindow
+ (JNIEnv *env, jobject obj, jlong window, jlong juserData)
+{
+ EGL_DISPMANX_WINDOW_T * nativeWindowPtr = (EGL_DISPMANX_WINDOW_T *) (intptr_t) window ;
+ free( nativeWindowPtr );
+ return 0;
+}
+
+/*
+ * Class: jogamp_newt_driver_bcm_vc_iv_WindowDriver
+ * Method: setVisible0
+ * Signature: (JJZ)V
+ */
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_vc_iv_WindowDriver_setVisible0
+ (JNIEnv *env, jobject obj, jlong window, jboolean visible)
+{
+}
+
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_vc_iv_WindowDriver_setFullScreen0
+ (JNIEnv *env, jobject obj, jlong window, jboolean fullscreen)
+{
+}
+
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_vc_iv_WindowDriver_setSize0
+ (JNIEnv *env, jobject obj, jlong window, jint width, jint height)
+{
+ // FIXME RESIZE (*env)->CallVoidMethod(env, obj, sizeChangedID, JNI_FALSE, (jint) width, (jint) height, JNI_FALSE);
+}
+
+
diff --git a/src/newt/native/bcm_vc_iv.h b/src/newt/native/bcm_vc_iv.h
new file mode 100644
index 0000000..b43483c
--- /dev/null
+++ b/src/newt/native/bcm_vc_iv.h
@@ -0,0 +1,187 @@
+/**
+ * Copyright 2012 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community OR
+ * CONTRIBUTORS 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.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+#ifndef BCM_VC_IV_H
+#define BCM_VC_IV_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+typedef uint32_t DISPMANX_PROTECTION_T;
+typedef uint32_t DISPMANX_RESOURCE_HANDLE_T;
+typedef uint32_t DISPMANX_DISPLAY_HANDLE_T;
+typedef uint32_t DISPMANX_UPDATE_HANDLE_T;
+typedef uint32_t DISPMANX_ELEMENT_HANDLE_T;
+
+#define DISPMANX_NO_HANDLE 0
+
+#define DISPMANX_PROTECTION_MAX 0x0f
+#define DISPMANX_PROTECTION_NONE 0
+#define DISPMANX_PROTECTION_HDCP 11 // Derived from the WM DRM levels, 101-300
+
+
+
+/* Default display IDs.
+ Note: if you overwrite with you own dispmanx_platfrom_init function, you
+ should use IDs you provided during dispmanx_display_attach.
+*/
+#define DISPMANX_ID_MAIN_LCD 0
+#define DISPMANX_ID_AUX_LCD 1
+#define DISPMANX_ID_HDMI 2
+#define DISPMANX_ID_SDTV 3
+
+/* Return codes. Nonzero ones indicate failure. */
+typedef enum {
+ DISPMANX_SUCCESS = 0,
+ DISPMANX_INVALID = -1
+ /* XXX others TBA */
+} DISPMANX_STATUS_T;
+
+typedef enum {
+ /* Bottom 2 bits sets the orientation */
+ DISPMANX_NO_ROTATE = 0,
+ DISPMANX_ROTATE_90 = 1,
+ DISPMANX_ROTATE_180 = 2,
+ DISPMANX_ROTATE_270 = 3,
+
+ DISPMANX_FLIP_HRIZ = 1 << 16,
+ DISPMANX_FLIP_VERT = 1 << 17
+} DISPMANX_TRANSFORM_T;
+
+typedef enum {
+ /* Bottom 2 bits sets the alpha mode */
+ DISPMANX_FLAGS_ALPHA_FROM_SOURCE = 0,
+ DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS = 1,
+ DISPMANX_FLAGS_ALPHA_FIXED_NON_ZERO = 2,
+ DISPMANX_FLAGS_ALPHA_FIXED_EXCEED_0X07 = 3,
+
+ DISPMANX_FLAGS_ALPHA_PREMULT = 1 << 16,
+ DISPMANX_FLAGS_ALPHA_MIX = 1 << 17
+} DISPMANX_FLAGS_ALPHA_T;
+
+struct VC_IMAGE_T;
+typedef struct VC_IMAGE_T VC_IMAGE_T;
+
+typedef struct {
+ DISPMANX_FLAGS_ALPHA_T flags;
+ uint32_t opacity;
+ VC_IMAGE_T *mask;
+} DISPMANX_ALPHA_T;
+
+typedef struct {
+ DISPMANX_FLAGS_ALPHA_T flags;
+ uint32_t opacity;
+ DISPMANX_RESOURCE_HANDLE_T mask;
+} VC_DISPMANX_ALPHA_T; /* for use with vmcs_host */
+
+
+typedef enum {
+ DISPMANX_FLAGS_CLAMP_NONE = 0,
+ DISPMANX_FLAGS_CLAMP_LUMA_TRANSPARENT = 1,
+#if __VCCOREVER__ >= 0x04000000
+ DISPMANX_FLAGS_CLAMP_TRANSPARENT = 2,
+ DISPMANX_FLAGS_CLAMP_REPLACE = 3
+#else
+ DISPMANX_FLAGS_CLAMP_CHROMA_TRANSPARENT = 2,
+ DISPMANX_FLAGS_CLAMP_TRANSPARENT = 3
+#endif
+} DISPMANX_FLAGS_CLAMP_T;
+
+typedef enum {
+ DISPMANX_FLAGS_KEYMASK_OVERRIDE = 1,
+ DISPMANX_FLAGS_KEYMASK_SMOOTH = 1 << 1,
+ DISPMANX_FLAGS_KEYMASK_CR_INV = 1 << 2,
+ DISPMANX_FLAGS_KEYMASK_CB_INV = 1 << 3,
+ DISPMANX_FLAGS_KEYMASK_YY_INV = 1 << 4
+} DISPMANX_FLAGS_KEYMASK_T;
+
+typedef union {
+ struct {
+ uint8_t yy_upper;
+ uint8_t yy_lower;
+ uint8_t cr_upper;
+ uint8_t cr_lower;
+ uint8_t cb_upper;
+ uint8_t cb_lower;
+ } yuv;
+ struct {
+ uint8_t red_upper;
+ uint8_t red_lower;
+ uint8_t blue_upper;
+ uint8_t blue_lower;
+ uint8_t green_upper;
+ uint8_t green_lower;
+ } rgb;
+} DISPMANX_CLAMP_KEYS_T;
+
+typedef struct {
+ DISPMANX_FLAGS_CLAMP_T mode;
+ DISPMANX_FLAGS_KEYMASK_T key_mask;
+ DISPMANX_CLAMP_KEYS_T key_value;
+ uint32_t replace_value;
+} DISPMANX_CLAMP_T;
+
+
+typedef struct {
+ DISPMANX_ELEMENT_HANDLE_T element;
+ int width; /* This is necessary because dispmanx elements are not queriable. */
+ int height;
+} EGL_DISPMANX_WINDOW_T;
+
+typedef struct tag_VC_RECT_T {
+ int32_t x;
+ int32_t y;
+ int32_t width;
+ int32_t height;
+} VC_RECT_T;
+
+extern void bcm_host_init(void);
+extern void bcm_host_deinit(void);
+
+extern int32_t graphics_get_display_size( const uint16_t display_number,
+ uint32_t *width,
+ uint32_t *height);
+
+extern DISPMANX_DISPLAY_HANDLE_T vc_dispmanx_display_open( uint32_t device );
+extern DISPMANX_UPDATE_HANDLE_T vc_dispmanx_update_start( int32_t priority );
+extern DISPMANX_ELEMENT_HANDLE_T vc_dispmanx_element_add ( DISPMANX_UPDATE_HANDLE_T update, DISPMANX_DISPLAY_HANDLE_T display,
+ int32_t layer, const VC_RECT_T *dest_rect, DISPMANX_RESOURCE_HANDLE_T src,
+ const VC_RECT_T *src_rect, DISPMANX_PROTECTION_T protection,
+ VC_DISPMANX_ALPHA_T *alpha,
+ DISPMANX_CLAMP_T *clamp, DISPMANX_TRANSFORM_T transform );
+
+extern int vc_dispmanx_update_submit_sync( DISPMANX_UPDATE_HANDLE_T update );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/test-native/contextRetargetDrawable01.c b/src/test-native/contextRetargetDrawable01.c
new file mode 100644
index 0000000..bad6c66
--- /dev/null
+++ b/src/test-native/contextRetargetDrawable01.c
@@ -0,0 +1,154 @@
+/**
+ * compile with: gcc -o contextRetargetDrawable01 contextRetargetDrawable01.c -lX11 -lGL
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <GL/glx.h>
+#include <GL/gl.h>
+
+static PFNGLXSWAPINTERVALSGIPROC _glXSwapIntervalSGI = NULL;
+
+static void testRetarget();
+
+static const char * msg = "contextRetargetDrawable01";
+
+static const useconds_t demodelay = 2 * 1000 * 1000;
+
+int main(int nargs, char **vargs) {
+ _glXSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC) glXGetProcAddressARB("glXSwapIntervalSGI");
+ if(NULL == _glXSwapIntervalSGI) {
+ fprintf(stderr, "No glXSwapIntervalSGI avail, bail out\n");
+ return 1;
+ }
+ testRetarget();
+ return 0;
+}
+
+static void createGLWin(Display *dpy, int width, int height, Window *rWin, GLXContext *rCtx);
+static void useGL(Display *dpy, Window win, GLXContext ctx, int width, int height, float c, int swapInterval);
+
+static void testRetarget() {
+ int major, minor;
+ Display *disp1;
+ Window win1;
+ GLXContext ctx1;
+
+ Display *disp2;
+ Window win2;
+ GLXContext ctx2;
+
+ fprintf(stderr, "%s: Create #1\n", msg);
+ disp1 = XOpenDisplay(NULL);
+ createGLWin(disp1, 200, 200, &win1, &ctx1);
+
+ fprintf(stderr, "%s: Create #2\n", msg);
+ disp2 = disp1;
+ // disp2 = XOpenDisplay(NULL);
+ createGLWin(disp2, 300, 300, &win2, &ctx2);
+
+ fprintf(stderr, "%s: Use #1.1\n", msg);
+ useGL(disp1, win1, ctx1, 200, 200, 0.0f, 1); // OK
+
+ fprintf(stderr, "%s: Use #1.2\n", msg);
+ useGL(disp2, win2, ctx2, 300, 300, 1.0f, 1); // OK
+
+ usleep( demodelay );
+
+ fprintf(stderr, "%s: Retarget Drawable\n", msg);
+ {
+ Window _win = win2;
+ win2 = win1;
+ win1 = _win;
+ }
+
+ fprintf(stderr, "%s: Use #2.1\n", msg);
+ useGL(disp1, win1, ctx1, 200, 200, 0.0f, 0); // no setSwapInterval - OK
+
+ fprintf(stderr, "%s: Use #2.2\n", msg);
+ useGL(disp2, win2, ctx2, 300, 300, 1.0f, 0); // no setSwapInterval - OK
+
+ usleep( demodelay );
+
+ fprintf(stderr, "%s: Use #3.1\n", msg);
+ useGL(disp1, win1, ctx1, 200, 200, 0.1f, 1); // setSwapInterval - crash on Mesa 8.0.4 DRI2
+
+ fprintf(stderr, "%s: Use #3.2\n", msg);
+ useGL(disp2, win2, ctx2, 300, 300, 0.9f, 1); // setSwapInterval - crash on Mesa 8.0.4 DRI2
+
+ fprintf(stderr, "%s: Success - no bug\n", msg);
+
+ usleep( demodelay );
+
+ fprintf(stderr, "%s: Destroy #1.0\n", msg);
+ glXMakeContextCurrent(disp1, 0, 0, 0);
+ glXDestroyContext(disp1, ctx1);
+ if( disp1 != disp2 ) {
+ XCloseDisplay(disp1);
+ }
+ fprintf(stderr, "%s: Destroy #1.X\n", msg);
+
+ fprintf(stderr, "%s: Destroy #2.0\n", msg);
+ glXMakeContextCurrent(disp2, 0, 0, 0);
+ glXDestroyContext(disp2, ctx2);
+ XCloseDisplay(disp2);
+ fprintf(stderr, "%s: Destroy #2.X\n", msg);
+
+ fprintf(stderr, "%s: Exit - OK\n", msg);
+}
+
+static void useGL(Display *dpy, Window win, GLXContext ctx, int width, int height, float c, int swapInterval)
+{
+ glXMakeContextCurrent(dpy, win, win, ctx);
+ glViewport(0, 0, width, height);
+ if(0 < swapInterval) {
+ fprintf(stderr, "%s: glXSwapIntervalSGI(1)\n", msg);
+ _glXSwapIntervalSGI(1); // offending op after retargeting drawable
+ }
+ fprintf(stderr, "GL_VENDOR: %s\n", glGetString(GL_VENDOR));
+ fprintf(stderr, "GL_VERSION: %s\n", glGetString(GL_VERSION));
+ fprintf(stderr, "GL_RENDERER: %s\n", glGetString(GL_RENDERER));
+ glClearColor(c, c, c, 0.0f);
+ glClearDepth(1.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glXSwapBuffers(dpy, win);
+ glXMakeContextCurrent(dpy, 0, 0, 0);
+}
+
+/* attributes for a double buffered visual in RGBA format with at least
+ * 4 bits per color and a 16 bit depth buffer */
+static int attrListDbl[] = { GLX_RGBA, GLX_DOUBLEBUFFER,
+ GLX_RED_SIZE, 4,
+ GLX_GREEN_SIZE, 4,
+ GLX_BLUE_SIZE, 4,
+ GLX_DEPTH_SIZE, 16,
+ None };
+
+static void createGLWin(Display *dpy, int width, int height, Window *rWin, GLXContext *rCtx)
+{
+ int screen = DefaultScreen(dpy);
+ XVisualInfo *vi = glXChooseVisual(dpy, screen, attrListDbl);
+ Colormap cmap;
+ XSetWindowAttributes attr;
+
+ /* create a GLX context */
+ *rCtx = glXCreateContext(dpy, vi, 0, GL_TRUE);
+
+ /* create a color map */
+ cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual, AllocNone);
+ attr.colormap = cmap;
+ attr.border_pixel = 0;
+
+ /* create a window in window mode*/
+ attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask |
+ StructureNotifyMask;
+ *rWin = XCreateWindow(dpy, RootWindow(dpy, vi->screen),
+ 0, 0, width, height, 0, vi->depth, InputOutput, vi->visual,
+ CWBorderPixel | CWColormap | CWEventMask, &attr);
+
+ XMapRaised(dpy, *rWin);
+}
+
diff --git a/src/test-native/contextRetargetDrawable02.c b/src/test-native/contextRetargetDrawable02.c
new file mode 100644
index 0000000..3d0807b
--- /dev/null
+++ b/src/test-native/contextRetargetDrawable02.c
@@ -0,0 +1,382 @@
+/**
+ * compile with: gcc -o contextRetargetDrawable02 contextRetargetDrawable02.c -lX11 -lGL
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <GL/glx.h>
+#include <GL/gl.h>
+
+typedef int bool;
+#define true 1
+#define false 0
+
+static PFNGLXSWAPINTERVALSGIPROC _glXSwapIntervalSGI = NULL;
+
+static void testRetarget(bool reverse);
+
+static const char * msg = "contextRetargetDrawable01";
+
+static const useconds_t demodelay = 2 * 1000 * 1000;
+
+int main(int nargs, char **vargs) {
+ _glXSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC) glXGetProcAddressARB("glXSwapIntervalSGI");
+ if(NULL == _glXSwapIntervalSGI) {
+ fprintf(stderr, "No glXSwapIntervalSGI avail, bail out\n");
+ return 1;
+ }
+ testRetarget(false);
+ return 0;
+}
+
+static void createGLWin(Display *dpy, int width, int height, Window *rWin, GLXContext *rCtx);
+static void useGL(Display *dpy, Window win, GLXContext ctx, int width, int height, float c, int swapInterval);
+
+static void testRetarget(bool reverse) {
+ int major, minor;
+ Display *disp1;
+ Window win1;
+ GLXContext ctx1;
+
+ Display *disp2;
+ Window win2;
+ GLXContext ctx2;
+
+ fprintf(stderr, "%s: Create #1\n", msg);
+ disp1 = XOpenDisplay(NULL);
+ createGLWin(disp1, 200, 200, &win1, &ctx1);
+
+ fprintf(stderr, "%s: Create #2\n", msg);
+ disp2 = disp1;
+ // disp2 = XOpenDisplay(NULL);
+ createGLWin(disp2, 300, 300, &win2, &ctx2);
+
+ fprintf(stderr, "%s: Use #1.1\n", msg);
+ useGL(disp1, win1, ctx1, 200, 200, 0.0f, 1); // OK
+
+ fprintf(stderr, "%s: Use #1.2\n", msg);
+ useGL(disp2, win2, ctx2, 300, 300, 1.0f, 1); // OK
+
+ usleep( demodelay );
+
+ fprintf(stderr, "%s: Retarget Drawable\n", msg);
+ {
+ GLXContext _ctx = ctx2;
+ ctx2 = ctx1;
+ ctx1 = _ctx;
+ }
+
+ /**
+ if(reverse) {
+ fprintf(stderr, "%s: Use #2.2\n", msg);
+ useGL(disp2, win2, ctx2, 300, 300, 1.0f, 0); // no setSwapInterval - OK
+
+ fprintf(stderr, "%s: Use #2.1\n", msg);
+ useGL(disp1, win1, ctx1, 200, 200, 0.0f, 0); // no setSwapInterval - OK
+ } else {
+ fprintf(stderr, "%s: Use #2.1\n", msg);
+ useGL(disp1, win1, ctx1, 200, 200, 0.0f, 0); // no setSwapInterval - OK
+
+ fprintf(stderr, "%s: Use #2.2\n", msg);
+ useGL(disp2, win2, ctx2, 300, 300, 1.0f, 0); // no setSwapInterval - OK
+ }
+ usleep( demodelay ); */
+
+ if(reverse) {
+ fprintf(stderr, "%s: Use #3.2\n", msg);
+ useGL(disp2, win2, ctx2, 300, 300, 0.9f, 1); // setSwapInterval - crash on Mesa 8.0.4 DRI2
+
+ fprintf(stderr, "%s: Use #3.1\n", msg);
+ useGL(disp1, win1, ctx1, 200, 200, 0.1f, 1); // setSwapInterval - crash on Mesa 8.0.4 DRI2
+ } else {
+ fprintf(stderr, "%s: Use #3.1\n", msg);
+ useGL(disp1, win1, ctx1, 200, 200, 0.1f, 1); // setSwapInterval - crash on Mesa 8.0.4 DRI2
+
+ fprintf(stderr, "%s: Use #3.2\n", msg);
+ useGL(disp2, win2, ctx2, 300, 300, 0.9f, 1); // setSwapInterval - crash on Mesa 8.0.4 DRI2
+ }
+ fprintf(stderr, "%s: Success - no bug\n", msg);
+ usleep( demodelay );
+
+ fprintf(stderr, "%s: Destroy #1.0\n", msg);
+ glXMakeContextCurrent(disp1, 0, 0, 0);
+ glXDestroyContext(disp1, ctx1);
+ if( disp1 != disp2 ) {
+ XCloseDisplay(disp1);
+ }
+ fprintf(stderr, "%s: Destroy #1.X\n", msg);
+
+ fprintf(stderr, "%s: Destroy #2.0\n", msg);
+ glXMakeContextCurrent(disp2, 0, 0, 0);
+ glXDestroyContext(disp2, ctx2);
+ XCloseDisplay(disp2);
+ fprintf(stderr, "%s: Destroy #2.X\n", msg);
+
+ fprintf(stderr, "%s: Exit - OK\n", msg);
+}
+
+static void useGL(Display *dpy, Window win, GLXContext ctx, int width, int height, float c, int swapInterval)
+{
+ glXMakeContextCurrent(dpy, win, win, ctx);
+ glViewport(0, 0, width, height);
+ if(0 < swapInterval) {
+ fprintf(stderr, "%s: glXSwapIntervalSGI(1)\n", msg);
+ _glXSwapIntervalSGI(1); // offending op after retargeting drawable
+ }
+ fprintf(stderr, "GL_VENDOR: %s\n", glGetString(GL_VENDOR));
+ fprintf(stderr, "GL_VERSION: %s\n", glGetString(GL_VERSION));
+ fprintf(stderr, "GL_RENDERER: %s\n", glGetString(GL_RENDERER));
+ glClearColor(c, c, c, 0.0f);
+ glClearDepth(1.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glXSwapBuffers(dpy, win);
+ glXMakeContextCurrent(dpy, 0, 0, 0);
+}
+
+static volatile bool ctxErrorOccurred = false;
+static int ctxErrorHandler( Display *dpy, XErrorEvent *e )
+{
+ const char * errnoStr = strerror(errno);
+ char errCodeStr[80];
+ char reqCodeStr[80];
+
+ snprintf(errCodeStr, sizeof(errCodeStr), "%d", e->request_code);
+ XGetErrorDatabaseText(dpy, "XRequest", errCodeStr, "Unknown", reqCodeStr, sizeof(reqCodeStr));
+ XGetErrorText(dpy, e->error_code, errCodeStr, sizeof(errCodeStr));
+
+ fprintf(stderr, "X11 Error: %d - %s, dpy %p, id %x, # %d: %d:%d %s\n",
+ e->error_code, errCodeStr, e->display, (int)e->resourceid, (int)e->serial,
+ (int)e->request_code, (int)e->minor_code, reqCodeStr);
+ fflush(stderr);
+
+ ctxErrorOccurred = true;
+ return 0;
+}
+
+/* attributes for a double buffered visual in RGBA format with at least
+ * 8 bits per color and a 16 bit depth buffer */
+static int visual_attribs[] = {
+ GLX_X_RENDERABLE , True,
+ GLX_DRAWABLE_TYPE , GLX_WINDOW_BIT,
+ GLX_RENDER_TYPE , GLX_RGBA_BIT,
+ GLX_RED_SIZE , 8,
+ GLX_GREEN_SIZE , 8,
+ GLX_BLUE_SIZE , 8,
+ GLX_DEPTH_SIZE , 16,
+ GLX_DOUBLEBUFFER , True,
+ GLX_STEREO , False,
+ GLX_TRANSPARENT_TYPE, GLX_NONE,
+ //GLX_SAMPLE_BUFFERS , 1,
+ //GLX_SAMPLES , 4,
+ None };
+
+static int context_attribs[] = {
+ GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
+ GLX_CONTEXT_MINOR_VERSION_ARB, 0,
+ GLX_RENDER_TYPE , GLX_RGBA_TYPE,
+ GLX_CONTEXT_FLAGS_ARB , 0,
+ // GLX_CONTEXT_FLAGS_ARB , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
+ // GLX_CONTEXT_PROFILE_MASK_ARB , GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
+ None };
+
+static bool isExtensionSupported(const char *extList, const char *extension);
+
+static void createGLWin(Display *dpy, int width, int height, Window *rWin, GLXContext *rCtx)
+{
+ int glx_major, glx_minor;
+
+ // FBConfigs were added in GLX version 1.3.
+ if ( !glXQueryVersion( dpy, &glx_major, &glx_minor ) ||
+ ( ( glx_major == 1 ) && ( glx_minor < 3 ) ) || ( glx_major < 1 ) )
+ {
+ printf( "Invalid GLX version" );
+ exit(1);
+ }
+
+ int fbcount;
+ GLXFBConfig *fbc = glXChooseFBConfig( dpy, DefaultScreen( dpy ),
+ visual_attribs, &fbcount );
+ if ( !fbc || 0 == fbcount )
+ {
+ printf( "Failed to retrieve a framebuffer config\n" );
+ exit(1);
+ }
+ printf( "Found %d matching FB configs.\n", fbcount );
+
+ GLXFBConfig bestFbc = fbc[ 0 ];
+ int bestFbcID = 0;
+ if( 0 != glXGetFBConfigAttrib( dpy, bestFbc, GLX_FBCONFIG_ID, &bestFbcID ) ) {
+ printf( "Invalid FBConfigID\n" );
+ exit(1);
+ }
+ printf( "Chosen FBConfigID = 0x%x\n", bestFbcID);
+
+ XVisualInfo *vi = glXGetVisualFromFBConfig( dpy, bestFbc );
+ printf( "Chosen visual ID = 0x%x\n", (int) vi->visualid );
+
+ XSetWindowAttributes swa;
+ Colormap cmap;
+ swa.colormap = cmap = XCreateColormap( dpy,
+ RootWindow( dpy, vi->screen ),
+ vi->visual, AllocNone );
+ swa.background_pixmap = None ;
+ swa.border_pixel = 0;
+ swa.event_mask = StructureNotifyMask;
+
+ printf( "Creating window\n" );
+ Window win = XCreateWindow( dpy, RootWindow( dpy, vi->screen ),
+ 0, 0, width, height, 0, vi->depth, InputOutput,
+ vi->visual,
+ CWBorderPixel|CWColormap|CWEventMask, &swa );
+ if ( !win )
+ {
+ printf( "Failed to create window.\n" );
+ exit(1);
+ }
+
+ // Done with the visual info data
+ XFree( vi );
+
+ XStoreName( dpy, win, "GL Window" );
+
+ XMapWindow( dpy, win );
+
+ *rWin = win;
+
+ GLXContext ctx0 = glXCreateNewContext( dpy, bestFbc, GLX_RGBA_TYPE, 0, True );
+ if( !ctx0 ) {
+ printf( "Failed to create intermediate old OpenGL context\n" );
+ exit(1);
+ }
+ glXMakeContextCurrent(dpy, win, win, ctx0);
+
+
+ // Get the default screen's GLX extension list
+ const char *glxExts01 = glXQueryExtensionsString( dpy,
+ DefaultScreen( dpy ) );
+ const char *glxExts02 = glXGetClientString( dpy, GLX_EXTENSIONS);
+ const char *glxExts03 = glXQueryServerString( dpy, DefaultScreen( dpy ), GLX_EXTENSIONS);
+
+ // NOTE: It is not necessary to create or make current to a context before
+ // calling glXGetProcAddressARB
+ PFNGLXCREATECONTEXTATTRIBSARBPROC _glXCreateContextAttribsARB = 0;
+ _glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)
+ glXGetProcAddressARB( (const GLubyte *) "glXCreateContextAttribsARB" );
+
+ // Check for the GLX_ARB_create_context extension string and the function.
+ // If either is not present, use GLX 1.3 context creation method.
+ bool isGLX_ARB_create_contextAvail = isExtensionSupported( glxExts01, "GLX_ARB_create_context" ) ||
+ isExtensionSupported( glxExts02, "GLX_ARB_create_context" ) ||
+ isExtensionSupported( glxExts03, "GLX_ARB_create_context" );
+
+ glXMakeContextCurrent(dpy, 0, 0, 0);
+
+ GLXContext ctx = 0;
+
+ // Install an X error handler so the application won't exit if GL 3.0
+ // context allocation fails.
+ //
+ // Note this error handler is global. All display connections in all threads
+ // of a process use the same error handler, so be sure to guard against other
+ // threads issuing X commands while this code is running.
+ int (*oldHandler)(Display*, XErrorEvent*) =
+ XSetErrorHandler(&ctxErrorHandler);
+
+ if ( !isGLX_ARB_create_contextAvail || !_glXCreateContextAttribsARB )
+ {
+ printf( "glXCreateContextAttribsARB() not found (ext %d, func %p)"
+ " ... using old-style GLX context\n", isGLX_ARB_create_contextAvail, _glXCreateContextAttribsARB );
+ printf( "extensions 01: %s\n", glxExts01);
+ printf( "extensions 02: %s\n", glxExts02);
+ printf( "extensions 03: %s\n", glxExts03);
+ ctx = ctx0;
+ }
+
+ // If it does, try to get a GL 3.0 context!
+ else
+ {
+ printf( "Creating context\n" );
+ XSync( dpy, False );
+ ctxErrorOccurred = false;
+ ctx = _glXCreateContextAttribsARB( dpy, bestFbc, 0, True, context_attribs );
+ XSync( dpy, False );
+
+ if ( !ctxErrorOccurred && ctx ) {
+ printf( "Created GL 3.0 context\n" );
+ glXDestroyContext(dpy, ctx0); // get rid of old ctx
+ } else
+ {
+ // Couldn't create GL 3.0 context. Fall back to old-style 2.x context.
+ // When a context version below 3.0 is requested, implementations will
+ // return the newest context version compatible with OpenGL versions less
+ // than version 3.0.
+ // GLX_CONTEXT_MAJOR_VERSION_ARB = 1
+ context_attribs[1] = 1;
+ // GLX_CONTEXT_MINOR_VERSION_ARB = 0
+ context_attribs[3] = 0;
+
+ printf( "Failed to create GL 3.0 context (err %d, ctx %p)"
+ " ... using old-style GLX context\n", ctxErrorOccurred, (void*)ctx );
+ ctx = ctx0;
+
+ ctxErrorOccurred = false;
+ }
+ }
+
+ // Sync to ensure any errors generated are processed.
+ XSync( dpy, False );
+
+ // Restore the original error handler
+ XSetErrorHandler( oldHandler );
+
+ if ( ctxErrorOccurred || !ctx )
+ {
+ printf( "Failed to create an OpenGL context\n" );
+ exit(1);
+ }
+
+ XFree( fbc );
+
+ *rCtx = ctx;
+}
+
+// Helper to check for extension string presence. Adapted from:
+// http://www.opengl.org/resources/features/OGLextensions/
+static bool isExtensionSupported(const char *extList, const char *extension)
+{
+
+ const char *start;
+ const char *where, *terminator;
+
+ /* Extension names should not have spaces. */
+ where = strchr(extension, ' ');
+ if ( where || *extension == '\0' )
+ return false;
+
+ /* It takes a bit of care to be fool-proof about parsing the
+ OpenGL extensions string. Don't be fooled by sub-strings,
+ etc. */
+ for ( start = extList; ; ) {
+ where = strstr( start, extension );
+
+ if ( !where )
+ break;
+
+ terminator = where + strlen( extension );
+
+ if ( where == start || *(where - 1) == ' ' )
+ if ( *terminator == ' ' || *terminator == '\0' )
+ return true;
+
+ start = terminator;
+ }
+
+ return false;
+}
+
diff --git a/src/test-native/glExtensionsListGL2.c b/src/test-native/glExtensionsListGL2.c
index 89815e9..ea47b8c 100644
--- a/src/test-native/glExtensionsListGL2.c
+++ b/src/test-native/glExtensionsListGL2.c
@@ -77,6 +77,8 @@ void useGL(Display *dpy, Window win, GLXContext ctx, int width, int height)
glXMakeCurrent(dpy, win, ctx);
fprintf(stderr, "GL_VENDOR: %s\n", glGetString(GL_VENDOR));
+ fprintf(stderr, "GL_VERSION: %s\n", glGetString(GL_VERSION));
+ fprintf(stderr, "GL_RENDERER: %s\n", glGetString(GL_RENDERER));
glGetIntegerv(GL_NUM_EXTENSIONS, &n);
fprintf(stderr, "GL_NUM_EXTENSIONS: %d\n", n);
diff --git a/src/test-native/glExtensionsListGL3.c b/src/test-native/glExtensionsListGL3.c
index c531577..5875c10 100644
--- a/src/test-native/glExtensionsListGL3.c
+++ b/src/test-native/glExtensionsListGL3.c
@@ -59,6 +59,8 @@ void dumpGLExtension() {
int i, n;
fprintf(stderr, "GL_VENDOR: %s\n", glGetString(GL_VENDOR));
+ fprintf(stderr, "GL_VERSION: %s\n", glGetString(GL_VERSION));
+ fprintf(stderr, "GL_RENDERER: %s\n", glGetString(GL_RENDERER));
glGetIntegerv(GL_NUM_EXTENSIONS, &n);
fprintf(stderr, "GL_NUM_EXTENSIONS: %d\n", n);
@@ -153,9 +155,6 @@ int main (int argc, char ** argv)
GLXFBConfig bestFbc = fbc[ best_fbc ];
- // Be sure to free the FBConfig list allocated by glXChooseFBConfig()
- XFree( fbc );
-
// Get a visual
XVisualInfo *vi = glXGetVisualFromFBConfig( display, bestFbc );
printf( "Chosen visual ID = 0x%x\n", (int) vi->visualid );
@@ -190,8 +189,9 @@ int main (int argc, char ** argv)
XMapWindow( display, win );
// Get the default screen's GLX extension list
- const char *glxExts = glXQueryExtensionsString( display,
- DefaultScreen( display ) );
+ const char *glxExts01 = glXQueryExtensionsString( display, DefaultScreen( display ) );
+ const char *glxExts02 = glXGetClientString( display, GLX_EXTENSIONS);
+ const char *glxExts03 = glXQueryServerString( display, DefaultScreen( display ), GLX_EXTENSIONS);
// NOTE: It is not necessary to create or make current to a context before
// calling glXGetProcAddressARB
@@ -213,11 +213,16 @@ int main (int argc, char ** argv)
// Check for the GLX_ARB_create_context extension string and the function.
// If either is not present, use GLX 1.3 context creation method.
- if ( !isExtensionSupported( glxExts, "GLX_ARB_create_context" ) ||
- !glXCreateContextAttribsARB )
+ bool isGLX_ARB_create_contextAvail = isExtensionSupported( glxExts01, "GLX_ARB_create_context" ) ||
+ isExtensionSupported( glxExts02, "GLX_ARB_create_context" ) ||
+ isExtensionSupported( glxExts03, "GLX_ARB_create_context" );
+ if ( !isGLX_ARB_create_contextAvail || !glXCreateContextAttribsARB )
{
printf( "glXCreateContextAttribsARB() not found"
" ... using old-style GLX context\n" );
+ printf( "extensions 01: %s\n", glxExts01);
+ printf( "extensions 02: %s\n", glxExts02);
+ printf( "extensions 03: %s\n", glxExts03);
ctx = glXCreateNewContext( display, bestFbc, GLX_RGBA_TYPE, 0, True );
}
@@ -229,7 +234,8 @@ int main (int argc, char ** argv)
GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
GLX_CONTEXT_MINOR_VERSION_ARB, 0,
GLX_RENDER_TYPE , GLX_RGBA_TYPE,
- GLX_CONTEXT_FLAGS_ARB , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
+ // GLX_CONTEXT_FLAGS_ARB , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
+ // GLX_CONTEXT_PROFILE_MASK_ARB , GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB
None
};
@@ -261,6 +267,9 @@ int main (int argc, char ** argv)
}
}
+ // Be sure to free the FBConfig list allocated by glXChooseFBConfig()
+ XFree( fbc );
+
// Sync to ensure any errors generated are processed.
XSync( display, False );
diff --git a/src/test-native/make.sh b/src/test-native/make.sh
index 20bd49e..269f09c 100755
--- a/src/test-native/make.sh
+++ b/src/test-native/make.sh
@@ -4,3 +4,5 @@ gcc -o displayMultiple01 displayMultiple01.c -lX11 -lGL
gcc -o displayMultiple02 displayMultiple02.c -lX11 -lGL
gcc -o glExtensionsListGL2 glExtensionsListGL2.c -lX11 -lGL
gcc -o glExtensionsListGL3 glExtensionsListGL3.c -lX11 -lGL
+gcc -o contextRetargetDrawable01 contextRetargetDrawable01.c -lX11 -lGL
+gcc -o contextRetargetDrawable02 contextRetargetDrawable02.c -lX11 -lGL
diff --git a/src/test/com/jogamp/opengl/test/android/MovieCubeActivityLauncher0.java b/src/test/com/jogamp/opengl/test/android/MovieCubeActivityLauncher0.java
index 4f24fc9..c4b74c5 100644
--- a/src/test/com/jogamp/opengl/test/android/MovieCubeActivityLauncher0.java
+++ b/src/test/com/jogamp/opengl/test/android/MovieCubeActivityLauncher0.java
@@ -50,6 +50,8 @@ public class MovieCubeActivityLauncher0 extends LauncherUtil.BaseActivityLaunche
// props.setProperty("jogamp.debug.NativeLibrary", "true");
// props.setProperty("jogamp.debug.NativeLibrary.Lookup", "true");
// props.setProperty("jogamp.debug.IOUtil", "true");
+ // props.setProperty("jogamp.debug.Lock", "true");
+ // props.setProperty("jogamp.debug.Lock.TraceLock", "true");
// props.setProperty("nativewindow.debug", "all");
props.setProperty("nativewindow.debug.GraphicsConfiguration", "true");
// props.setProperty("jogl.debug", "all");
diff --git a/src/test/com/jogamp/opengl/test/android/MovieSimpleActivity0.java b/src/test/com/jogamp/opengl/test/android/MovieSimpleActivity0.java
index 11babf1..89395e3 100644
--- a/src/test/com/jogamp/opengl/test/android/MovieSimpleActivity0.java
+++ b/src/test/com/jogamp/opengl/test/android/MovieSimpleActivity0.java
@@ -34,11 +34,11 @@ import java.util.Arrays;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLProfile;
-import jogamp.newt.driver.android.AndroidWindow;
import jogamp.newt.driver.android.NewtBaseActivity;
import com.jogamp.common.util.IOUtil;
import com.jogamp.newt.NewtFactory;
+import com.jogamp.newt.Window;
import com.jogamp.newt.event.MouseAdapter;
import com.jogamp.newt.event.MouseEvent;
import com.jogamp.newt.opengl.GLWindow;
@@ -55,8 +55,8 @@ public class MovieSimpleActivity0 extends NewtBaseActivity {
MouseAdapter toFrontMouseListener = new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
Object src = e.getSource();
- if(src instanceof AndroidWindow) {
- ((AndroidWindow)src).requestFocus(false);
+ if(src instanceof Window) {
+ ((Window)src).requestFocus(false);
}
} };
diff --git a/src/test/com/jogamp/opengl/test/android/MovieSimpleActivity1.java b/src/test/com/jogamp/opengl/test/android/MovieSimpleActivity1.java
index a5e5f4c..a7fefd8 100644
--- a/src/test/com/jogamp/opengl/test/android/MovieSimpleActivity1.java
+++ b/src/test/com/jogamp/opengl/test/android/MovieSimpleActivity1.java
@@ -36,11 +36,11 @@ import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLProfile;
import javax.media.opengl.GLRunnable;
-import jogamp.newt.driver.android.AndroidWindow;
import jogamp.newt.driver.android.NewtBaseActivity;
import com.jogamp.common.util.IOUtil;
import com.jogamp.newt.NewtFactory;
+import com.jogamp.newt.Window;
import com.jogamp.newt.event.MouseAdapter;
import com.jogamp.newt.event.MouseEvent;
import com.jogamp.newt.opengl.GLWindow;
@@ -59,8 +59,8 @@ public class MovieSimpleActivity1 extends NewtBaseActivity {
MouseAdapter toFrontMouseListener = new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
Object src = e.getSource();
- if(src instanceof AndroidWindow) {
- ((AndroidWindow)src).requestFocus(false);
+ if(src instanceof Window) {
+ ((Window)src).requestFocus(false);
}
} };
@@ -121,7 +121,7 @@ public class MovieSimpleActivity1 extends NewtBaseActivity {
final GLWindow glWindowMain = GLWindow.create(scrn, capsMain);
{
final int padding = mPlayerHUD ? 32 : 0;
- final android.view.View androidView = ((AndroidWindow)glWindowMain.getDelegatedWindow()).getAndroidView();
+ final android.view.View androidView = ((jogamp.newt.driver.android.WindowDriver)glWindowMain.getDelegatedWindow()).getAndroidView();
glWindowMain.setSize(scrn.getWidth()-padding, scrn.getHeight()-padding);
glWindowMain.setUndecorated(true);
// setContentView(getWindow(), glWindowMain);
@@ -168,7 +168,7 @@ public class MovieSimpleActivity1 extends NewtBaseActivity {
viewGroup.post(new Runnable() {
public void run() {
- final android.view.View androidView = ((AndroidWindow)glWindowHUD.getDelegatedWindow()).getAndroidView();
+ final android.view.View androidView = ((jogamp.newt.driver.android.WindowDriver)glWindowHUD.getDelegatedWindow()).getAndroidView();
// addContentView(getWindow(), glWindowHUD, new android.view.ViewGroup.LayoutParams(glWindowHUD.getWidth(), glWindowHUD.getHeight()));
viewGroup.addView(androidView, new android.widget.FrameLayout.LayoutParams(glWindowHUD.getWidth(), glWindowHUD.getHeight(), Gravity.TOP|Gravity.LEFT));
registerNEWTWindow(glWindowHUD);
diff --git a/src/test/com/jogamp/opengl/test/android/NEWTGearsES2ActivityLauncher.java b/src/test/com/jogamp/opengl/test/android/NEWTGearsES2ActivityLauncher.java
index 907be50..415efc7 100644
--- a/src/test/com/jogamp/opengl/test/android/NEWTGearsES2ActivityLauncher.java
+++ b/src/test/com/jogamp/opengl/test/android/NEWTGearsES2ActivityLauncher.java
@@ -53,10 +53,10 @@ public class NEWTGearsES2ActivityLauncher extends LauncherUtil.BaseActivityLaunc
props.setProperty("jogl.debug.GLContext", "true");
props.setProperty("jogl.debug.GLSLCode", "true");
// props.setProperty("jogl.debug.CapabilitiesChooser", "true");
- // properties.setProperty("jogl.debug.GLSLState", "true");
- // properties.setProperty("jogl.debug.DebugGL", "true");
- // properties.setProperty("jogl.debug.TraceGL", "true");
- // properties.setProperty("newt.debug", "all");
+ // props.setProperty("jogl.debug.GLSLState", "true");
+ // props.setProperty("jogl.debug.DebugGL", "true");
+ // props.setProperty("jogl.debug.TraceGL", "true");
+ // props.setProperty("newt.debug", "all");
// props.setProperty("newt.debug.Window", "true");
// props.setProperty("newt.debug.Window.MouseEvent", "true");
props.setProperty("newt.debug.Window.KeyEvent", "true");
diff --git a/src/test/com/jogamp/opengl/test/android/NEWTGraphUI1pActivityLauncher.java b/src/test/com/jogamp/opengl/test/android/NEWTGraphUI1pActivityLauncher.java
index c75c229..5763058 100644
--- a/src/test/com/jogamp/opengl/test/android/NEWTGraphUI1pActivityLauncher.java
+++ b/src/test/com/jogamp/opengl/test/android/NEWTGraphUI1pActivityLauncher.java
@@ -14,23 +14,23 @@ public class NEWTGraphUI1pActivityLauncher extends LauncherUtil.BaseActivityLaun
final OrderedProperties props = getProperties();
// props.setProperty("jogamp.debug.JNILibLoader", "true");
// props.setProperty("jogamp.debug.NativeLibrary", "true");
- // properties.setProperty("jogamp.debug.NativeLibrary.Lookup", "true");
- // properties.setProperty("jogamp.debug.IOUtil", "true");
- // properties.setProperty("nativewindow.debug", "all");
+ // props.setProperty("jogamp.debug.NativeLibrary.Lookup", "true");
+ // props.setProperty("jogamp.debug.IOUtil", "true");
+ // props.setProperty("nativewindow.debug", "all");
props.setProperty("nativewindow.debug.GraphicsConfiguration", "true");
- // properties.setProperty("jogl.debug", "all");
- // properties.setProperty("jogl.debug.GLProfile", "true");
+ // props.setProperty("jogl.debug", "all");
+ // props.setProperty("jogl.debug.GLProfile", "true");
props.setProperty("jogl.debug.GLDrawable", "true");
props.setProperty("jogl.debug.GLContext", "true");
props.setProperty("jogl.debug.GLSLCode", "true");
props.setProperty("jogl.debug.CapabilitiesChooser", "true");
- // properties.setProperty("jogl.debug.GLSLState", "true");
- // properties.setProperty("jogl.debug.DebugGL", "true");
- // properties.setProperty("jogl.debug.TraceGL", "true");
- // properties.setProperty("newt.debug", "all");
+ // props.setProperty("jogl.debug.GLSLState", "true");
+ // props.setProperty("jogl.debug.DebugGL", "true");
+ // props.setProperty("jogl.debug.TraceGL", "true");
+ // props.setProperty("newt.debug", "all");
props.setProperty("newt.debug.Window", "true");
- // properties.setProperty("newt.debug.Window.MouseEvent", "true");
- // properties.setProperty("newt.debug.Window.KeyEvent", "true");
+ // props.setProperty("newt.debug.Window.MouseEvent", "true");
+ // props.setProperty("newt.debug.Window.KeyEvent", "true");
}
@Override
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestInitConcurrentNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/InitConcurrentBaseNEWT.java
similarity index 80%
rename from src/test/com/jogamp/opengl/test/junit/jogl/acore/TestInitConcurrentNEWT.java
rename to src/test/com/jogamp/opengl/test/junit/jogl/acore/InitConcurrentBaseNEWT.java
index 7127b0a..6b2de83 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestInitConcurrentNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/InitConcurrentBaseNEWT.java
@@ -28,8 +28,6 @@
package com.jogamp.opengl.test.junit.jogl.acore;
-import java.io.IOException;
-
import javax.media.nativewindow.Capabilities;
import javax.media.nativewindow.util.InsetsImmutable;
import javax.media.opengl.GLCapabilities;
@@ -37,17 +35,25 @@ import javax.media.opengl.GLProfile;
import org.junit.Assert;
import org.junit.BeforeClass;
-import org.junit.Test;
-import com.jogamp.common.os.Platform;
+import com.jogamp.newt.Display;
import com.jogamp.newt.NewtFactory;
+import com.jogamp.newt.Screen;
import com.jogamp.newt.Window;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
import com.jogamp.opengl.test.junit.util.UITestCase;
+import com.jogamp.opengl.test.junit.util.ValidateLockListener;
import com.jogamp.opengl.util.Animator;
-public class TestInitConcurrentNEWT extends UITestCase {
+/**
+ * Concurrent and lock-free initialization and rendering using exclusive NEWT Display EDT instances, or
+ * concurrent locked initialization and lock-free rendering using a shared NEWT Display EDT instances.
+ * <p>
+ * Rendering is always lock-free and independent of the EDT.
+ * </p>
+ */
+public class InitConcurrentBaseNEWT extends UITestCase {
static final int demoSize = 128;
@@ -73,24 +79,29 @@ public class TestInitConcurrentNEWT extends UITestCase {
}
public class JOGLTask implements Runnable {
- private int id;
- private Object postSync;
+ private final int id;
+ private final Object postSync;
+ private final boolean reuse;
private boolean done = false;
- public JOGLTask(Object postSync, int id) {
+ public JOGLTask(Object postSync, int id, boolean reuse) {
this.postSync = postSync;
this.id = id;
+ this.reuse = reuse;
}
public void run() {
int x = ( id % num_x ) * ( demoSize + insets.getTotalHeight() );
int y = ( (id / num_x) % num_y ) * ( demoSize + insets.getTotalHeight() );
- System.err.println("JOGLTask "+id+": START: "+x+"/"+y+" - "+Thread.currentThread().getName());
- GLWindow glWindow = GLWindow.create(new GLCapabilities(GLProfile.getDefault()));
+ System.err.println("JOGLTask "+id+": START: "+x+"/"+y+", reuse "+reuse+" - "+Thread.currentThread().getName());
+ final Display display = NewtFactory.createDisplay(null, reuse);
+ final Screen screen = NewtFactory.createScreen(display, 0);
+ final GLWindow glWindow = GLWindow.create(screen, new GLCapabilities(GLProfile.getDefault()));
Assert.assertNotNull(glWindow);
glWindow.setTitle("Task "+id);
glWindow.setPosition(x + insets.getLeftWidth(), y + insets.getTopHeight() );
+ glWindow.addGLEventListener(new ValidateLockListener());
glWindow.addGLEventListener(new GearsES2(0));
Animator animator = new Animator(glWindow);
@@ -98,6 +109,9 @@ public class TestInitConcurrentNEWT extends UITestCase {
glWindow.setSize(demoSize, demoSize);
glWindow.setVisible(true);
animator.setUpdateFPSFrames(60, null);
+
+ System.err.println("JOGLTask "+id+": INITIALIZED: "+", "+display+" - "+Thread.currentThread().getName());
+
animator.start();
Assert.assertEquals(true, animator.isAnimating());
Assert.assertEquals(true, glWindow.isVisible());
@@ -169,67 +183,39 @@ public class TestInitConcurrentNEWT extends UITestCase {
return sb.toString();
}
- protected void runJOGLTasks(int num) throws InterruptedException {
+ protected void runJOGLTasks(int num, boolean reuse) throws InterruptedException {
final String currentThreadName = Thread.currentThread().getName();
- final Object sync = new Object();
+ final Object syncDone = new Object();
final JOGLTask[] tasks = new JOGLTask[num];
final Thread[] threads = new Thread[num];
int i;
for(i=0; i<num; i++) {
- tasks[i] = new JOGLTask(sync, i);
+ tasks[i] = new JOGLTask(syncDone, i, reuse);
threads[i] = new Thread(tasks[i], currentThreadName+"-jt"+i);
}
+ final long t0 = System.currentTimeMillis();
+
for(i=0; i<num; i++) {
threads[i].start();
}
- synchronized (sync) {
+ synchronized (syncDone) {
while(!done(tasks)) {
try {
- sync.wait();
+ syncDone.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
+ final long t1 = System.currentTimeMillis();
+ System.err.println("total: "+(t1-t0)/1000.0+"s");
+
Assert.assertTrue("Tasks are incomplete. Complete: "+doneDump(tasks), done(tasks));
i=0;
while(i<30 && !isDead(threads)) {
Thread.sleep(100);
i++;
}
- Assert.assertTrue("Threads are still alive after 3s. Alive: "+isAliveDump(threads), isDead(threads));
- }
-
- @Test
- public void test01OneThread() throws InterruptedException {
- runJOGLTasks(1);
- }
-
- @Test
- public void test02TwoThreads() throws InterruptedException {
- runJOGLTasks(2);
- }
-
- @Test
- public void test16SixteenThreads() throws InterruptedException {
- if( Platform.getCPUFamily() == Platform.CPUFamily.ARM ) {
- runJOGLTasks(8);
- } else {
- runJOGLTasks(16);
- }
- }
-
- public static void main(String args[]) throws IOException {
- for(int i=0; i<args.length; i++) {
- if(args[i].equals("-time")) {
- i++;
- try {
- duration = Integer.parseInt(args[i]);
- } catch (Exception ex) { ex.printStackTrace(); }
- }
- }
- String tstname = TestInitConcurrentNEWT.class.getName();
- org.junit.runner.JUnitCore.main(tstname);
- }
-
+ Assert.assertTrue("Threads are still alive after 3s. Alive: "+isAliveDump(threads), isDead(threads));
+ }
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestPBufferDeadlockAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOAutoDrawableDeadlockAWT.java
similarity index 92%
copy from src/test/com/jogamp/opengl/test/junit/jogl/acore/TestPBufferDeadlockAWT.java
copy to src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOAutoDrawableDeadlockAWT.java
index 3a25d12..eab1a37 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestPBufferDeadlockAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOAutoDrawableDeadlockAWT.java
@@ -33,7 +33,7 @@ import java.lang.reflect.InvocationTargetException;
import javax.media.opengl.DefaultGLCapabilitiesChooser;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLDrawableFactory;
-import javax.media.opengl.GLPbuffer;
+import javax.media.opengl.GLOffscreenAutoDrawable;
import javax.media.opengl.GLProfile;
import jogamp.nativewindow.jawt.JAWTUtil;
@@ -45,7 +45,7 @@ import org.junit.Test;
import com.jogamp.common.util.RunnableTask;
import com.jogamp.opengl.test.junit.util.UITestCase;
-public class TestPBufferDeadlockAWT extends UITestCase {
+public class TestFBOAutoDrawableDeadlockAWT extends UITestCase {
static GLProfile glp;
static int width, height;
@@ -58,7 +58,7 @@ public class TestPBufferDeadlockAWT extends UITestCase {
}
protected void runTestGL( GLCapabilities caps ) throws InterruptedException, InvocationTargetException {
- final GLPbuffer pbuffer = GLDrawableFactory.getFactory( GLProfile.getGL2ES2() ).createGLPbuffer(
+ final GLOffscreenAutoDrawable fbod = GLDrawableFactory.getFactory(caps.getGLProfile()).createOffscreenAutoDrawable(
null,
caps, new DefaultGLCapabilitiesChooser(),
512, 512,
@@ -69,7 +69,7 @@ public class TestPBufferDeadlockAWT extends UITestCase {
final Runnable pbufferCreationAction = new Runnable() {
public void run() {
System.err.println("AA.1");
- pbuffer.display();
+ fbod.display();
done[ 0 ] = true;
System.err.println("AA.X");
}
@@ -100,6 +100,7 @@ public class TestPBufferDeadlockAWT extends UITestCase {
}
});
Assert.assertTrue(done[0]);
+ fbod.destroy();
}
@Test(timeout = 2000) // 2s timeout
@@ -122,6 +123,6 @@ public class TestPBufferDeadlockAWT extends UITestCase {
}
}
}
- org.junit.runner.JUnitCore.main( TestPBufferDeadlockAWT.class.getName() );
+ org.junit.runner.JUnitCore.main( TestFBOAutoDrawableDeadlockAWT.class.getName() );
}
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOAutoDrawableFactoryNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOAutoDrawableFactoryNEWT.java
new file mode 100644
index 0000000..2dc547f
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOAutoDrawableFactoryNEWT.java
@@ -0,0 +1,375 @@
+/**
+ * Copyright 2012 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community OR
+ * CONTRIBUTORS 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.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.opengl.test.junit.jogl.acore;
+
+import java.io.IOException;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLOffscreenAutoDrawable;
+import javax.media.opengl.GLProfile;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.jogamp.opengl.FBObject;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.FBOMix2DemosES2;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.MultisampleDemoES2;
+import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+
+/**
+ * Toolkit agnostic {@link GLOffscreenAutoDrawable.FBO} tests using the
+ * {@link GLDrawableFactory#createOffscreenAutoDrawable(javax.media.nativewindow.AbstractGraphicsDevice, GLCapabilitiesImmutable, javax.media.opengl.GLCapabilitiesChooser, int, int, GLContext) factory model}.
+ * <p>
+ * The created {@link GLOffscreenAutoDrawable.FBO} is being used to run the {@link GLEventListener}.
+ * </p>
+ * <p>
+ * Extensive FBO reconfiguration (size and sample buffer count) and validation are performed.
+ * </p>
+ */
+public class TestFBOAutoDrawableFactoryNEWT extends UITestCase {
+
+ static final int widthStep = 800/4;
+ static final int heightStep = 600/4;
+ volatile int szStep = 2;
+
+ interface MyGLEventListener extends GLEventListener {
+ void setMakeSnapshot();
+ }
+
+ @Test
+ public void testGL2ES2_Demo1_SingleBuffer_Normal() throws InterruptedException {
+ final GLProfile glp = GLProfile.getGL2ES2();
+ final GLCapabilities caps = new GLCapabilities(glp);
+ caps.setDoubleBuffered(false);
+ testGLFBODrawableImpl(caps, new GearsES2(0));
+ }
+
+ @Test
+ public void testGL2ES2_Demo1_DoubleBuffer_Normal() throws InterruptedException {
+ final GLProfile glp = GLProfile.getGL2ES2();
+ final GLCapabilities caps = new GLCapabilities(glp);
+ caps.setDoubleBuffered(true); // default
+ testGLFBODrawableImpl(caps, new GearsES2(0));
+ }
+
+ @Test
+ public void testGL2ES2_Demo2MSAA4() throws InterruptedException {
+ final GLProfile glp = GLProfile.getGL2ES2();
+ final GLCapabilities caps = new GLCapabilities(glp);
+ caps.setSampleBuffers(true);
+ caps.setNumSamples(4);
+ testGLFBODrawableImpl(caps, new MultisampleDemoES2(true));
+ }
+
+ @Test
+ public void testGL2ES2_FBODemoMSAA4() throws InterruptedException {
+ final GLProfile glp = GLProfile.getGL2ES2();
+ final FBOMix2DemosES2 demo = new FBOMix2DemosES2(0);
+ demo.setDoRotation(false);
+ final GLCapabilities caps = new GLCapabilities(glp);
+ caps.setSampleBuffers(true);
+ caps.setNumSamples(4);
+ testGLFBODrawableImpl(caps, demo);
+ }
+
+ @Test
+ public void testEGLES2_Demo0Normal() throws InterruptedException {
+ if( GLProfile.isAvailable(GLProfile.GLES2) ) {
+ final GLProfile glp = GLProfile.get(GLProfile.GLES2);
+ final GLCapabilities caps = new GLCapabilities(glp);
+ testGLFBODrawableImpl(caps, new GearsES2(0));
+ } else {
+ System.err.println("EGL ES2 n/a");
+ }
+ }
+
+ @Test
+ public void testEGLES2_Demo0MSAA4() throws InterruptedException {
+ if( GLProfile.isAvailable(GLProfile.GLES2) ) {
+ final GLProfile glp = GLProfile.get(GLProfile.GLES2);
+ final GLCapabilities caps = new GLCapabilities(glp);
+ caps.setSampleBuffers(true);
+ caps.setNumSamples(4);
+ testGLFBODrawableImpl(caps, new GearsES2(0));
+ } else {
+ System.err.println("EGL ES2 n/a");
+ }
+ }
+
+ void testGLFBODrawableImpl(GLCapabilities caps, GLEventListener demo) throws InterruptedException {
+ caps.setFBO(true);
+ final GLDrawableFactory factory = GLDrawableFactory.getFactory(caps.getGLProfile());
+ final GLOffscreenAutoDrawable.FBO glad = (GLOffscreenAutoDrawable.FBO)
+ factory.createOffscreenAutoDrawable(null, caps, null, widthStep*szStep, heightStep*szStep, null);
+ Assert.assertNotNull(glad);
+
+ System.out.println("Realized GLAD: "+glad);
+ System.out.println("Realized GLAD: "+glad.getChosenGLCapabilities());
+ Assert.assertTrue("FBO drawable is initialized before ctx creation", !glad.isInitialized());
+
+ glad.display(); // initial display incl. init!
+ {
+ final GLContext context = glad.getContext();
+ Assert.assertNotNull(context);
+ Assert.assertTrue(context.isCreated());
+ }
+ Assert.assertTrue("FBO drawable is not initialized after ctx creation", glad.isInitialized());
+
+ //
+ // FBO incl. MSAA is fully initialized now
+ //
+
+ final GLCapabilitiesImmutable chosenCaps = glad.getChosenGLCapabilities();
+ System.out.println("Init GLAD: "+glad);
+ System.out.println("Init GLAD: "+chosenCaps);
+
+ final FBObject fboFront = glad.getFBObject(GL.GL_FRONT);
+ final FBObject fboBack = glad.getFBObject(GL.GL_BACK);
+
+ System.out.println("Init front FBO: "+fboFront);
+ System.out.println("Init back FBO: "+fboBack);
+
+ Assert.assertTrue("FBO drawable is not initialized before ctx creation", glad.isInitialized());
+ Assert.assertTrue("FBO Front is not initialized before ctx creation", fboFront.isInitialized());
+ Assert.assertTrue("FBO Back is not initialized before ctx creation", fboBack.isInitialized());
+
+ if( chosenCaps.getDoubleBuffered() ) {
+ Assert.assertTrue("FBO are equal: "+fboFront+" == "+fboBack, !fboFront.equals(fboBack));
+ Assert.assertNotSame(fboFront, fboBack);
+ } else {
+ Assert.assertTrue("FBO are not equal: "+fboFront+" != "+fboBack, fboFront.equals(fboBack));
+ Assert.assertSame(fboFront, fboBack);
+ }
+
+ final FBObject.TextureAttachment texAttachA, texAttachB;
+
+ texAttachA = glad.getTextureBuffer(GL.GL_FRONT);
+ if(0==glad.getNumSamples()) {
+ texAttachB = glad.getTextureBuffer(GL.GL_BACK);
+ } else {
+ texAttachB = null;
+ }
+
+ final FBObject.Colorbuffer colorA, colorB;
+ final FBObject.RenderAttachment depthA, depthB;
+
+ colorA = fboFront.getColorbuffer(0);
+ Assert.assertNotNull(colorA);
+ colorB = fboBack.getColorbuffer(0);
+ Assert.assertNotNull(colorB);
+
+ depthA = fboFront.getDepthAttachment();
+ Assert.assertNotNull(depthA);
+ depthB = fboBack.getDepthAttachment();
+ Assert.assertNotNull(depthB);
+
+ glad.display(); // SWAP_ODD
+
+ if( chosenCaps.getDoubleBuffered() ) {
+ // double buffer or MSAA
+ Assert.assertTrue("Color attachments are equal: "+colorB+" == "+colorA, !colorB.equals(colorA));
+ Assert.assertNotSame(colorB, colorA);
+ Assert.assertTrue("Depth attachments are equal: "+depthB+" == "+depthA, !depthB.equals(depthA));
+ Assert.assertNotSame(depthB, depthA);
+ } else {
+ // single buffer
+ Assert.assertEquals(colorA, colorB);
+ Assert.assertSame(colorA, colorB);
+ Assert.assertEquals(depthA, depthB);
+ Assert.assertSame(depthA, depthB);
+ }
+
+ Assert.assertEquals(texAttachA, colorA);
+ Assert.assertSame(texAttachA, colorA);
+ if(0==glad.getNumSamples()) {
+ Assert.assertEquals(texAttachB, colorB);
+ Assert.assertSame(texAttachB, colorB);
+ }
+
+ if( chosenCaps.getNumSamples() > 0 ) {
+ // MSAA
+ FBObject _fboFront = glad.getFBObject(GL.GL_FRONT);
+ FBObject _fboBack = glad.getFBObject(GL.GL_BACK);
+ Assert.assertTrue("FBO are not equal: "+fboFront+" != "+_fboFront, fboFront.equals(_fboFront));
+ Assert.assertSame(fboFront, _fboFront);
+ Assert.assertTrue("FBO are not equal: "+fboBack+" != "+_fboBack, fboBack.equals(_fboBack));
+ Assert.assertSame(fboBack, _fboBack);
+ } else if( chosenCaps.getDoubleBuffered() ) {
+ // real double buffer
+ FBObject _fboFront = glad.getFBObject(GL.GL_FRONT);
+ FBObject _fboBack = glad.getFBObject(GL.GL_BACK);
+ Assert.assertTrue("FBO are not equal: "+fboBack+" != "+_fboFront, fboBack.equals(_fboFront));
+ Assert.assertSame(fboBack, _fboFront);
+ Assert.assertTrue("FBO are not equal: "+fboFront+" != "+_fboBack, fboFront.equals(_fboBack));
+ Assert.assertSame(fboFront, _fboBack);
+ } else {
+ // single buffer
+ FBObject _fboFront = glad.getFBObject(GL.GL_FRONT);
+ FBObject _fboBack = glad.getFBObject(GL.GL_BACK);
+ Assert.assertTrue("FBO are not equal: "+fboFront+" != "+_fboFront, fboFront.equals(_fboFront));
+ Assert.assertSame(fboFront, _fboFront);
+ Assert.assertTrue("FBO are not equal: "+fboBack+" != "+_fboFront, fboBack.equals(_fboFront));
+ Assert.assertSame(fboBack, _fboFront);
+ Assert.assertTrue("FBO are not equal: "+fboBack+" != "+_fboBack, fboBack.equals(_fboBack));
+ Assert.assertSame(fboBack, _fboBack);
+ Assert.assertTrue("FBO are not equal: "+fboFront+" != "+_fboBack, fboFront.equals(_fboBack));
+ Assert.assertSame(fboFront, _fboBack);
+ }
+
+ glad.addGLEventListener(demo);
+
+ final SnapshotGLEventListener snapshotGLEventListener = new SnapshotGLEventListener();
+ glad.addGLEventListener(snapshotGLEventListener);
+
+ glad.display(); // - SWAP_EVEN
+
+ // 1 - szStep = 2
+ snapshotGLEventListener.setMakeSnapshot();
+ glad.display(); // - SWAP_ODD
+
+ // 2, 3 (resize + display)
+ szStep = 1;
+ glad.setSize(widthStep*szStep, heightStep*szStep); // SWAP_EVEN
+ Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(),
+ AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep));
+ snapshotGLEventListener.setMakeSnapshot();
+ glad.display(); // - SWAP_ODD
+ glad.display(); // - SWAP_EVEN
+ {
+ // Check whether the attachment reference are still valid!
+ final FBObject _fboFront = glad.getFBObject(GL.GL_FRONT);
+ final FBObject _fboBack = glad.getFBObject(GL.GL_BACK);
+ System.out.println("Resize1.oldFront: "+fboFront);
+ System.out.println("Resize1.nowFront: "+_fboFront);
+ System.out.println("Resize1.oldBack : "+fboBack);
+ System.out.println("Resize1.nowBack : "+_fboBack);
+ Assert.assertEquals(fboFront, _fboFront);
+ Assert.assertSame(fboFront, _fboFront);
+ Assert.assertEquals(fboBack, _fboBack);
+ Assert.assertSame(fboBack, _fboBack);
+
+ FBObject.Colorbuffer _color = _fboFront.getColorbuffer(0);
+ Assert.assertNotNull(_color);
+ Assert.assertEquals(colorA, _color);
+ Assert.assertSame(colorA, _color);
+
+ FBObject.RenderAttachment _depth = _fboFront.getDepthAttachment();
+ System.err.println("Resize1.oldDepth "+depthA);
+ System.err.println("Resize1.newDepth "+_depth);
+ Assert.assertNotNull(_depth);
+
+ Assert.assertEquals(depthA, _depth);
+ Assert.assertSame(depthA, _depth);
+ _depth = _fboBack.getDepthAttachment();
+ Assert.assertNotNull(_depth);
+ Assert.assertEquals(depthB, _depth);
+ Assert.assertSame(depthB, _depth);
+
+ _color = _fboFront.getColorbuffer(colorA);
+ Assert.assertNotNull(_color);
+ Assert.assertEquals(colorA, _color);
+ Assert.assertSame(colorA, _color);
+ }
+
+ // 4, 5 (resize + display)
+ szStep = 4;
+ glad.setSize(widthStep*szStep, heightStep*szStep); // SWAP_ODD
+ Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(),
+ AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep));
+ snapshotGLEventListener.setMakeSnapshot();
+ glad.display(); // - SWAP_EVEN
+ glad.display(); // - SWAP_ODD
+ {
+ // Check whether the attachment reference are still valid!
+ final FBObject _fboFront = glad.getFBObject(GL.GL_FRONT);
+ final FBObject _fboBack = glad.getFBObject(GL.GL_BACK);
+ System.out.println("Resize2.oldFront: "+fboFront);
+ System.out.println("Resize2.nowFront: "+_fboFront);
+ System.out.println("Resize2.oldBack : "+fboBack);
+ System.out.println("Resize2.nowBack : "+_fboBack);
+ if(chosenCaps.getDoubleBuffered() && 0==chosenCaps.getNumSamples()) {
+ // real double buffer
+ Assert.assertEquals(fboBack, _fboFront);
+ Assert.assertEquals(fboFront, _fboBack);
+ } else {
+ // single or MSAA
+ Assert.assertEquals(fboFront, _fboFront);
+ Assert.assertEquals(fboBack, _fboBack);
+ }
+
+ FBObject.Colorbuffer _color = fboBack.getColorbuffer(0);
+ Assert.assertNotNull(_color);
+ Assert.assertEquals(colorB, _color);
+ Assert.assertSame(colorB, _color);
+
+ FBObject.RenderAttachment _depth = fboBack.getDepthAttachment();
+ Assert.assertNotNull(_depth); // MSAA back w/ depth
+ Assert.assertEquals(depthB, _depth);
+ Assert.assertSame(depthB, _depth);
+
+ _depth = fboFront.getDepthAttachment();
+ Assert.assertNotNull(_depth);
+ Assert.assertEquals(depthA, _depth);
+ Assert.assertSame(depthA, _depth);
+
+ _color = fboBack.getColorbuffer(colorB);
+ Assert.assertNotNull(_color);
+ Assert.assertEquals(colorB, _color);
+ Assert.assertSame(colorB, _color);
+ }
+
+ // 6 + 7 (samples + display)
+ glad.setNumSamples(glad.getGL(), chosenCaps.getNumSamples() > 0 ? 0 : 4); // triggers repaint
+ snapshotGLEventListener.setMakeSnapshot();
+ glad.display(); // actual screenshot
+
+ // 8, 9 (resize + samples + display)
+ szStep = 3;
+ glad.setSize(widthStep*szStep, heightStep*szStep);
+ Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(),
+ AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep));
+ snapshotGLEventListener.setMakeSnapshot();
+ glad.display();
+
+ glad.destroy();
+ System.out.println("Fin: "+glad);
+ }
+
+ public static void main(String args[]) throws IOException {
+ org.junit.runner.JUnitCore.main(TestFBOAutoDrawableFactoryNEWT.class.getName());
+ }
+
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBODrawableNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBODrawableNEWT.java
deleted file mode 100644
index 7977347..0000000
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBODrawableNEWT.java
+++ /dev/null
@@ -1,272 +0,0 @@
-/**
- * Copyright 2012 JogAmp Community. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are
- * permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- *
- * 2. 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.
- *
- * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community OR
- * CONTRIBUTORS 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.
- *
- * The views and conclusions contained in the software and documentation are those of the
- * authors and should not be interpreted as representing official policies, either expressed
- * or implied, of JogAmp Community.
- */
-
-package com.jogamp.opengl.test.junit.jogl.acore;
-
-import java.io.IOException;
-
-import javax.media.opengl.GL;
-import javax.media.opengl.GLAutoDrawable;
-import javax.media.opengl.GLCapabilities;
-import javax.media.opengl.GLContext;
-import javax.media.opengl.GLDrawable;
-import javax.media.opengl.GLDrawableFactory;
-import javax.media.opengl.GLEventListener;
-import javax.media.opengl.GLProfile;
-
-import jogamp.opengl.GLFBODrawableImpl;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-import com.jogamp.opengl.FBObject;
-import com.jogamp.opengl.OffscreenAutoDrawable;
-import com.jogamp.opengl.test.junit.jogl.demos.es2.FBOMix2DemosES2;
-import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
-import com.jogamp.opengl.test.junit.jogl.demos.es2.MultisampleDemoES2;
-import com.jogamp.opengl.test.junit.util.UITestCase;
-import com.jogamp.opengl.util.GLReadBufferUtil;
-import com.jogamp.opengl.util.texture.TextureIO;
-
-public class TestFBODrawableNEWT extends UITestCase {
-
- static final int widthStep = 800/4;
- static final int heightStep = 600/4;
- volatile int szStep = 2;
-
- @Test
- public void testGL2ES2_Demo1Normal() throws InterruptedException {
- final GLProfile glp = GLProfile.getGL2ES2();
- final GLCapabilities caps = new GLCapabilities(glp);
- testGLFBODrawableImpl(caps, new GearsES2(0));
- }
-
- @Test
- public void testGL2ES2_Demo1MSAA4() throws InterruptedException {
- final GLProfile glp = GLProfile.getGL2ES2();
- final GLCapabilities caps = new GLCapabilities(glp);
- caps.setSampleBuffers(true);
- caps.setNumSamples(4);
- testGLFBODrawableImpl(caps, new GearsES2(0));
- }
-
- @Test
- public void testGL2ES2_Demo2Normal() throws InterruptedException {
- final GLProfile glp = GLProfile.getGL2ES2();
- final GLCapabilities caps = new GLCapabilities(glp);
- testGLFBODrawableImpl(caps, new MultisampleDemoES2(false));
- }
-
- @Test
- public void testGL2ES2_Demo2MSAA4() throws InterruptedException {
- final GLProfile glp = GLProfile.getGL2ES2();
- final GLCapabilities caps = new GLCapabilities(glp);
- caps.setSampleBuffers(true);
- caps.setNumSamples(4);
- testGLFBODrawableImpl(caps, new MultisampleDemoES2(true));
- }
-
- @Test
- public void testGL2ES2_FBODemoNormal() throws InterruptedException {
- final GLProfile glp = GLProfile.getGL2ES2();
- final FBOMix2DemosES2 demo = new FBOMix2DemosES2(0);
- demo.setDoRotation(false);
- final GLCapabilities caps = new GLCapabilities(glp);
- testGLFBODrawableImpl(caps, demo);
- }
-
- @Test
- public void testGL2ES2_FBODemoMSAA4() throws InterruptedException {
- final GLProfile glp = GLProfile.getGL2ES2();
- final FBOMix2DemosES2 demo = new FBOMix2DemosES2(0);
- demo.setDoRotation(false);
- final GLCapabilities caps = new GLCapabilities(glp);
- caps.setSampleBuffers(true);
- caps.setNumSamples(4);
- testGLFBODrawableImpl(caps, demo);
- }
-
- @Test
- public void testEGLES2_Demo0Normal() throws InterruptedException {
- if( GLProfile.isAvailable(GLProfile.GLES2) ) {
- final GLProfile glp = GLProfile.get(GLProfile.GLES2);
- final GLCapabilities caps = new GLCapabilities(glp);
- testGLFBODrawableImpl(caps, new GearsES2(0));
- } else {
- System.err.println("EGL ES2 n/a");
- }
- }
-
- @Test
- public void testEGLES2_Demo0MSAA4() throws InterruptedException {
- if( GLProfile.isAvailable(GLProfile.GLES2) ) {
- final GLProfile glp = GLProfile.get(GLProfile.GLES2);
- final GLCapabilities caps = new GLCapabilities(glp);
- caps.setSampleBuffers(true);
- caps.setNumSamples(4);
- testGLFBODrawableImpl(caps, new GearsES2(0));
- } else {
- System.err.println("EGL ES2 n/a");
- }
- }
-
- boolean skipShot = false;
-
- void testGLFBODrawableImpl(GLCapabilities caps, GLEventListener demo) throws InterruptedException {
- final GLReadBufferUtil screenshot = new GLReadBufferUtil(false, false);
- caps.setFBO(true);
- final GLDrawableFactory factory = GLDrawableFactory.getFactory(caps.getGLProfile());
- final GLDrawable fboDrawable = factory.createOffscreenDrawable(null, caps, null, widthStep*szStep, heightStep*szStep);
- Assert.assertNotNull(fboDrawable);
- Assert.assertTrue("Not an FBO Drawable", fboDrawable instanceof GLFBODrawableImpl);
-
- fboDrawable.setRealized(true);
- Assert.assertTrue(fboDrawable.isRealized());
-
- final FBObject fbo = ((GLFBODrawableImpl)fboDrawable).getFBObject();
-
- System.out.println("Realized: "+fboDrawable);
- System.out.println("Realized: "+fboDrawable.getChosenGLCapabilities());
- System.out.println("Realized: "+fbo);
-
- final GLContext context = fboDrawable.createContext(null);
- Assert.assertNotNull(context);
-
- int res = context.makeCurrent();
- Assert.assertTrue(GLContext.CONTEXT_CURRENT_NEW==res || GLContext.CONTEXT_CURRENT==res);
- context.release();
-
- System.out.println("Post Create-Ctx: "+fbo);
- final FBObject.Colorbuffer colorA = fbo.getColorbuffer(0);
- Assert.assertNotNull(colorA);
- final FBObject.RenderAttachment depthA = fbo.getDepthAttachment();
- Assert.assertNotNull(depthA);
-
- final OffscreenAutoDrawable glad = new OffscreenAutoDrawable(fboDrawable, context, true);
-
- glad.addGLEventListener(demo);
- glad.addGLEventListener(new GLEventListener() {
- volatile int displayCount=0;
- volatile int reshapeCount=0;
- public void init(GLAutoDrawable drawable) {}
- public void dispose(GLAutoDrawable drawable) {}
- public void display(GLAutoDrawable drawable) {
- final GL gl = drawable.getGL();
- // System.err.println(Thread.currentThread().getName()+": ** display: "+displayCount+": step "+szStep+" "+drawable.getWidth()+"x"+drawable.getHeight());
- // System.err.println(Thread.currentThread().getName()+": ** FBO-THIS: "+fbo);
- // System.err.println(Thread.currentThread().getName()+": ** FBO-SINK: "+fbo.getSamplingSinkFBO());
- // System.err.println(Thread.currentThread().getName()+": ** drawable-read: "+gl.getDefaultReadFramebuffer());
- if(skipShot) {
- skipShot=false;
- } else {
- snapshot(getSimpleTestName("."), displayCount, "msaa"+fbo.getNumSamples(), gl, screenshot, TextureIO.PNG, null);
- }
- Assert.assertEquals(drawable.getWidth(), widthStep*szStep);
- Assert.assertEquals(drawable.getHeight(), heightStep*szStep);
- displayCount++;
- }
- public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
- System.err.println(Thread.currentThread().getName()+": ** reshape: "+reshapeCount+": step "+szStep+" "+width+"x"+height+" - "+drawable.getWidth()+"x"+drawable.getHeight());
- Assert.assertEquals(drawable.getWidth(), widthStep*szStep);
- Assert.assertEquals(drawable.getHeight(), heightStep*szStep);
- reshapeCount++;
- }
- });
-
- // 0 - szStep = 2
- glad.display();
-
- // 1, 2 (resize + display)
- szStep = 1;
- skipShot=true;
- glad.setSize(widthStep*szStep, heightStep*szStep);
- glad.display();
- Assert.assertEquals(glad.getWidth(), widthStep*szStep);
- Assert.assertEquals(glad.getHeight(), heightStep*szStep);
- {
- // Check whether the attachment reference are still valid!
- FBObject.Colorbuffer _colorA = fbo.getColorbuffer(0);
- Assert.assertNotNull(_colorA);
- Assert.assertTrue(colorA == _colorA);
- Assert.assertTrue(colorA.equals(_colorA));
- FBObject.RenderAttachment _depthA = fbo.getDepthAttachment();
- Assert.assertNotNull(_depthA);
- Assert.assertTrue(depthA == _depthA);
- Assert.assertTrue(depthA.equals(_depthA));
-
- _colorA = fbo.getColorbuffer(colorA);
- Assert.assertNotNull(_colorA);
- Assert.assertTrue(colorA == _colorA);
- Assert.assertTrue(colorA.equals(_colorA));
- }
-
- // 3, 4 (resize + display)
- szStep = 4;
- skipShot=true;
- glad.setSize(widthStep*szStep, heightStep*szStep);
- glad.display();
- Assert.assertEquals(glad.getWidth(), widthStep*szStep);
- Assert.assertEquals(glad.getHeight(), heightStep*szStep);
- {
- // Check whether the attachment reference are still valid!
- FBObject.Colorbuffer _colorA = fbo.getColorbuffer(0);
- Assert.assertNotNull(_colorA);
- Assert.assertTrue(colorA == _colorA);
- final FBObject.RenderAttachment _depthA = fbo.getDepthAttachment();
- Assert.assertNotNull(_depthA);
- Assert.assertTrue(depthA == _depthA);
-
- _colorA = fbo.getColorbuffer(colorA);
- Assert.assertNotNull(_colorA);
- Assert.assertTrue(colorA == _colorA);
- }
-
- // 5
- glad.display();
- Assert.assertEquals(glad.getWidth(), widthStep*szStep);
- Assert.assertEquals(glad.getHeight(), heightStep*szStep);
-
- // 6, 7 (resize + display)
- szStep = 3;
- skipShot=true;
- glad.setSize(widthStep*szStep, heightStep*szStep);
- glad.display();
- Assert.assertEquals(glad.getWidth(), widthStep*szStep);
- Assert.assertEquals(glad.getHeight(), heightStep*szStep);
-
- glad.destroy();
- System.out.println("Fin: "+fboDrawable);
-
- // final GLAutoDrawableDelegate glad = new GLAutoDrawableDelegate(fboDrawable, context);
- }
-
- public static void main(String args[]) throws IOException {
- org.junit.runner.JUnitCore.main(TestFBODrawableNEWT.class.getName());
- }
-
-}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMRTNEWT01.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMRTNEWT01.java
index f7c83a0..e5075bb 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMRTNEWT01.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMRTNEWT01.java
@@ -50,7 +50,6 @@ import javax.media.opengl.GL2ES2;
import javax.media.opengl.GL2GL3;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLDrawable;
-import javax.media.opengl.GLPipelineFactory;
import javax.media.opengl.GLProfile;
import javax.media.opengl.GLUniformData;
@@ -74,7 +73,7 @@ public class TestFBOMRTNEWT01 extends UITestCase {
new GLCapabilities(GLProfile.getGL2GL3()), width/step, height/step, true);
final GLDrawable drawable = winctx.context.getGLDrawable();
GL2GL3 gl = winctx.context.getGL().getGL2GL3();
- gl = gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Debug", null, gl, null) ).getGL2GL3();
+ // gl = gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Debug", null, gl, null) ).getGL2GL3();
System.err.println(winctx.context);
Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
@@ -88,8 +87,8 @@ public class TestFBOMRTNEWT01 extends UITestCase {
"shader/bin", "fbo-mrt-1", false);
final ShaderProgram sp0 = new ShaderProgram();
sp0.add(gl, vp0, System.err);
- sp0.add(gl, fp0, System.err);
- Assert.assertTrue(0<=sp0.program());
+ sp0.add(gl, fp0, System.err);
+ Assert.assertTrue(0 != sp0.program());
Assert.assertTrue(!sp0.inUse());
Assert.assertTrue(!sp0.linked());
Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
@@ -102,7 +101,7 @@ public class TestFBOMRTNEWT01 extends UITestCase {
final ShaderProgram sp1 = new ShaderProgram();
sp1.add(gl, vp1, System.err);
sp1.add(gl, fp1, System.err);
- Assert.assertTrue(0<=sp1.program());
+ Assert.assertTrue(0 != sp1.program());
Assert.assertTrue(!sp1.inUse());
Assert.assertTrue(!sp1.linked());
Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
@@ -162,7 +161,13 @@ public class TestFBOMRTNEWT01 extends UITestCase {
final FBObject fbo_mrt = new FBObject();
fbo_mrt.reset(gl, drawable.getWidth(), drawable.getHeight());
final TextureAttachment texA0 = fbo_mrt.attachTexture2D(gl, texA0Point, true, GL.GL_NEAREST, GL.GL_NEAREST, GL.GL_CLAMP_TO_EDGE, GL.GL_CLAMP_TO_EDGE);
- final TextureAttachment texA1 = fbo_mrt.attachTexture2D(gl, texA1Point, true, GL.GL_NEAREST, GL.GL_NEAREST, GL.GL_CLAMP_TO_EDGE, GL.GL_CLAMP_TO_EDGE);
+ final TextureAttachment texA1;
+ if(fbo_mrt.getMaxColorAttachments() > 1) {
+ texA1 = fbo_mrt.attachTexture2D(gl, texA1Point, true, GL.GL_NEAREST, GL.GL_NEAREST, GL.GL_CLAMP_TO_EDGE, GL.GL_CLAMP_TO_EDGE);
+ } else {
+ texA1 = null;
+ System.err.println("FBO supports only one attachment, no MRT available!");
+ }
fbo_mrt.attachRenderbuffer(gl, Type.DEPTH, 24);
Assert.assertTrue( fbo_mrt.isStatusValid() ) ;
fbo_mrt.unbind(gl);
@@ -216,8 +221,10 @@ public class TestFBOMRTNEWT01 extends UITestCase {
gl.glActiveTexture(GL.GL_TEXTURE0 + texUnit0.intValue());
fbo_mrt.use(gl, texA0);
- gl.glActiveTexture(GL.GL_TEXTURE0 + texUnit1.intValue());
- fbo_mrt.use(gl, texA1);
+ if(null != texA1) {
+ gl.glActiveTexture(GL.GL_TEXTURE0 + texUnit1.intValue());
+ fbo_mrt.use(gl, texA1);
+ }
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
gl.glDrawArrays(GL.GL_TRIANGLE_STRIP, 0, 4);
fbo_mrt.unuse(gl);
@@ -229,7 +236,7 @@ public class TestFBOMRTNEWT01 extends UITestCase {
final NativeSurface ns = gl.getContext().getGLReadDrawable().getNativeSurface();
if(last_snap_size[0] != ns.getWidth() && last_snap_size[1] != ns.getHeight()) {
gl.glFinish(); // sync .. no swap buffers yet!
- snapshot(getSimpleTestName("."), step_i, null, gl, screenshot, TextureIO.PNG, null); // overwrite ok
+ snapshot(step_i, null, gl, screenshot, TextureIO.PNG, null); // overwrite ok
last_snap_size[0] = ns.getWidth();
last_snap_size[1] = ns.getHeight();
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMix2DemosES2NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMix2DemosES2NEWT.java
index b384c93..b3c542c 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMix2DemosES2NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMix2DemosES2NEWT.java
@@ -106,7 +106,7 @@ public class TestFBOMix2DemosES2NEWT extends UITestCase {
if(dw<800) {
System.err.println("XXX: "+dw+"x"+dh+", c "+c);
if(0 == c%3) {
- snapshot(getSimpleTestName("."), i++, "msaa"+demo.getMSAA(), drawable.getGL(), screenshot, TextureIO.PNG, null);
+ snapshot(i++, "msaa"+demo.getMSAA(), drawable.getGL(), screenshot, TextureIO.PNG, null);
}
if( 3 == c ) {
new Thread() {
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMix2DemosES2NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOOffThreadSharedContextMix2DemosES2NEWT.java
similarity index 54%
copy from src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMix2DemosES2NEWT.java
copy to src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOOffThreadSharedContextMix2DemosES2NEWT.java
index b384c93..3ecf89b 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMix2DemosES2NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOOffThreadSharedContextMix2DemosES2NEWT.java
@@ -32,8 +32,6 @@ import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
-import com.jogamp.newt.event.KeyAdapter;
-import com.jogamp.newt.event.KeyEvent;
import com.jogamp.newt.event.WindowEvent;
import com.jogamp.newt.event.WindowAdapter;
import com.jogamp.newt.opengl.GLWindow;
@@ -43,58 +41,134 @@ import com.jogamp.opengl.test.junit.util.UITestCase;
import com.jogamp.opengl.test.junit.util.QuitAdapter;
import com.jogamp.opengl.util.Animator;
+import com.jogamp.opengl.util.FPSAnimator;
import com.jogamp.opengl.util.GLReadBufferUtil;
import com.jogamp.opengl.util.texture.TextureIO;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.Mix2TexturesES2;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.RedSquareES2;
-import com.jogamp.opengl.test.junit.jogl.demos.es2.FBOMix2DemosES2;
-
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.SurfaceUpdatedListener;
+import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLOffscreenAutoDrawable;
import javax.media.opengl.GLProfile;
import org.junit.Assert;
import org.junit.AfterClass;
import org.junit.Test;
-public class TestFBOMix2DemosES2NEWT extends UITestCase {
+/**
+ * Toolkit agnostic {@link GLOffscreenAutoDrawable.FBO} tests using the
+ * {@link GLDrawableFactory#createOffscreenAutoDrawable(javax.media.nativewindow.AbstractGraphicsDevice, GLCapabilitiesImmutable, javax.media.opengl.GLCapabilitiesChooser, int, int, GLContext) factory model}.
+ * <p>
+ * The created {@link GLOffscreenAutoDrawable.FBO} is being used to run the {@link GLEventListener}.
+ * </p>
+ * <p>
+ * This test simulates shared off-thread GL context / texture usage,
+ * where the producer use FBOs and delivers shared textures.
+ * The receiver blends the shared textures onscreen.
+ * In detail the test consist of:
+ * <ul>
+ * <li>2 {@link GLOffscreenAutoDrawable.FBO} double buffered
+ * <ul>
+ * <li>each with their own {@link GLContext}, which is shares the {@link GLWindow} one (see below)</li>
+ * <li>both run within one {@link FPSAnimator} @ 30fps</li>
+ * <li>produce a texture</li>
+ * <li>notify the onscreen renderer about new textureID (swapping double buffer)</li>
+ * </ul></li>
+ * <li>1 onscreen {@link GLWindow}
+ * <ul>
+ * <li>shares it's {@link GLContext} w/ above FBOs</li>
+ * <li>running within one {@link Animator} at v-sync</li>
+ * <li>uses the shared FBO textures and blends them onscreen</li>
+ * </ul></li>
+ * </ul>
+ * </p>
+ */
+public class TestFBOOffThreadSharedContextMix2DemosES2NEWT extends UITestCase {
static long duration = 500; // ms
static int swapInterval = 1;
static boolean showFPS = false;
static boolean forceES2 = false;
- static boolean doRotate = true;
- static boolean demo0Only = false;
- static int globalNumSamples = 0;
static boolean mainRun = false;
-
+
@AfterClass
public static void releaseClass() {
}
- protected void runTestGL(GLCapabilitiesImmutable caps, int numSamples) throws InterruptedException {
- final GLReadBufferUtil screenshot = new GLReadBufferUtil(true, false);
+ protected void runTestGL(GLCapabilitiesImmutable caps) throws InterruptedException {
+ final GLReadBufferUtil screenshot = new GLReadBufferUtil(false, false);
System.err.println("requested: vsync "+swapInterval+", "+caps);
+
final GLWindow glWindow = GLWindow.create(caps);
Assert.assertNotNull(glWindow);
glWindow.setTitle("Gears NEWT Test (translucent "+!caps.isBackgroundOpaque()+"), swapInterval "+swapInterval);
if(mainRun) {
glWindow.setSize(512, 512);
} else {
- glWindow.setSize(128, 128);
+ glWindow.setSize(256, 256);
+ }
+ // eager initialization of context
+ glWindow.setVisible(true);
+ glWindow.display();
+
+ final int fbod1_texUnit = 0;
+ final int fbod2_texUnit = 1;
+
+ final GLDrawableFactory factory = GLDrawableFactory.getFactory(caps.getGLProfile());
+ GLCapabilities fbodCaps = (GLCapabilities) caps.cloneMutable();
+ // fbodCaps.setDoubleBuffered(false);
+
+ final Mix2TexturesES2 mixerDemo = new Mix2TexturesES2(1, fbod1_texUnit, fbod2_texUnit);
+
+ // FBOD1
+ final GLOffscreenAutoDrawable.FBO fbod1 = (GLOffscreenAutoDrawable.FBO)
+ factory.createOffscreenAutoDrawable(null, fbodCaps, null, glWindow.getWidth(), glWindow.getHeight(), glWindow.getContext());
+ fbod1.setUpstreamWidget(glWindow); // connect the real GLWindow (mouse/key) to offscreen!
+ fbod1.setTextureUnit(fbod1_texUnit);
+ {
+ GearsES2 demo0 = new GearsES2(-1);
+ fbod1.addGLEventListener(demo0);
+ demo0.setIgnoreFocus(true);
}
+ fbod1.getNativeSurface().addSurfaceUpdatedListener(new SurfaceUpdatedListener() {
+ @Override
+ public void surfaceUpdated(Object updater, NativeSurface ns, long when) {
+ mixerDemo.setTexID0(fbod1.getTextureBuffer(GL.GL_FRONT).getName());
+ } });
+ fbod1.display(); // init
+ System.err.println("FBOD1 "+fbod1);
+ Assert.assertTrue(fbod1.isInitialized());
+
+ // FBOD2
+ final GLOffscreenAutoDrawable.FBO fbod2 = (GLOffscreenAutoDrawable.FBO)
+ factory.createOffscreenAutoDrawable(null, fbodCaps, null, glWindow.getWidth(), glWindow.getHeight(), glWindow.getContext());
+ fbod2.setTextureUnit(fbod2_texUnit);
+ fbod2.addGLEventListener(new RedSquareES2(-1));
+ fbod2.getNativeSurface().addSurfaceUpdatedListener(new SurfaceUpdatedListener() {
+ @Override
+ public void surfaceUpdated(Object updater, NativeSurface ns, long when) {
+ mixerDemo.setTexID1(fbod2.getTextureBuffer(GL.GL_FRONT).getName());
+ } });
+ fbod2.display(); // init
+ System.err.println("FBOD2 "+fbod2);
+ Assert.assertTrue(fbod2.isInitialized());
- final FBOMix2DemosES2 demo = new FBOMix2DemosES2(swapInterval);
- demo.setMSAA(numSamples);
- demo.setDoRotation(doRotate);
- demo.setDemo0Only(demo0Only);
- glWindow.addGLEventListener(demo);
+ // preinit texIDs
+ mixerDemo.setTexID0(fbod1.getTextureBuffer(GL.GL_FRONT).getName());
+ mixerDemo.setTexID1(fbod2.getTextureBuffer(GL.GL_FRONT).getName());
+
+ glWindow.addGLEventListener(mixerDemo);
glWindow.addGLEventListener(new GLEventListener() {
int i=0, c=0;
- int origS;
- public void init(GLAutoDrawable drawable) {
- origS = demo.getMSAA();
- }
+ public void init(GLAutoDrawable drawable) {}
public void dispose(GLAutoDrawable drawable) {}
public void display(GLAutoDrawable drawable) {
if(mainRun) return;
@@ -105,36 +179,32 @@ public class TestFBOMix2DemosES2NEWT extends UITestCase {
if(dw<800) {
System.err.println("XXX: "+dw+"x"+dh+", c "+c);
- if(0 == c%3) {
- snapshot(getSimpleTestName("."), i++, "msaa"+demo.getMSAA(), drawable.getGL(), screenshot, TextureIO.PNG, null);
+ if(8 == c) {
+ snapshot(i++, "msaa"+fbod1.getNumSamples(), drawable.getGL(), screenshot, TextureIO.PNG, null);
}
- if( 3 == c ) {
- new Thread() {
- @Override
- public void run() {
- demo.setMSAA(4);
- } }.start();
- } else if( 6 == c ) {
- new Thread() {
- @Override
- public void run() {
- demo.setMSAA(8);
- } }.start();
- } else if(9 == c) {
+ if(9 == c) {
c=0;
new Thread() {
@Override
public void run() {
glWindow.setSize(dw+256, dh+256);
- demo.setMSAA(origS);
} }.start();
}
}
}
- public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { }
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
+ fbod1.setSize(width, height);
+ fbod2.setSize(width, height);
+ }
});
- Animator animator = new Animator(glWindow);
+ final FPSAnimator animator0 = new FPSAnimator(30);
+ animator0.add(fbod1);
+ animator0.add(fbod2);
+
+ final Animator animator1 = new Animator();
+ animator1.add(glWindow);
+
QuitAdapter quitAdapter = new QuitAdapter();
//glWindow.addKeyListener(new TraceKeyAdapter(quitAdapter));
@@ -151,30 +221,8 @@ public class TestFBOMix2DemosES2NEWT extends UITestCase {
}
});
- glWindow.addKeyListener(new KeyAdapter() {
- public void keyTyped(KeyEvent e) {
- System.err.println("*** "+e);
- if(e.getKeyChar()=='f') {
- new Thread() {
- public void run() {
- System.err.println("[set fullscreen pre]: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", f "+glWindow.isFullscreen()+", a "+glWindow.isAlwaysOnTop()+", "+glWindow.getInsets());
- glWindow.setFullscreen(!glWindow.isFullscreen());
- System.err.println("[set fullscreen post]: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", f "+glWindow.isFullscreen()+", a "+glWindow.isAlwaysOnTop()+", "+glWindow.getInsets());
- } }.start();
- } else if(e.getKeyChar()=='d') {
- demo.setDemo0Only(!demo.getDemo0Only());
- } else {
- int num = e.getKeyChar() - '0';
- System.err.println("*** "+num);
- if(0 <= num && num <= 8) {
- System.err.println("MSAA: "+demo.getMSAA()+" -> "+num);
- demo.setMSAA(num);
- }
- }
- }
- });
-
- animator.start();
+ animator0.start();
+ animator1.start();
// glWindow.setSkipContextReleaseThread(animator.getThread());
glWindow.setVisible(true);
@@ -183,36 +231,35 @@ public class TestFBOMix2DemosES2NEWT extends UITestCase {
System.err.println("GL chosen: "+glWindow.getChosenCapabilities());
System.err.println("window pos/siz: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", "+glWindow.getInsets());
- animator.setUpdateFPSFrames(60, showFPS ? System.err : null);
+ animator0.setUpdateFPSFrames(30, showFPS ? System.err : null);
+ animator1.setUpdateFPSFrames(60, showFPS ? System.err : null);
- while(!quitAdapter.shouldQuit() && animator.isAnimating() && animator.getTotalFPSDuration()<duration) {
+ while(!quitAdapter.shouldQuit() && animator1.isAnimating() && animator1.getTotalFPSDuration()<duration) {
Thread.sleep(100);
}
- animator.stop();
- Assert.assertFalse(animator.isAnimating());
- Assert.assertFalse(animator.isStarted());
+ animator0.stop();
+ Assert.assertFalse(animator0.isAnimating());
+ Assert.assertFalse(animator0.isStarted());
+
+ animator1.stop();
+ Assert.assertFalse(animator1.isAnimating());
+ Assert.assertFalse(animator1.isStarted());
+
+ fbod1.destroy();
+ fbod2.destroy();
+
glWindow.destroy();
Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glWindow, false));
}
@Test
- public void test01_Main() throws InterruptedException {
- if( mainRun ) {
- GLCapabilities caps = new GLCapabilities(forceES2 ? GLProfile.get(GLProfile.GLES2) : GLProfile.getGL2ES2());
- caps.setAlphaBits(1);
- runTestGL(caps, globalNumSamples);
- }
- }
-
- @Test
public void test01() throws InterruptedException {
- if( mainRun ) return ;
GLCapabilities caps = new GLCapabilities(forceES2 ? GLProfile.get(GLProfile.GLES2) : GLProfile.getGL2ES2());
caps.setAlphaBits(1);
- runTestGL(caps, 0);
+ runTestGL(caps);
}
-
+
public static void main(String args[]) throws IOException {
boolean waitForKey = false;
@@ -229,13 +276,6 @@ public class TestFBOMix2DemosES2NEWT extends UITestCase {
forceES2 = true;
} else if(args[i].equals("-showFPS")) {
showFPS = true;
- } else if(args[i].equals("-samples")) {
- i++;
- globalNumSamples = MiscUtils.atoi(args[i], globalNumSamples);
- } else if(args[i].equals("-norotate")) {
- doRotate = false;
- } else if(args[i].equals("-demo0Only")) {
- demo0Only = true;
} else if(args[i].equals("-wait")) {
waitForKey = true;
} else if(args[i].equals("-nomain")) {
@@ -253,6 +293,6 @@ public class TestFBOMix2DemosES2NEWT extends UITestCase {
System.err.println(stdin.readLine());
} catch (IOException e) { }
}
- org.junit.runner.JUnitCore.main(TestFBOMix2DemosES2NEWT.class.getName());
+ org.junit.runner.JUnitCore.main(TestFBOOffThreadSharedContextMix2DemosES2NEWT.class.getName());
}
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMix2DemosES2NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOOnThreadSharedContext1DemoES2NEWT.java
similarity index 60%
copy from src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMix2DemosES2NEWT.java
copy to src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOOnThreadSharedContext1DemoES2NEWT.java
index b384c93..7d9a9c6 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMix2DemosES2NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOOnThreadSharedContext1DemoES2NEWT.java
@@ -32,8 +32,6 @@ import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
-import com.jogamp.newt.event.KeyAdapter;
-import com.jogamp.newt.event.KeyEvent;
import com.jogamp.newt.event.WindowEvent;
import com.jogamp.newt.event.WindowAdapter;
import com.jogamp.newt.opengl.GLWindow;
@@ -45,56 +43,120 @@ import com.jogamp.opengl.test.junit.util.QuitAdapter;
import com.jogamp.opengl.util.Animator;
import com.jogamp.opengl.util.GLReadBufferUtil;
import com.jogamp.opengl.util.texture.TextureIO;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.Mix2TexturesES2;
-import com.jogamp.opengl.test.junit.jogl.demos.es2.FBOMix2DemosES2;
-
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.SurfaceUpdatedListener;
+import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLOffscreenAutoDrawable;
import javax.media.opengl.GLProfile;
import org.junit.Assert;
import org.junit.AfterClass;
import org.junit.Test;
-public class TestFBOMix2DemosES2NEWT extends UITestCase {
+/**
+ * Toolkit agnostic {@link GLOffscreenAutoDrawable.FBO} tests using the
+ * {@link GLDrawableFactory#createOffscreenAutoDrawable(javax.media.nativewindow.AbstractGraphicsDevice, GLCapabilitiesImmutable, javax.media.opengl.GLCapabilitiesChooser, int, int, GLContext) factory model}.
+ * <p>
+ * The created {@link GLOffscreenAutoDrawable.FBO} is being used to run the {@link GLEventListener}.
+ * </p>
+ * <p>
+ * This test simulates shared on-thread GL context / texture usage,
+ * where the producer uses an FBO and delivers a shared texture.
+ * The receiver draws the shared texture onscreen.
+ * In detail the test consist of:
+ * <ul>
+ * <li>1 {@link GLOffscreenAutoDrawable.FBO} double buffered
+ * <ul>
+ * <liwith its own {@link GLContext}, which is shares the {@link GLWindow} one (see below)</li>
+ * <li>running within common {@link Animator} @ 60fps</li>
+ * <li>produce a texture</li>
+ * <li>notify the onscreen renderer about new textureID (swapping double buffer)</li>
+ * </ul></li>
+ * <li>1 onscreen {@link GLWindow}
+ * <ul>
+ * <li>shares it's {@link GLContext} w/ above FBO</li>
+ * <li>running within common {@link Animator} @ 60fps</li>
+ * <li>uses the shared FBO texture and draws it onscreen</li>
+ * </ul></li>
+ * </ul>
+ * </p>
+ */
+public class TestFBOOnThreadSharedContext1DemoES2NEWT extends UITestCase {
static long duration = 500; // ms
static int swapInterval = 1;
static boolean showFPS = false;
static boolean forceES2 = false;
- static boolean doRotate = true;
- static boolean demo0Only = false;
- static int globalNumSamples = 0;
static boolean mainRun = false;
-
+
@AfterClass
public static void releaseClass() {
}
- protected void runTestGL(GLCapabilitiesImmutable caps, int numSamples) throws InterruptedException {
- final GLReadBufferUtil screenshot = new GLReadBufferUtil(true, false);
+ protected void runTestGL(GLCapabilitiesImmutable caps) throws InterruptedException {
+ final GLReadBufferUtil screenshot = new GLReadBufferUtil(false, false);
System.err.println("requested: vsync "+swapInterval+", "+caps);
+
final GLWindow glWindow = GLWindow.create(caps);
Assert.assertNotNull(glWindow);
glWindow.setTitle("Gears NEWT Test (translucent "+!caps.isBackgroundOpaque()+"), swapInterval "+swapInterval);
if(mainRun) {
glWindow.setSize(512, 512);
} else {
- glWindow.setSize(128, 128);
+ glWindow.setSize(256, 256);
}
+ // eager initialization of context
+ glWindow.setVisible(true);
+ glWindow.display();
+
+ final int fbod1_texUnit = 0;
+
+ final GLDrawableFactory factory = GLDrawableFactory.getFactory(caps.getGLProfile());
+ GLCapabilities fbodCaps = (GLCapabilities) caps.cloneMutable();
+ // fbodCaps.setDoubleBuffered(false);
+
+ final Mix2TexturesES2 mixerDemo = new Mix2TexturesES2(1, fbod1_texUnit, 0);
- final FBOMix2DemosES2 demo = new FBOMix2DemosES2(swapInterval);
- demo.setMSAA(numSamples);
- demo.setDoRotation(doRotate);
- demo.setDemo0Only(demo0Only);
- glWindow.addGLEventListener(demo);
+ // FBOD1
+ final GLOffscreenAutoDrawable.FBO fbod1 = (GLOffscreenAutoDrawable.FBO)
+ factory.createOffscreenAutoDrawable(null, fbodCaps, null, glWindow.getWidth(), glWindow.getHeight(), glWindow.getContext());
+ fbod1.setUpstreamWidget(glWindow); // connect the real GLWindow (mouse/key) to offscreen!
+ fbod1.setTextureUnit(fbod1_texUnit);
+ {
+ GearsES2 demo0 = new GearsES2(-1);
+ fbod1.addGLEventListener(demo0);
+ demo0.setIgnoreFocus(true);
+ }
+ fbod1.getNativeSurface().addSurfaceUpdatedListener(new SurfaceUpdatedListener() {
+ @Override
+ public void surfaceUpdated(Object updater, NativeSurface ns, long when) {
+ mixerDemo.setTexID0(fbod1.getTextureBuffer(GL.GL_FRONT).getName());
+ } });
+ fbod1.display(); // init
+ System.err.println("FBOD1 "+fbod1);
+ Assert.assertTrue(fbod1.isInitialized());
+
+ // preinit texIDs
+ mixerDemo.setTexID0(fbod1.getTextureBuffer(GL.GL_FRONT).getName());
+
+ glWindow.addWindowListener(new WindowAdapter() {
+ @Override
+ public void windowResized(WindowEvent e) {
+ fbod1.setSize(glWindow.getWidth(), glWindow.getHeight());
+ }
+ });
+ glWindow.addGLEventListener(mixerDemo);
glWindow.addGLEventListener(new GLEventListener() {
int i=0, c=0;
- int origS;
- public void init(GLAutoDrawable drawable) {
- origS = demo.getMSAA();
- }
+ public void init(GLAutoDrawable drawable) {}
public void dispose(GLAutoDrawable drawable) {}
public void display(GLAutoDrawable drawable) {
if(mainRun) return;
@@ -105,36 +167,26 @@ public class TestFBOMix2DemosES2NEWT extends UITestCase {
if(dw<800) {
System.err.println("XXX: "+dw+"x"+dh+", c "+c);
- if(0 == c%3) {
- snapshot(getSimpleTestName("."), i++, "msaa"+demo.getMSAA(), drawable.getGL(), screenshot, TextureIO.PNG, null);
+ if(8 == c) {
+ snapshot(i++, "msaa"+fbod1.getNumSamples(), drawable.getGL(), screenshot, TextureIO.PNG, null);
}
- if( 3 == c ) {
- new Thread() {
- @Override
- public void run() {
- demo.setMSAA(4);
- } }.start();
- } else if( 6 == c ) {
- new Thread() {
- @Override
- public void run() {
- demo.setMSAA(8);
- } }.start();
- } else if(9 == c) {
+ if(9 == c) {
c=0;
new Thread() {
@Override
public void run() {
glWindow.setSize(dw+256, dh+256);
- demo.setMSAA(origS);
} }.start();
}
}
}
- public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { }
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { }
});
- Animator animator = new Animator(glWindow);
+ final Animator animator1 = new Animator();
+ animator1.add(fbod1);
+ animator1.add(glWindow);
+
QuitAdapter quitAdapter = new QuitAdapter();
//glWindow.addKeyListener(new TraceKeyAdapter(quitAdapter));
@@ -151,30 +203,7 @@ public class TestFBOMix2DemosES2NEWT extends UITestCase {
}
});
- glWindow.addKeyListener(new KeyAdapter() {
- public void keyTyped(KeyEvent e) {
- System.err.println("*** "+e);
- if(e.getKeyChar()=='f') {
- new Thread() {
- public void run() {
- System.err.println("[set fullscreen pre]: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", f "+glWindow.isFullscreen()+", a "+glWindow.isAlwaysOnTop()+", "+glWindow.getInsets());
- glWindow.setFullscreen(!glWindow.isFullscreen());
- System.err.println("[set fullscreen post]: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", f "+glWindow.isFullscreen()+", a "+glWindow.isAlwaysOnTop()+", "+glWindow.getInsets());
- } }.start();
- } else if(e.getKeyChar()=='d') {
- demo.setDemo0Only(!demo.getDemo0Only());
- } else {
- int num = e.getKeyChar() - '0';
- System.err.println("*** "+num);
- if(0 <= num && num <= 8) {
- System.err.println("MSAA: "+demo.getMSAA()+" -> "+num);
- demo.setMSAA(num);
- }
- }
- }
- });
-
- animator.start();
+ animator1.start();
// glWindow.setSkipContextReleaseThread(animator.getThread());
glWindow.setVisible(true);
@@ -183,36 +212,29 @@ public class TestFBOMix2DemosES2NEWT extends UITestCase {
System.err.println("GL chosen: "+glWindow.getChosenCapabilities());
System.err.println("window pos/siz: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", "+glWindow.getInsets());
- animator.setUpdateFPSFrames(60, showFPS ? System.err : null);
+ animator1.setUpdateFPSFrames(60, showFPS ? System.err : null);
- while(!quitAdapter.shouldQuit() && animator.isAnimating() && animator.getTotalFPSDuration()<duration) {
+ while(!quitAdapter.shouldQuit() && animator1.isAnimating() && animator1.getTotalFPSDuration()<duration) {
Thread.sleep(100);
}
- animator.stop();
- Assert.assertFalse(animator.isAnimating());
- Assert.assertFalse(animator.isStarted());
+ animator1.stop();
+ Assert.assertFalse(animator1.isAnimating());
+ Assert.assertFalse(animator1.isStarted());
+
+ fbod1.destroy();
+
glWindow.destroy();
Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glWindow, false));
}
@Test
- public void test01_Main() throws InterruptedException {
- if( mainRun ) {
- GLCapabilities caps = new GLCapabilities(forceES2 ? GLProfile.get(GLProfile.GLES2) : GLProfile.getGL2ES2());
- caps.setAlphaBits(1);
- runTestGL(caps, globalNumSamples);
- }
- }
-
- @Test
public void test01() throws InterruptedException {
- if( mainRun ) return ;
GLCapabilities caps = new GLCapabilities(forceES2 ? GLProfile.get(GLProfile.GLES2) : GLProfile.getGL2ES2());
caps.setAlphaBits(1);
- runTestGL(caps, 0);
+ runTestGL(caps);
}
-
+
public static void main(String args[]) throws IOException {
boolean waitForKey = false;
@@ -229,13 +251,6 @@ public class TestFBOMix2DemosES2NEWT extends UITestCase {
forceES2 = true;
} else if(args[i].equals("-showFPS")) {
showFPS = true;
- } else if(args[i].equals("-samples")) {
- i++;
- globalNumSamples = MiscUtils.atoi(args[i], globalNumSamples);
- } else if(args[i].equals("-norotate")) {
- doRotate = false;
- } else if(args[i].equals("-demo0Only")) {
- demo0Only = true;
} else if(args[i].equals("-wait")) {
waitForKey = true;
} else if(args[i].equals("-nomain")) {
@@ -253,6 +268,6 @@ public class TestFBOMix2DemosES2NEWT extends UITestCase {
System.err.println(stdin.readLine());
} catch (IOException e) { }
}
- org.junit.runner.JUnitCore.main(TestFBOMix2DemosES2NEWT.class.getName());
+ org.junit.runner.JUnitCore.main(TestFBOOnThreadSharedContext1DemoES2NEWT.class.getName());
}
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableDelegateNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableDelegateNEWT.java
deleted file mode 100644
index 96d9b2e..0000000
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableDelegateNEWT.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/**
- * Copyright 2012 JogAmp Community. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are
- * permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- *
- * 2. 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.
- *
- * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community OR
- * CONTRIBUTORS 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.
- *
- * The views and conclusions contained in the software and documentation are those of the
- * authors and should not be interpreted as representing official policies, either expressed
- * or implied, of JogAmp Community.
- */
-
-package com.jogamp.opengl.test.junit.jogl.acore;
-
-import java.io.IOException;
-
-import javax.media.opengl.GLAutoDrawable;
-import javax.media.opengl.GLAutoDrawableDelegate;
-import javax.media.opengl.GLCapabilities;
-import javax.media.opengl.GLContext;
-import javax.media.opengl.GLDrawable;
-import javax.media.opengl.GLDrawableFactory;
-import javax.media.opengl.GLException;
-import javax.media.opengl.GLProfile;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-import com.jogamp.newt.NewtFactory;
-import com.jogamp.newt.Window;
-import com.jogamp.newt.event.WindowAdapter;
-import com.jogamp.newt.event.WindowEvent;
-import com.jogamp.newt.event.WindowListener;
-import com.jogamp.newt.event.WindowUpdateEvent;
-import com.jogamp.opengl.util.Animator;
-
-import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
-import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
-import com.jogamp.opengl.test.junit.util.QuitAdapter;
-import com.jogamp.opengl.test.junit.util.UITestCase;
-
-/**
- * Demonstrates a full featured custom GLAutoDrawable implementation
- * utilizing {@link GLAutoDrawableDelegate}.
- */
-public class TestGLAutoDrawableDelegateNEWT extends UITestCase {
-
- /** Note: Creates a full featured GLAutoDrawable w/ all window events connected. */
- private GLAutoDrawable createGLAutoDrawable(GLCapabilities caps, int x, int y, int width, int height, WindowListener wl) throws InterruptedException {
- final Window window = NewtFactory.createWindow(caps);
- Assert.assertNotNull(window);
- window.setPosition(x, y);
- window.setSize(width, height);
- window.setVisible(true);
- Assert.assertTrue(AWTRobotUtil.waitForVisible(window, true));
- Assert.assertTrue(AWTRobotUtil.waitForRealized(window, true));
-
- GLDrawableFactory factory = GLDrawableFactory.getFactory(caps.getGLProfile());
- GLDrawable drawable = factory.createGLDrawable(window);
- Assert.assertNotNull(drawable);
-
- drawable.setRealized(true);
- Assert.assertTrue(drawable.isRealized());
-
- GLContext context = drawable.createContext(null);
- Assert.assertNotNull(context);
-
- int res = context.makeCurrent();
- Assert.assertTrue(GLContext.CONTEXT_CURRENT_NEW==res || GLContext.CONTEXT_CURRENT==res);
- context.release();
-
- final GLAutoDrawableDelegate glad = new GLAutoDrawableDelegate(drawable, context, window, false) {
- @Override
- protected void destroyImplInLock() {
- super.destroyImplInLock(); // destroys drawable/context
- window.destroy(); // destroys the actual window
- }
- };
-
- // add basic window interaction
- window.addWindowListener(new WindowAdapter() {
- @Override
- public void windowRepaint(WindowUpdateEvent e) {
- glad.windowRepaintOp();
- }
- @Override
- public void windowResized(WindowEvent e) {
- glad.windowResizedOp();
- }
- @Override
- public void windowDestroyNotify(WindowEvent e) {
- glad.windowDestroyNotifyOp();
- }
- });
- window.addWindowListener(wl);
-
- return glad;
- }
-
- @Test
- public void test01() throws GLException, InterruptedException {
- final QuitAdapter quitAdapter = new QuitAdapter();
- GLAutoDrawable glad = createGLAutoDrawable(new GLCapabilities(GLProfile.getGL2ES2()), 0, 0, 640, 480, quitAdapter);
- glad.addGLEventListener(new GearsES2(1));
-
- final Animator animator = new Animator(glad);
- animator.setUpdateFPSFrames(60, null);
- animator.start();
-
- while(!quitAdapter.shouldQuit() && animator.isAnimating() && animator.getTotalFPSDuration()<duration) {
- Thread.sleep(100);
- }
-
- animator.stop();
-
- glad.destroy();
- }
-
- static long duration = 2000; // ms
-
- public static void main(String args[]) throws IOException {
- for(int i=0; i<args.length; i++) {
- if(args[i].equals("-time")) {
- i++;
- try {
- duration = Integer.parseInt(args[i]);
- } catch (Exception ex) { ex.printStackTrace(); }
- }
- }
- /**
- BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
- System.err.println("Press enter to continue");
- System.err.println(stdin.readLine()); */
- org.junit.runner.JUnitCore.main(TestGLAutoDrawableDelegateNEWT.class.getName());
- }
-}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableDelegateOnOffscrnCapsNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableDelegateOnOffscrnCapsNEWT.java
new file mode 100644
index 0000000..d9e9b2b
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableDelegateOnOffscrnCapsNEWT.java
@@ -0,0 +1,385 @@
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community OR
+ * CONTRIBUTORS 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.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.opengl.test.junit.jogl.acore;
+
+import java.io.IOException;
+
+import javax.media.nativewindow.CapabilitiesImmutable;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLProfile;
+
+import jogamp.opengl.GLGraphicsConfigurationUtil;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.jogamp.newt.NewtFactory;
+import com.jogamp.newt.Window;
+import com.jogamp.newt.event.WindowAdapter;
+import com.jogamp.newt.event.WindowEvent;
+import com.jogamp.newt.event.WindowUpdateEvent;
+import com.jogamp.opengl.GLAutoDrawableDelegate;
+import com.jogamp.opengl.JoglVersion;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+import com.jogamp.opengl.test.junit.jogl.demos.gl2.Gears;
+import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+
+/**
+ * Tests using a NEWT {@link Window} for on- and offscreen cases.
+ * <p>
+ * Each test creates a {@link GLDrawable} using the
+ * {@link GLDrawableFactory#createGLDrawable(javax.media.nativewindow.NativeSurface) factory model}.
+ * The {@link GLContext} is derived {@link GLDrawable#createContext(GLContext) from the drawable}.
+ * </p>
+ * <p>
+ * Finally a {@link GLAutoDrawableDelegate} is created with the just created {@link GLDrawable} and {@link GLContext}.
+ * It is being used to run the {@link GLEventListener}.
+ * </p>
+ */
+public class TestGLAutoDrawableDelegateOnOffscrnCapsNEWT extends UITestCase {
+ static final int widthStep = 800/4;
+ static final int heightStep = 600/4;
+ volatile int szStep = 2;
+
+ static GLCapabilities getCaps(String profile) {
+ if( !GLProfile.isAvailable(profile) ) {
+ System.err.println("Profile "+profile+" n/a");
+ return null;
+ }
+ return new GLCapabilities(GLProfile.get(profile));
+ }
+
+ void doTest(GLCapabilitiesImmutable reqGLCaps, GLEventListener demo) throws InterruptedException {
+ System.out.println("Requested GL Caps: "+reqGLCaps);
+ final GLDrawableFactory factory = GLDrawableFactory.getFactory(reqGLCaps.getGLProfile());
+ final GLCapabilitiesImmutable expGLCaps = GLGraphicsConfigurationUtil.fixGLCapabilities(reqGLCaps, factory, null);
+ System.out.println("Expected GL Caps: "+expGLCaps);
+ //
+ // Create native windowing resources .. X11/Win/OSX
+ //
+ final Window window = NewtFactory.createWindow(reqGLCaps);
+ Assert.assertNotNull(window);
+ window.setSize(widthStep*szStep, heightStep*szStep);
+ window.setVisible(true);
+ Assert.assertTrue(AWTRobotUtil.waitForVisible(window, true));
+ Assert.assertTrue(AWTRobotUtil.waitForRealized(window, true));
+ System.out.println("Window: "+window.getClass().getName());
+
+ // Check caps of NativeWindow config w/o GL
+ final CapabilitiesImmutable chosenCaps = window.getGraphicsConfiguration().getChosenCapabilities();
+ System.out.println("Window Caps Pre_GL: "+chosenCaps);
+ Assert.assertNotNull(chosenCaps);
+ Assert.assertTrue(chosenCaps.getGreenBits()>5);
+ Assert.assertTrue(chosenCaps.getBlueBits()>5);
+ Assert.assertTrue(chosenCaps.getRedBits()>5);
+
+ //
+ // Create native OpenGL resources .. XGL/WGL/CGL ..
+ // equivalent to GLAutoDrawable methods: setVisible(true)
+ //
+ final GLDrawable drawable = factory.createGLDrawable(window);
+ Assert.assertNotNull(drawable);
+ System.out.println("Drawable Pre-GL(0): "+drawable.getClass().getName()+", "+drawable.getNativeSurface().getClass().getName());
+
+ //
+ drawable.setRealized(true);
+ Assert.assertTrue(drawable.isRealized());
+
+ System.out.println("Window Caps PostGL : "+window.getGraphicsConfiguration().getChosenCapabilities());
+ System.out.println("Drawable Post-GL(1): "+drawable.getClass().getName()+", "+drawable.getNativeSurface().getClass().getName());
+
+ // Note: FBO Drawable realization happens at 1st context.makeCurrent(),
+ // and hence only then it's caps can _fully_ reflect expectations,
+ // i.e. depth, stencil and MSAA will be valid only after makeCurrent(),
+ // where on-/offscreen state after setRealized(true)
+ // See GLFBODrawable API doc in this regard!
+
+
+ final GLCapabilitiesImmutable chosenGLCaps01 = drawable.getChosenGLCapabilities();
+ System.out.println("Chosen GL Caps(1): "+chosenGLCaps01);
+ Assert.assertNotNull(chosenGLCaps01);
+ Assert.assertEquals(expGLCaps.isOnscreen(), chosenGLCaps01.isOnscreen());
+ Assert.assertEquals(expGLCaps.isFBO(), chosenGLCaps01.isFBO());
+ Assert.assertEquals(expGLCaps.isPBuffer(), chosenGLCaps01.isPBuffer());
+ Assert.assertEquals(expGLCaps.isBitmap(), chosenGLCaps01.isBitmap());
+
+ final GLContext context = drawable.createContext(null);
+ Assert.assertNotNull(context);
+ int res = context.makeCurrent();
+ Assert.assertTrue(GLContext.CONTEXT_CURRENT_NEW==res || GLContext.CONTEXT_CURRENT==res);
+ context.release();
+
+ // Check caps of GLDrawable after realization
+ final GLCapabilitiesImmutable chosenGLCaps02 = drawable.getChosenGLCapabilities();
+ System.out.println("Chosen GL Caps(2): "+chosenGLCaps02);
+ System.out.println("Chosen GL CTX (2): "+context.getGLVersion());
+ System.out.println("Drawable Post-GL(2): "+drawable.getClass().getName()+", "+drawable.getNativeSurface().getClass().getName());
+ Assert.assertNotNull(chosenGLCaps02);
+ Assert.assertTrue(chosenGLCaps02.getGreenBits()>5);
+ Assert.assertTrue(chosenGLCaps02.getBlueBits()>5);
+ Assert.assertTrue(chosenGLCaps02.getRedBits()>5);
+ Assert.assertTrue(chosenGLCaps02.getDepthBits()>4);
+ Assert.assertEquals(expGLCaps.isOnscreen(), chosenGLCaps02.isOnscreen());
+ Assert.assertEquals(expGLCaps.isFBO(), chosenGLCaps02.isFBO());
+ Assert.assertEquals(expGLCaps.isPBuffer(), chosenGLCaps02.isPBuffer());
+ Assert.assertEquals(expGLCaps.isBitmap(), chosenGLCaps02.isBitmap());
+ /** Single/Double buffer cannot be checked since result may vary ..
+ if(chosenGLCaps.isOnscreen() || chosenGLCaps.isFBO()) {
+ // dbl buffer may be disabled w/ offscreen pbuffer and bitmap
+ Assert.assertEquals(expGLCaps.getDoubleBuffered(), chosenGLCaps.getDoubleBuffered());
+ } */
+
+ final GLAutoDrawableDelegate glad = new GLAutoDrawableDelegate(drawable, context, window, false, null) {
+ @Override
+ protected void destroyImplInLock() {
+ super.destroyImplInLock(); // destroys drawable/context
+ window.destroy(); // destroys the actual window, incl. the device
+ }
+ };
+
+ window.addWindowListener(new WindowAdapter() {
+ @Override
+ public void windowRepaint(WindowUpdateEvent e) {
+ glad.windowRepaintOp();
+ }
+
+ @Override
+ public void windowResized(WindowEvent e) {
+ glad.windowResizedOp(window.getWidth(), window.getHeight());
+ }
+
+ @Override
+ public void windowDestroyNotify(WindowEvent e) {
+ glad.windowDestroyNotifyOp();
+ }
+ });
+
+ glad.addGLEventListener(demo);
+
+ final SnapshotGLEventListener snapshotGLEventListener = new SnapshotGLEventListener();
+ glad.addGLEventListener(snapshotGLEventListener);
+
+ glad.display(); // initial resize/display
+
+ // 1 - szStep = 2
+ Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(),
+ AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep));
+ snapshotGLEventListener.setMakeSnapshot();
+ glad.display();
+
+ // 2, 3 (resize + display)
+ szStep = 1;
+ window.setSize(widthStep*szStep, heightStep*szStep);
+ Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(),
+ AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep));
+ snapshotGLEventListener.setMakeSnapshot();
+ glad.display();
+
+ // 4, 5 (resize + display)
+ szStep = 4;
+ window.setSize(widthStep*szStep, heightStep*szStep);
+ Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(),
+ AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep));
+ snapshotGLEventListener.setMakeSnapshot();
+ glad.display();
+
+ Thread.sleep(50);
+
+ glad.destroy();
+ System.out.println("Fin Drawable: "+drawable);
+ System.out.println("Fin Window: "+window);
+ }
+
+ @Test
+ public void testAvailableInfo() {
+ GLDrawableFactory f = GLDrawableFactory.getDesktopFactory();
+ if(null != f) {
+ System.err.println(JoglVersion.getDefaultOpenGLInfo(f.getDefaultDevice(), null, true).toString());
+ }
+ f = GLDrawableFactory.getEGLFactory();
+ if(null != f) {
+ System.err.println(JoglVersion.getDefaultOpenGLInfo(f.getDefaultDevice(), null, true).toString());
+ }
+ }
+
+ @Test
+ public void testGL2OnScreenDblBuf() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+ if(null == reqGLCaps) return;
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testGL2OnScreenSglBuf() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setDoubleBuffered(false);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testGL2OffScreenAutoDblBuf() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setOnscreen(false);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testGL2OffScreenFBODblBuf() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setOnscreen(false);
+ reqGLCaps.setFBO(true);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testGL2OffScreenFBOSglBuf() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setOnscreen(false);
+ reqGLCaps.setFBO(true);
+ reqGLCaps.setDoubleBuffered(false);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testGL2OffScreenPbufferDblBuf() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setOnscreen(false);
+ reqGLCaps.setPBuffer(true);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testGL2OffScreenPbufferSglBuf() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setOnscreen(false);
+ reqGLCaps.setPBuffer(true);
+ reqGLCaps.setDoubleBuffered(false);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testGL2OffScreenBitmapSglBuf() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setOnscreen(false);
+ reqGLCaps.setBitmap(true);
+ reqGLCaps.setDoubleBuffered(false);
+ doTest(reqGLCaps, new Gears(1));
+ }
+
+ @Test
+ public void testES2OnScreenDblBuf() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
+ if(null == reqGLCaps) return;
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testES2OnScreenSglBuf() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setDoubleBuffered(false);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testES2OffScreenAutoDblBuf() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setOnscreen(false);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testES2OffScreenFBODblBuf() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setOnscreen(false);
+ reqGLCaps.setFBO(true);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testES2OffScreenFBOSglBuf() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setOnscreen(false);
+ reqGLCaps.setFBO(true);
+ reqGLCaps.setDoubleBuffered(false);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testES2OffScreenPbufferDblBuf() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setOnscreen(false);
+ reqGLCaps.setPBuffer(true);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testES2OffScreenPbufferSglBuf() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setOnscreen(false);
+ reqGLCaps.setPBuffer(true);
+ reqGLCaps.setDoubleBuffered(false);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ /** Not implemented !
+ @Test
+ public void testES2OffScreenBitmapDblBuf() throws InterruptedException {
+ if(!checkProfile(GLProfile.GLES2)) {
+ return;
+ }
+ final GLCapabilities reqGLCaps = new GLCapabilities(GLProfile.get(GLProfile.GLES2));
+ reqGLCaps.setOnscreen(false);
+ reqGLCaps.setBitmap(true);
+ doTest(reqGLCaps, new GearsES2(1));
+ } */
+
+ public static void main(String args[]) throws IOException {
+ org.junit.runner.JUnitCore.main(TestGLAutoDrawableDelegateOnOffscrnCapsNEWT.class.getName());
+ }
+
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableFactoryOffscrnCapsNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableFactoryOffscrnCapsNEWT.java
new file mode 100644
index 0000000..51f9cc4
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableFactoryOffscrnCapsNEWT.java
@@ -0,0 +1,306 @@
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community OR
+ * CONTRIBUTORS 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.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.opengl.test.junit.jogl.acore;
+
+import java.io.IOException;
+
+import javax.media.nativewindow.CapabilitiesImmutable;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLOffscreenAutoDrawable;
+import javax.media.opengl.GLProfile;
+
+import jogamp.opengl.GLGraphicsConfigurationUtil;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.jogamp.opengl.JoglVersion;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+import com.jogamp.opengl.test.junit.jogl.demos.gl2.Gears;
+import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+
+/**
+ * Toolkit agnostic {@link GLOffscreenAutoDrawable} tests using the
+ * {@link GLDrawableFactory#createOffscreenAutoDrawable(javax.media.nativewindow.AbstractGraphicsDevice, GLCapabilitiesImmutable, javax.media.opengl.GLCapabilitiesChooser, int, int, GLContext) factory model}.
+ * <p>
+ * The created {@link GLOffscreenAutoDrawable} is being used to run the {@link GLEventListener}.
+ * </p>
+ */
+public class TestGLAutoDrawableFactoryOffscrnCapsNEWT extends UITestCase {
+ static final int widthStep = 800/4;
+ static final int heightStep = 600/4;
+ volatile int szStep = 2;
+
+ static GLCapabilities getCaps(String profile) {
+ if( !GLProfile.isAvailable(profile) ) {
+ System.err.println("Profile "+profile+" n/a");
+ return null;
+ }
+ return new GLCapabilities(GLProfile.get(profile));
+ }
+
+ void doTest(GLCapabilitiesImmutable reqGLCaps, GLEventListener demo) throws InterruptedException {
+ System.out.println("Requested GL Caps: "+reqGLCaps);
+ final GLDrawableFactory factory = GLDrawableFactory.getFactory(reqGLCaps.getGLProfile());
+ final GLCapabilitiesImmutable expGLCaps = GLGraphicsConfigurationUtil.fixGLCapabilities(reqGLCaps, factory, null);
+ System.out.println("Expected GL Caps: "+expGLCaps);
+
+ //
+ // Create native OpenGL resources .. XGL/WGL/CGL ..
+ // equivalent to GLAutoDrawable methods: setVisible(true)
+ //
+ final GLOffscreenAutoDrawable glad = factory.createOffscreenAutoDrawable(null, reqGLCaps, null, widthStep*szStep, heightStep*szStep, null);
+
+ Assert.assertNotNull(glad);
+ System.out.println("Drawable Pre-GL(0): "+glad.getClass().getName()+", "+glad.getNativeSurface().getClass().getName());
+ Assert.assertTrue(glad.isRealized());
+
+ // Check caps of NativeWindow config w/o GL
+ final CapabilitiesImmutable chosenCaps = glad.getChosenGLCapabilities();
+ System.out.println("Drawable Caps Pre_GL : "+chosenCaps);
+ Assert.assertNotNull(chosenCaps);
+ Assert.assertTrue(chosenCaps.getGreenBits()>5);
+ Assert.assertTrue(chosenCaps.getBlueBits()>5);
+ Assert.assertTrue(chosenCaps.getRedBits()>5);
+
+ glad.display(); // force native context creation
+
+ // Check caps of GLDrawable after realization
+ final GLCapabilitiesImmutable chosenGLCaps = glad.getChosenGLCapabilities();
+ System.out.println("Chosen GL CTX (1): "+glad.getContext().getGLVersion());
+ System.out.println("Chosen GL Caps(1): "+chosenGLCaps);
+ System.out.println("Chosen GL Caps(2): "+glad.getNativeSurface().getGraphicsConfiguration().getChosenCapabilities());
+
+ Assert.assertNotNull(chosenGLCaps);
+ Assert.assertTrue(chosenGLCaps.getGreenBits()>5);
+ Assert.assertTrue(chosenGLCaps.getBlueBits()>5);
+ Assert.assertTrue(chosenGLCaps.getRedBits()>5);
+ Assert.assertTrue(chosenGLCaps.getDepthBits()>4);
+ Assert.assertEquals(expGLCaps.isOnscreen(), chosenGLCaps.isOnscreen());
+ Assert.assertEquals(expGLCaps.isFBO(), chosenGLCaps.isFBO());
+ Assert.assertEquals(expGLCaps.isPBuffer(), chosenGLCaps.isPBuffer());
+ Assert.assertEquals(expGLCaps.isBitmap(), chosenGLCaps.isBitmap());
+ /** Single/Double buffer cannot be checked since result may vary ..
+ if(chosenGLCaps.isOnscreen() || chosenGLCaps.isFBO()) {
+ // dbl buffer may be disabled w/ offscreen pbuffer and bitmap
+ Assert.assertEquals(expGLCaps.getDoubleBuffered(), chosenGLCaps.getDoubleBuffered());
+ } */
+
+ glad.addGLEventListener(demo);
+
+ final SnapshotGLEventListener snapshotGLEventListener = new SnapshotGLEventListener();
+ glad.addGLEventListener(snapshotGLEventListener);
+
+ glad.display(); // initial resize/display
+
+ // 1 - szStep = 2
+ Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(),
+ AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep));
+ snapshotGLEventListener.setMakeSnapshot();
+ glad.display();
+
+ // 2, 3 (resize + display)
+ szStep = 1;
+ glad.setSize(widthStep*szStep, heightStep*szStep);
+ Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(),
+ AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep));
+ snapshotGLEventListener.setMakeSnapshot();
+ glad.display();
+
+ // 4, 5 (resize + display)
+ szStep = 4;
+ glad.setSize(widthStep*szStep, heightStep*szStep);
+ Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(),
+ AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep));
+ snapshotGLEventListener.setMakeSnapshot();
+ glad.display();
+
+ Thread.sleep(50);
+
+ glad.destroy();
+ System.out.println("Fin Drawable: "+glad);
+ }
+
+ @Test
+ public void testAvailableInfo() {
+ GLDrawableFactory f = GLDrawableFactory.getDesktopFactory();
+ if(null != f) {
+ System.err.println(JoglVersion.getDefaultOpenGLInfo(f.getDefaultDevice(), null, true).toString());
+ }
+ f = GLDrawableFactory.getEGLFactory();
+ if(null != f) {
+ System.err.println(JoglVersion.getDefaultOpenGLInfo(f.getDefaultDevice(), null, true).toString());
+ }
+ }
+
+ @Test
+ public void testGL2OffScreenAutoDblBuf() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setOnscreen(false);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testGL2OffScreenFBODblBuf() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setOnscreen(false);
+ reqGLCaps.setFBO(true);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testGL2OffScreenFBOSglBuf() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setOnscreen(false);
+ reqGLCaps.setFBO(true);
+ reqGLCaps.setDoubleBuffered(false);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testGL2OffScreenFBOStencil() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setOnscreen(false);
+ reqGLCaps.setFBO(true);
+ reqGLCaps.setStencilBits(1);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testGL2OffScreenFBOStencilMSAA() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setOnscreen(false);
+ reqGLCaps.setFBO(true);
+ reqGLCaps.setStencilBits(1);
+ reqGLCaps.setSampleBuffers(true);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testGL2OffScreenPbufferDblBuf() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setOnscreen(false);
+ reqGLCaps.setPBuffer(true);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testGL2OffScreenPbufferSglBuf() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setOnscreen(false);
+ reqGLCaps.setPBuffer(true);
+ reqGLCaps.setDoubleBuffered(false);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testGL2OffScreenBitmapSglBuf() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setOnscreen(false);
+ reqGLCaps.setBitmap(true);
+ reqGLCaps.setDoubleBuffered(false);
+ doTest(reqGLCaps, new Gears(1));
+ }
+
+ @Test
+ public void testES2OffScreenAutoDblBuf() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setOnscreen(false);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testES2OffScreenFBODblBuf() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setOnscreen(false);
+ reqGLCaps.setFBO(true);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testES2OffScreenFBOSglBuf() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setOnscreen(false);
+ reqGLCaps.setFBO(true);
+ reqGLCaps.setDoubleBuffered(false);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testES2OffScreenPbufferDblBuf() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setOnscreen(false);
+ reqGLCaps.setPBuffer(true);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testES2OffScreenPbufferSglBuf() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setOnscreen(false);
+ reqGLCaps.setPBuffer(true);
+ reqGLCaps.setDoubleBuffered(false);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ /** Not implemented !
+ @Test
+ public void testES2OffScreenBitmapDblBuf() throws InterruptedException {
+ if(!checkProfile(GLProfile.GLES2)) {
+ return;
+ }
+ final GLCapabilities reqGLCaps = new GLCapabilities(GLProfile.get(GLProfile.GLES2));
+ reqGLCaps.setOnscreen(false);
+ reqGLCaps.setBitmap(true);
+ doTest(reqGLCaps, new GearsES2(1));
+ } */
+
+ public static void main(String args[]) throws IOException {
+ org.junit.runner.JUnitCore.main(TestGLAutoDrawableFactoryOffscrnCapsNEWT.class.getName());
+ }
+
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableGLCanvasOnOffscrnCapsAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableGLCanvasOnOffscrnCapsAWT.java
new file mode 100644
index 0000000..a2ffa90
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableGLCanvasOnOffscrnCapsAWT.java
@@ -0,0 +1,324 @@
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community OR
+ * CONTRIBUTORS 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.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.opengl.test.junit.jogl.acore;
+
+import java.awt.Dimension;
+import java.awt.Frame;
+import java.io.IOException;
+
+import javax.media.nativewindow.CapabilitiesImmutable;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLProfile;
+import javax.media.opengl.awt.GLCanvas;
+
+import jogamp.nativewindow.jawt.JAWTUtil;
+import jogamp.opengl.GLGraphicsConfigurationUtil;
+
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.Test;
+
+import com.jogamp.opengl.JoglVersion;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+
+/**
+ * Tests using an AWT {@link GLCanvas} {@link GLAutoDrawable auto drawable} for on- and offscreen cases.
+ * <p>
+ * The NEWT {@link GLAutoDrawable} is being used to run the {@link GLEventListener}.
+ * </p>
+ */
+public class TestGLAutoDrawableGLCanvasOnOffscrnCapsAWT extends UITestCase {
+ static final int widthStep = 800/4;
+ static final int heightStep = 600/4;
+ volatile int szStep = 2;
+
+ static GLCapabilities getCaps(String profile) {
+ if( !GLProfile.isAvailable(profile) ) {
+ System.err.println("Profile "+profile+" n/a");
+ return null;
+ }
+ return new GLCapabilities(GLProfile.get(profile));
+ }
+
+ static void setGLCanvasSize(final Frame frame, final GLCanvas glc, final int width, final int height) {
+ try {
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ final Dimension new_sz = new Dimension(width, height);
+ glc.setMinimumSize(new_sz);
+ glc.setPreferredSize(new_sz);
+ glc.setSize(new_sz);
+ frame.pack();
+ frame.validate();
+ } } );
+ } catch( Throwable throwable ) {
+ throwable.printStackTrace();
+ Assume.assumeNoException( throwable );
+ }
+ }
+
+ static interface MyGLEventListener extends GLEventListener {
+ void setMakeSnapshot();
+ }
+
+ void doTest(GLCapabilitiesImmutable reqGLCaps, GLEventListener demo) throws InterruptedException {
+ if(reqGLCaps.isOnscreen() && JAWTUtil.isOffscreenLayerRequired()) {
+ System.err.println("onscreen layer n/a");
+ return;
+ }
+ if(!reqGLCaps.isOnscreen() && !JAWTUtil.isOffscreenLayerSupported()) {
+ System.err.println("offscreen layer n/a");
+ return;
+ }
+ System.out.println("Requested GL Caps: "+reqGLCaps);
+ final GLDrawableFactory factory = GLDrawableFactory.getFactory(reqGLCaps.getGLProfile());
+ final GLCapabilitiesImmutable expGLCaps = GLGraphicsConfigurationUtil.fixGLCapabilities(reqGLCaps, factory, null);
+ System.out.println("Expected GL Caps: "+expGLCaps);
+ //
+ // Create native windowing resources .. X11/Win/OSX
+ //
+ final GLCanvas glad = new GLCanvas(reqGLCaps); // will implicit trigger offscreen layer - if !onscreen && supported
+ Assert.assertNotNull(glad);
+ Dimension glc_sz = new Dimension(widthStep*szStep, heightStep*szStep);
+ glad.setMinimumSize(glc_sz);
+ glad.setPreferredSize(glc_sz);
+ glad.setSize(glc_sz);
+ final Frame frame = new Frame(getSimpleTestName("."));
+ Assert.assertNotNull(frame);
+ frame.add(glad);
+
+ try {
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ frame.pack();
+ frame.setVisible(true);
+ }});
+ } catch( Throwable throwable ) {
+ throwable.printStackTrace();
+ Assume.assumeNoException( throwable );
+ }
+
+ Assert.assertTrue(AWTRobotUtil.waitForVisible(glad, true));
+ Assert.assertTrue(AWTRobotUtil.waitForRealized(glad, true));
+ System.out.println("Window: "+glad.getClass().getName());
+
+ // Check caps of NativeWindow config w/o GL
+ final CapabilitiesImmutable chosenCaps = glad.getChosenGLCapabilities();
+ System.out.println("Window Caps Pre_GL: "+chosenCaps);
+ Assert.assertNotNull(chosenCaps);
+ Assert.assertTrue(chosenCaps.getGreenBits()>5);
+ Assert.assertTrue(chosenCaps.getBlueBits()>5);
+ Assert.assertTrue(chosenCaps.getRedBits()>5);
+
+ glad.display(); // force native context creation
+
+ //
+ // Create native OpenGL resources .. XGL/WGL/CGL ..
+ // equivalent to GLAutoDrawable methods: setVisible(true)
+ //
+ {
+ final GLDrawable actualDrawable = glad.getDelegatedDrawable();
+ Assert.assertNotNull(actualDrawable);
+ System.out.println("Drawable Pre-GL(0): "+actualDrawable.getClass().getName()+", "+actualDrawable.getNativeSurface().getClass().getName());
+ }
+
+ System.out.println("Window Caps PostGL : "+glad.getChosenGLCapabilities());
+ System.out.println("Drawable Post-GL(1): "+glad.getClass().getName()+", "+glad.getNativeSurface().getClass().getName());
+
+ // Check caps of GLDrawable after realization
+ final GLCapabilitiesImmutable chosenGLCaps = glad.getChosenGLCapabilities();
+ System.out.println("Chosen GL Caps(1): "+chosenGLCaps);
+ Assert.assertNotNull(chosenGLCaps);
+ Assert.assertTrue(chosenGLCaps.getGreenBits()>5);
+ Assert.assertTrue(chosenGLCaps.getBlueBits()>5);
+ Assert.assertTrue(chosenGLCaps.getRedBits()>5);
+ Assert.assertTrue(chosenGLCaps.getDepthBits()>4);
+ Assert.assertEquals(expGLCaps.isOnscreen(), chosenGLCaps.isOnscreen());
+ Assert.assertEquals(expGLCaps.isFBO(), chosenGLCaps.isFBO());
+ Assert.assertEquals(expGLCaps.isPBuffer(), chosenGLCaps.isPBuffer());
+ Assert.assertEquals(expGLCaps.isBitmap(), chosenGLCaps.isBitmap());
+ /** Single/Double buffer cannot be checked since result may vary ..
+ if(chosenGLCaps.isOnscreen() || chosenGLCaps.isFBO()) {
+ // dbl buffer may be disabled w/ offscreen pbuffer and bitmap
+ Assert.assertEquals(expGLCaps.getDoubleBuffered(), chosenGLCaps.getDoubleBuffered());
+ } */
+
+ {
+ GLContext context = glad.getContext();
+ System.out.println("Chosen GL CTX (2): "+context.getGLVersion());
+ Assert.assertNotNull(context);
+ Assert.assertTrue(context.isCreated());
+ }
+
+ System.out.println("Chosen GL Caps(2): "+glad.getChosenGLCapabilities());
+ System.out.println("Drawable Post-GL(2): "+glad.getClass().getName()+", "+glad.getNativeSurface().getClass().getName());
+
+ glad.addGLEventListener(demo);
+
+ final SnapshotGLEventListener snapshotGLEventListener = new SnapshotGLEventListener();
+ glad.addGLEventListener(snapshotGLEventListener);
+
+ glad.display(); // initial resize/display
+
+ // 1 - szStep = 2
+ Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(),
+ AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep));
+ snapshotGLEventListener.setMakeSnapshot();
+ glad.display();
+
+ // 2, 3 (resize + display)
+ szStep = 1;
+ setGLCanvasSize(frame, glad, widthStep*szStep, heightStep*szStep);
+ Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(),
+ AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep));
+ glad.display();
+ snapshotGLEventListener.setMakeSnapshot();
+ glad.display();
+
+ // 4, 5 (resize + display)
+ szStep = 4;
+ setGLCanvasSize(frame, glad, widthStep*szStep, heightStep*szStep);
+ Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(),
+ AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep));
+ glad.display();
+ snapshotGLEventListener.setMakeSnapshot();
+ glad.display();
+
+ Thread.sleep(50);
+
+ try {
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ frame.setVisible(false);
+ frame.remove(glad);
+ frame.dispose();
+ }});
+ } catch( Throwable throwable ) {
+ throwable.printStackTrace();
+ Assume.assumeNoException( throwable );
+ }
+ System.out.println("Fin: "+glad);
+ }
+
+ @Test
+ public void testAvailableInfo() {
+ GLDrawableFactory f = GLDrawableFactory.getDesktopFactory();
+ if(null != f) {
+ System.err.println(JoglVersion.getDefaultOpenGLInfo(f.getDefaultDevice(), null, true).toString());
+ }
+ f = GLDrawableFactory.getEGLFactory();
+ if(null != f) {
+ System.err.println(JoglVersion.getDefaultOpenGLInfo(f.getDefaultDevice(), null, true).toString());
+ }
+ }
+
+ @Test
+ public void testGL2OnScreen() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+ if(null == reqGLCaps) return;
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testGL2OffScreenAuto() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setOnscreen(false);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testGL2OffScreenFBOMSAA() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setOnscreen(false);
+ reqGLCaps.setFBO(true);
+ reqGLCaps.setSampleBuffers(true);
+ reqGLCaps.setNumSamples(4);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testGL2OffScreenPbuffer() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setOnscreen(false);
+ reqGLCaps.setPBuffer(true);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testES2OnScreen() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
+ if(null == reqGLCaps) return;
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testES2OffScreenAuto() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setOnscreen(false);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testES2OffScreenFBOMSAA() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setOnscreen(false);
+ reqGLCaps.setFBO(true);
+ reqGLCaps.setSampleBuffers(true);
+ reqGLCaps.setNumSamples(4);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testES2OffScreenPbuffer() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setOnscreen(false);
+ reqGLCaps.setPBuffer(true);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+
+ public static void main(String args[]) throws IOException {
+ org.junit.runner.JUnitCore.main(TestGLAutoDrawableGLCanvasOnOffscrnCapsAWT.class.getName());
+ }
+
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableGLWindowOnOffscrnCapsNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableGLWindowOnOffscrnCapsNEWT.java
new file mode 100644
index 0000000..da54567
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableGLWindowOnOffscrnCapsNEWT.java
@@ -0,0 +1,339 @@
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community OR
+ * CONTRIBUTORS 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.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.opengl.test.junit.jogl.acore;
+
+import java.io.IOException;
+
+import javax.media.nativewindow.CapabilitiesImmutable;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLProfile;
+
+import jogamp.opengl.GLGraphicsConfigurationUtil;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.JoglVersion;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+import com.jogamp.opengl.test.junit.jogl.demos.gl2.Gears;
+import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+
+/**
+ * Tests using a NEWT {@link GLWindow} {@link GLAutoDrawable auto drawable} for on- and offscreen cases.
+ * <p>
+ * The NEWT {@link GLAutoDrawable} is being used to run the {@link GLEventListener}.
+ * </p>
+ */
+public class TestGLAutoDrawableGLWindowOnOffscrnCapsNEWT extends UITestCase {
+ static final int widthStep = 800/4;
+ static final int heightStep = 600/4;
+ volatile int szStep = 2;
+
+ static interface MyGLEventListener extends GLEventListener {
+ void setMakeSnapshot();
+ }
+
+ static GLCapabilities getCaps(String profile) {
+ if( !GLProfile.isAvailable(profile) ) {
+ System.err.println("Profile "+profile+" n/a");
+ return null;
+ }
+ return new GLCapabilities(GLProfile.get(profile));
+ }
+
+ void doTest(GLCapabilitiesImmutable reqGLCaps, GLEventListener demo) throws InterruptedException {
+ System.out.println("Requested GL Caps: "+reqGLCaps);
+ final GLDrawableFactory factory = GLDrawableFactory.getFactory(reqGLCaps.getGLProfile());
+ final GLCapabilitiesImmutable expGLCaps = GLGraphicsConfigurationUtil.fixGLCapabilities(reqGLCaps, factory, null);
+ System.out.println("Expected GL Caps: "+expGLCaps);
+ //
+ // Create native windowing resources .. X11/Win/OSX
+ //
+ final GLWindow glad = GLWindow.create(reqGLCaps);
+ Assert.assertNotNull(glad);
+ glad.setSize(widthStep*szStep, heightStep*szStep);
+ glad.setVisible(true);
+ Assert.assertTrue(AWTRobotUtil.waitForVisible(glad, true));
+ Assert.assertTrue(AWTRobotUtil.waitForRealized(glad, true));
+ System.out.println("Window: "+glad.getClass().getName());
+
+ // Check caps of NativeWindow config w/o GL
+ final CapabilitiesImmutable chosenCaps = glad.getGraphicsConfiguration().getChosenCapabilities();
+ System.out.println("Window Caps Pre_GL: "+chosenCaps);
+ Assert.assertNotNull(chosenCaps);
+ Assert.assertTrue(chosenCaps.getGreenBits()>5);
+ Assert.assertTrue(chosenCaps.getBlueBits()>5);
+ Assert.assertTrue(chosenCaps.getRedBits()>5);
+
+ //
+ // Create native OpenGL resources .. XGL/WGL/CGL ..
+ // equivalent to GLAutoDrawable methods: setVisible(true)
+ //
+ {
+ final GLDrawable actualDrawable = glad.getDelegatedDrawable();
+ Assert.assertNotNull(actualDrawable);
+ System.out.println("Drawable Pre-GL(0): "+actualDrawable.getClass().getName()+", "+actualDrawable.getNativeSurface().getClass().getName());
+ }
+
+ System.out.println("Window Caps PostGL : "+glad.getGraphicsConfiguration().getChosenCapabilities());
+ System.out.println("Drawable Post-GL(1): "+glad.getClass().getName()+", "+glad.getNativeSurface().getClass().getName());
+
+ // Check caps of GLDrawable after realization
+ final GLCapabilitiesImmutable chosenGLCaps = glad.getChosenGLCapabilities();
+ System.out.println("Chosen GL Caps(1): "+chosenGLCaps);
+ Assert.assertNotNull(chosenGLCaps);
+ Assert.assertTrue(chosenGLCaps.getGreenBits()>5);
+ Assert.assertTrue(chosenGLCaps.getBlueBits()>5);
+ Assert.assertTrue(chosenGLCaps.getRedBits()>5);
+ Assert.assertTrue(chosenGLCaps.getDepthBits()>4);
+ Assert.assertEquals(expGLCaps.isOnscreen(), chosenGLCaps.isOnscreen());
+ Assert.assertEquals(expGLCaps.isFBO(), chosenGLCaps.isFBO());
+ Assert.assertEquals(expGLCaps.isPBuffer(), chosenGLCaps.isPBuffer());
+ Assert.assertEquals(expGLCaps.isBitmap(), chosenGLCaps.isBitmap());
+ /** Single/Double buffer cannot be checked since result may vary ..
+ if(chosenGLCaps.isOnscreen() || chosenGLCaps.isFBO()) {
+ // dbl buffer may be disabled w/ offscreen pbuffer and bitmap
+ Assert.assertEquals(expGLCaps.getDoubleBuffered(), chosenGLCaps.getDoubleBuffered());
+ } */
+
+ glad.display();
+ {
+ GLContext context = glad.getContext();
+ System.out.println("Chosen GL CTX (2): "+context.getGLVersion());
+ Assert.assertNotNull(context);
+ Assert.assertTrue(context.isCreated());
+ }
+
+ System.out.println("Chosen GL Caps(2): "+glad.getChosenGLCapabilities());
+ System.out.println("Drawable Post-GL(2): "+glad.getClass().getName()+", "+glad.getNativeSurface().getClass().getName());
+
+ glad.addGLEventListener(demo);
+
+ final SnapshotGLEventListener snapshotGLEventListener = new SnapshotGLEventListener();
+ glad.addGLEventListener(snapshotGLEventListener);
+
+ glad.display(); // initial resize/display
+
+ // 1 - szStep = 2
+ Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(),
+ AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep));
+ snapshotGLEventListener.setMakeSnapshot();
+ glad.display();
+
+ // 2, 3 (resize + display)
+ szStep = 1;
+ glad.setSize(widthStep*szStep, heightStep*szStep);
+ Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(),
+ AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep));
+ snapshotGLEventListener.setMakeSnapshot();
+ glad.display();
+
+ // 4, 5 (resize + display)
+ szStep = 4;
+ glad.setSize(widthStep*szStep, heightStep*szStep);
+ Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(),
+ AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep));
+ snapshotGLEventListener.setMakeSnapshot();
+ glad.display();
+
+ Thread.sleep(50);
+
+ glad.destroy();
+ System.out.println("Fin: "+glad);
+ }
+
+ @Test
+ public void testAvailableInfo() {
+ GLDrawableFactory f = GLDrawableFactory.getDesktopFactory();
+ if(null != f) {
+ System.err.println(JoglVersion.getDefaultOpenGLInfo(f.getDefaultDevice(), null, true).toString());
+ }
+ f = GLDrawableFactory.getEGLFactory();
+ if(null != f) {
+ System.err.println(JoglVersion.getDefaultOpenGLInfo(f.getDefaultDevice(), null, true).toString());
+ }
+ }
+
+ @Test
+ public void testGL2OnScreenDblBuf() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+ if(null == reqGLCaps) return;
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testGL2OnScreenSglBuf() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setDoubleBuffered(false);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testGL2OffScreenAutoDblBuf() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setOnscreen(false);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testGL2OffScreenFBODblBuf() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setOnscreen(false);
+ reqGLCaps.setFBO(true);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testGL2OffScreenFBOSglBuf() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setOnscreen(false);
+ reqGLCaps.setFBO(true);
+ reqGLCaps.setDoubleBuffered(false);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testGL2OffScreenPbufferDblBuf() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setOnscreen(false);
+ reqGLCaps.setPBuffer(true);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testGL2OffScreenPbufferSglBuf() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setOnscreen(false);
+ reqGLCaps.setPBuffer(true);
+ reqGLCaps.setDoubleBuffered(false);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testGL2OffScreenBitmapSglBuf() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setOnscreen(false);
+ reqGLCaps.setBitmap(true);
+ reqGLCaps.setDoubleBuffered(false);
+ doTest(reqGLCaps, new Gears(1));
+ }
+
+ @Test
+ public void testES2OnScreenDblBuf() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
+ if(null == reqGLCaps) return;
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testES2OnScreenSglBuf() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setDoubleBuffered(false);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testES2OffScreenAutoDblBuf() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setOnscreen(false);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testES2OffScreenFBODblBuf() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setOnscreen(false);
+ reqGLCaps.setFBO(true);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testES2OffScreenFBOSglBuf() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setOnscreen(false);
+ reqGLCaps.setFBO(true);
+ reqGLCaps.setDoubleBuffered(false);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testES2OffScreenPbufferDblBuf() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setOnscreen(false);
+ reqGLCaps.setPBuffer(true);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testES2OffScreenPbufferSglBuf() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setOnscreen(false);
+ reqGLCaps.setPBuffer(true);
+ reqGLCaps.setDoubleBuffered(false);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ /** Not implemented !
+ @Test
+ public void testES2OffScreenBitmapDblBuf() throws InterruptedException {
+ if(!checkProfile(GLProfile.GLES2)) {
+ return;
+ }
+ final GLCapabilities reqGLCaps = new GLCapabilities(GLProfile.get(GLProfile.GLES2));
+ reqGLCaps.setOnscreen(false);
+ reqGLCaps.setBitmap(true);
+ doTest(reqGLCaps, new GearsES2(1));
+ } */
+
+ public static void main(String args[]) throws IOException {
+ org.junit.runner.JUnitCore.main(TestGLAutoDrawableGLWindowOnOffscrnCapsNEWT.class.getName());
+ }
+
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableNewtCanvasAWTOnOffscrnCapsAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableNewtCanvasAWTOnOffscrnCapsAWT.java
new file mode 100644
index 0000000..37483f7
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableNewtCanvasAWTOnOffscrnCapsAWT.java
@@ -0,0 +1,299 @@
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community OR
+ * CONTRIBUTORS 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.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.opengl.test.junit.jogl.acore;
+
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Frame;
+import java.io.IOException;
+
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.CapabilitiesImmutable;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLProfile;
+
+import jogamp.nativewindow.jawt.JAWTUtil;
+import jogamp.opengl.GLGraphicsConfigurationUtil;
+
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.Test;
+
+import com.jogamp.newt.awt.NewtCanvasAWT;
+import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.JoglVersion;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+
+/**
+ * Tests using a NEWT {@link GLWindow} {@link GLAutoDrawable auto drawable} for on- and offscreen cases.
+ * <p>
+ * The NEWT {@link GLAutoDrawable} is being used to run the {@link GLEventListener}.
+ * </p>
+ */
+public class TestGLAutoDrawableNewtCanvasAWTOnOffscrnCapsAWT extends UITestCase {
+ static final int widthStep = 800/4;
+ static final int heightStep = 600/4;
+ volatile int szStep = 2;
+
+ static GLCapabilities getCaps(String profile) {
+ if( !GLProfile.isAvailable(profile) ) {
+ System.err.println("Profile "+profile+" n/a");
+ return null;
+ }
+ return new GLCapabilities(GLProfile.get(profile));
+ }
+
+ static void setComponentSize(final Frame frame, final Component comp, final int width, final int height) {
+ try {
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ final Dimension new_sz = new Dimension(width, height);
+ comp.setMinimumSize(new_sz);
+ comp.setPreferredSize(new_sz);
+ comp.setSize(new_sz);
+ frame.pack();
+ frame.validate();
+ } } );
+ } catch( Throwable throwable ) {
+ throwable.printStackTrace();
+ Assume.assumeNoException( throwable );
+ }
+ }
+
+ static interface MyGLEventListener extends GLEventListener {
+ void setMakeSnapshot();
+ }
+
+ void doTest(boolean offscreenLayer, GLCapabilitiesImmutable reqGLCaps, GLEventListener demo) throws InterruptedException {
+ if(!offscreenLayer && JAWTUtil.isOffscreenLayerRequired()) {
+ System.err.println("onscreen layer n/a");
+ return;
+ }
+ if(offscreenLayer && !JAWTUtil.isOffscreenLayerSupported()) {
+ System.err.println("offscreen layer n/a");
+ return;
+ }
+ System.out.println("Requested GL Caps: "+reqGLCaps);
+ final GLDrawableFactory factory = GLDrawableFactory.getFactory(reqGLCaps.getGLProfile());
+ final AbstractGraphicsDevice device = factory.getDefaultDevice();
+ final GLCapabilitiesImmutable expGLCaps = offscreenLayer ?
+ GLGraphicsConfigurationUtil.fixOffscreenGLCapabilities(reqGLCaps, factory, device) :
+ GLGraphicsConfigurationUtil.fixGLCapabilities(reqGLCaps, factory, device);
+ System.out.println("Expected GL Caps: "+expGLCaps);
+
+ final GLWindow glad = GLWindow.create(reqGLCaps);
+ Assert.assertNotNull(glad);
+
+
+ final NewtCanvasAWT nca = new NewtCanvasAWT(glad);
+ Assert.assertNotNull(nca);
+ Dimension size0 = new Dimension(widthStep*szStep, heightStep*szStep);
+ nca.setShallUseOffscreenLayer(offscreenLayer); // trigger offscreen layer - if supported
+ nca.setPreferredSize(size0);
+ nca.setMinimumSize(size0);
+ nca.setSize(size0);
+
+ final Frame frame = new Frame(getSimpleTestName("."));
+ Assert.assertNotNull(frame);
+ frame.add(nca);
+
+ try {
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ frame.pack();
+ frame.setVisible(true);
+ }});
+ } catch( Throwable throwable ) {
+ throwable.printStackTrace();
+ Assume.assumeNoException( throwable );
+ }
+
+ Assert.assertTrue(AWTRobotUtil.waitForVisible(glad, true));
+ Assert.assertTrue(AWTRobotUtil.waitForRealized(glad, true));
+ System.out.println("Window: "+glad.getClass().getName());
+
+ // Check caps of NativeWindow config w/o GL
+ final CapabilitiesImmutable chosenCaps = glad.getChosenGLCapabilities();
+ System.out.println("Window Caps Pre_GL: "+chosenCaps);
+ Assert.assertNotNull(chosenCaps);
+ Assert.assertTrue(chosenCaps.getGreenBits()>5);
+ Assert.assertTrue(chosenCaps.getBlueBits()>5);
+ Assert.assertTrue(chosenCaps.getRedBits()>5);
+
+ glad.display(); // force native context creation
+
+ //
+ // Create native OpenGL resources .. XGL/WGL/CGL ..
+ // equivalent to GLAutoDrawable methods: setVisible(true)
+ //
+ {
+ final GLDrawable actualDrawable = glad.getDelegatedDrawable();
+ Assert.assertNotNull(actualDrawable);
+ System.out.println("Drawable Pre-GL(0): "+actualDrawable.getClass().getName()+", "+actualDrawable.getNativeSurface().getClass().getName());
+ }
+
+ System.out.println("Window Caps PostGL : "+glad.getChosenGLCapabilities());
+ System.out.println("Drawable Post-GL(1): "+glad.getClass().getName()+", "+glad.getNativeSurface().getClass().getName());
+
+ // Check caps of GLDrawable after realization
+ final GLCapabilitiesImmutable chosenGLCaps = glad.getChosenGLCapabilities();
+ System.out.println("Chosen GL Caps(1): "+chosenGLCaps);
+ Assert.assertNotNull(chosenGLCaps);
+ Assert.assertTrue(chosenGLCaps.getGreenBits()>5);
+ Assert.assertTrue(chosenGLCaps.getBlueBits()>5);
+ Assert.assertTrue(chosenGLCaps.getRedBits()>5);
+ Assert.assertTrue(chosenGLCaps.getDepthBits()>4);
+ Assert.assertEquals(expGLCaps.isOnscreen(), chosenGLCaps.isOnscreen());
+ Assert.assertEquals(expGLCaps.isFBO(), chosenGLCaps.isFBO());
+ Assert.assertEquals(expGLCaps.isPBuffer(), chosenGLCaps.isPBuffer());
+ Assert.assertEquals(expGLCaps.isBitmap(), chosenGLCaps.isBitmap());
+ /** Single/Double buffer cannot be checked since result may vary ..
+ if(chosenGLCaps.isOnscreen() || chosenGLCaps.isFBO()) {
+ // dbl buffer may be disabled w/ offscreen pbuffer and bitmap
+ Assert.assertEquals(expGLCaps.getDoubleBuffered(), chosenGLCaps.getDoubleBuffered());
+ } */
+
+ {
+ GLContext context = glad.getContext();
+ System.out.println("Chosen GL CTX (2): "+context.getGLVersion());
+ Assert.assertNotNull(context);
+ Assert.assertTrue(context.isCreated());
+ }
+
+ System.out.println("Chosen GL Caps(2): "+glad.getChosenGLCapabilities());
+ System.out.println("Drawable Post-GL(2): "+glad.getClass().getName()+", "+glad.getNativeSurface().getClass().getName());
+
+ glad.addGLEventListener(demo);
+
+ final SnapshotGLEventListener snapshotGLEventListener = new SnapshotGLEventListener();
+ glad.addGLEventListener(snapshotGLEventListener);
+
+ glad.display(); // initial resize/display
+
+ // 1 - szStep = 2
+ Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(),
+ AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep));
+ snapshotGLEventListener.setMakeSnapshot();
+ glad.display();
+
+ // 2, 3 (resize + display)
+ szStep = 1;
+ setComponentSize(frame, nca, widthStep*szStep, heightStep*szStep);
+ Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(),
+ AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep));
+ glad.display();
+ snapshotGLEventListener.setMakeSnapshot();
+ glad.display();
+
+ // 4, 5 (resize + display)
+ szStep = 4;
+ setComponentSize(frame, nca, widthStep*szStep, heightStep*szStep);
+ Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(),
+ AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep));
+ glad.display();
+ snapshotGLEventListener.setMakeSnapshot();
+ glad.display();
+
+ Thread.sleep(50);
+
+ try {
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ frame.setVisible(false);
+ frame.remove(nca);
+ frame.dispose();
+ }});
+ } catch( Throwable throwable ) {
+ throwable.printStackTrace();
+ Assume.assumeNoException( throwable );
+ }
+ glad.destroy();
+ System.out.println("Fin: "+nca);
+ System.out.println("Fin: "+glad);
+ }
+
+ @Test
+ public void testAvailableInfo() {
+ GLDrawableFactory f = GLDrawableFactory.getDesktopFactory();
+ if(null != f) {
+ System.err.println(JoglVersion.getDefaultOpenGLInfo(f.getDefaultDevice(), null, true).toString());
+ }
+ f = GLDrawableFactory.getEGLFactory();
+ if(null != f) {
+ System.err.println(JoglVersion.getDefaultOpenGLInfo(f.getDefaultDevice(), null, true).toString());
+ }
+ }
+
+ @Test
+ public void testGL2OnScreenDblBuf() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+ if(null == reqGLCaps) return;
+ doTest(false, reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testGL2OffScreenLayerAuto() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+ if(null == reqGLCaps) return;
+ doTest(true, reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testGL2OffScreenFBOMSAA() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setFBO(true);
+ reqGLCaps.setOnscreen(true); // get native NEWT Window, not OffscreenWindow
+ reqGLCaps.setSampleBuffers(true);
+ reqGLCaps.setNumSamples(4);
+ doTest(true, reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testGL2OffScreenPbuffer() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2);
+ if(null == reqGLCaps) return;
+ reqGLCaps.setPBuffer(true);
+ reqGLCaps.setOnscreen(true); // get native NEWT Window, not OffscreenWindow
+ doTest(true, reqGLCaps, new GearsES2(1));
+ }
+
+ public static void main(String args[]) throws IOException {
+ org.junit.runner.JUnitCore.main(TestGLAutoDrawableNewtCanvasAWTOnOffscrnCapsAWT.class.getName());
+ }
+
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextDrawableSwitchNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextDrawableSwitchNEWT.java
index cece4c6..496be3d 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextDrawableSwitchNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextDrawableSwitchNEWT.java
@@ -39,13 +39,14 @@ import com.jogamp.newt.event.WindowUpdateEvent;
import com.jogamp.newt.opengl.GLWindow;
import javax.media.opengl.GLAutoDrawable;
-import javax.media.opengl.GLAutoDrawableDelegate;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawable;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
+
+import com.jogamp.opengl.GLAutoDrawableDelegate;
import com.jogamp.opengl.util.Animator;
import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
@@ -81,14 +82,17 @@ public class TestGLContextDrawableSwitchNEWT extends UITestCase {
Assert.assertTrue(AWTRobotUtil.waitForVisible(window, true));
Assert.assertTrue(AWTRobotUtil.waitForRealized(window, true));
- GLDrawableFactory factory = GLDrawableFactory.getFactory(caps.getGLProfile());
- GLDrawable drawable = factory.createGLDrawable(window);
+ final GLDrawableFactory factory = GLDrawableFactory.getFactory(caps.getGLProfile());
+ final GLDrawable drawable = factory.createGLDrawable(window);
Assert.assertNotNull(drawable);
drawable.setRealized(true);
Assert.assertTrue(drawable.isRealized());
- final GLAutoDrawableDelegate glad = new GLAutoDrawableDelegate(drawable, null, window, false) {
+ final GLContext context = drawable.createContext(null);
+ Assert.assertNotNull(context);
+
+ final GLAutoDrawableDelegate glad = new GLAutoDrawableDelegate(drawable, context, window, false, null) {
@Override
protected void destroyImplInLock() {
super.destroyImplInLock();
@@ -104,7 +108,7 @@ public class TestGLContextDrawableSwitchNEWT extends UITestCase {
}
@Override
public void windowResized(WindowEvent e) {
- glad.windowResizedOp();
+ glad.windowResizedOp(window.getWidth(), window.getHeight());
}
@Override
public void windowDestroyNotify(WindowEvent e) {
@@ -120,12 +124,16 @@ public class TestGLContextDrawableSwitchNEWT extends UITestCase {
public void testSwitch2WindowSingleContext() throws InterruptedException {
final QuitAdapter quitAdapter = new QuitAdapter();
- GLAutoDrawable glad1 = createGLAutoDrawable(caps, 64, 64, width, height, quitAdapter); // no GLContext!
- GLAutoDrawable glad2 = createGLAutoDrawable(caps, 2*64+width, 64, width+100, height+100, quitAdapter); // no GLContext!
+ GLAutoDrawable glad1 = createGLAutoDrawable(caps, 64, 64, width, height, quitAdapter);
+ GLAutoDrawable glad2 = createGLAutoDrawable(caps, 2*64+width, 64, width+100, height+100, quitAdapter);
- // create single context using glad1 and assign it to glad1
+ // create single context using glad1 and assign it to glad1,
+ // after destroying the prev. context!
{
- GLContext singleCtx = glad1.createContext(null);
+ final GLContext oldCtx = glad1.getContext();
+ Assert.assertNotNull(oldCtx);
+ oldCtx.destroy();
+ final GLContext singleCtx = glad1.createContext(null);
Assert.assertNotNull(singleCtx);
int res = singleCtx.makeCurrent();
Assert.assertTrue(GLContext.CONTEXT_CURRENT_NEW==res || GLContext.CONTEXT_CURRENT==res);
@@ -151,15 +159,22 @@ public class TestGLContextDrawableSwitchNEWT extends UITestCase {
System.err.println(s+" - switch - START "+ ( t1 - t0 ));
animator.pause();
+ // switch context _and_ the demo synchronously
if(0 == s%2) {
- glad1.addGLEventListener(0, glad2.removeGLEventListener(0));
+ final GLEventListener demo = glad2.removeGLEventListener(0);
GLContext ctx1 = glad1.setContext(glad2.getContext());
glad2.setContext(ctx1);
+ glad1.addGLEventListener(0, demo);
} else {
- glad2.addGLEventListener(0, glad1.removeGLEventListener(0));
+ final GLEventListener demo = glad1.removeGLEventListener(0);
GLContext ctx2 = glad2.setContext(glad1.getContext());
glad1.setContext(ctx2);
+ glad2.addGLEventListener(0, demo);
}
+ System.err.println(s+" - switch - display-1");
+ glad1.display();
+ System.err.println(s+" - switch - display-2");
+ glad2.display();
System.err.println(s+" - switch - END "+ ( t1 - t0 ));
@@ -210,13 +225,16 @@ public class TestGLContextDrawableSwitchNEWT extends UITestCase {
System.err.println(s+" - switch - START "+ ( t1 - t0 ));
animator.pause();
+ // switch context _and_ the demo synchronously
if(0 == s%2) {
- glWindow1.addGLEventListener(0, glWindow2.removeGLEventListener(0));
+ final GLEventListener demo = glWindow2.removeGLEventListener(0);
GLContext ctx1 = glWindow1.setContext(glWindow2.getContext());
+ glWindow1.addGLEventListener(0, demo);
glWindow2.setContext(ctx1);
} else {
- glWindow2.addGLEventListener(0, glWindow1.removeGLEventListener(0));
+ final GLEventListener demo = glWindow1.removeGLEventListener(0);
GLContext ctx2 = glWindow2.setContext(glWindow1.getContext());
+ glWindow2.addGLEventListener(0, demo);
glWindow1.setContext(ctx2);
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLExtensionQueryOffscreen.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLExtensionQueryOffscreen.java
index e4245ef..d4f3fec 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLExtensionQueryOffscreen.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLExtensionQueryOffscreen.java
@@ -32,14 +32,11 @@ import java.util.Collections;
import java.util.SortedSet;
import java.util.TreeSet;
-import javax.media.nativewindow.AbstractGraphicsDevice;
-import javax.media.opengl.DefaultGLCapabilitiesChooser;
import javax.media.opengl.GL;
-import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
-import javax.media.opengl.GLCapabilitiesChooser;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLOffscreenAutoDrawable;
import javax.media.opengl.GLProfile;
import jogamp.opengl.GLDrawableFactoryImpl;
@@ -77,13 +74,11 @@ public class TestGLExtensionQueryOffscreen {
@Test
public void testJogl2ExtensionCheck2() {
- GLCapabilities caps = new GLCapabilities(GLProfile.getDefault());
- GLDrawableFactory factory = GLDrawableFactory.getDesktopFactory();
- GLCapabilitiesChooser glCapsChooser = new DefaultGLCapabilitiesChooser();
- AbstractGraphicsDevice agd = factory.getDefaultDevice();
+ final GLCapabilities caps = new GLCapabilities(GLProfile.getDefault());
+ final GLDrawableFactory factory = GLDrawableFactory.getFactory(caps.getGLProfile());
+ final GLOffscreenAutoDrawable drawable = factory.createOffscreenAutoDrawable(null, caps, null, 256, 256, null);
- GLAutoDrawable drawable = factory.createGLPbuffer(agd, caps, glCapsChooser, 256, 256, null);
- GLContext context = drawable.getContext();
+ final GLContext context = drawable.getContext();
context.makeCurrent();
String extensions;
try {
@@ -94,8 +89,8 @@ public class TestGLExtensionQueryOffscreen {
String[] tabExtensions = extensions.split(" ");
SortedSet<String> setExtensions = new TreeSet<String>();
Collections.addAll(setExtensions, tabExtensions);
- System.out.println("DefaulContext: "+context);
- System.out.println("DefaulContext: "+setExtensions);
+ System.out.println("DefaultContext: "+context);
+ System.out.println("DefaultContext: "+setExtensions);
}
}
diff --git a/src/newt/classes/com/jogamp/newt/event/WindowUpdateEvent.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLProfile00NEWT.java
similarity index 72%
copy from src/newt/classes/com/jogamp/newt/event/WindowUpdateEvent.java
copy to src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLProfile00NEWT.java
index 505939d..19402c9 100644
--- a/src/newt/classes/com/jogamp/newt/event/WindowUpdateEvent.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLProfile00NEWT.java
@@ -1,5 +1,5 @@
/**
- * Copyright 2010 JogAmp Community. All rights reserved.
+ * Copyright 2012 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
@@ -26,24 +26,26 @@
* or implied, of JogAmp Community.
*/
-package com.jogamp.newt.event;
+package com.jogamp.opengl.test.junit.jogl.acore;
-import javax.media.nativewindow.util.Rectangle;
+import java.io.IOException;
-public class WindowUpdateEvent extends WindowEvent {
- final Rectangle bounds;
+import org.junit.Test;
- public WindowUpdateEvent(int eventType, Object source, long when, Rectangle bounds)
- {
- super(eventType, source, when);
- this.bounds = bounds;
- }
+import javax.media.opengl.*;
+
+import com.jogamp.opengl.test.junit.util.UITestCase;
- public Rectangle getBounds() {
- return bounds;
+public class TestGLProfile00NEWT extends UITestCase {
+
+ @Test
+ public void testInitSingleton() throws InterruptedException {
+ GLProfile.initSingleton();
}
- public String toString() {
- return "WindowUpdateEvent["+super.toString()+", "+bounds+"]";
+ public static void main(String args[]) throws IOException {
+ String tstname = TestGLProfile00NEWT.class.getName();
+ org.junit.runner.JUnitCore.main(tstname);
}
+
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGPUMemSec01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGPUMemSec01NEWT.java
index bebe353..6080343 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGPUMemSec01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGPUMemSec01NEWT.java
@@ -61,6 +61,8 @@ public class TestGPUMemSec01NEWT extends UITestCase {
new GLCapabilities(glp), width, height, true);
final GL gl = winctx.context.getGL();
+ // System.err.println("Pre GL Error: 0x"+Integer.toHexString(gl.glGetError()));
+ // System.err.println(winctx.drawable);
Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
// misc GL setup
@@ -249,7 +251,7 @@ public class TestGPUMemSec01NEWT extends UITestCase {
NEWTGLContext.destroyWindow(winctx);
}
-
+
@Test
public void testReadPixelsGL_99x100xRGBxUB() throws InterruptedException {
GLProfile glp = GLProfile.getGL2ES2();
diff --git a/src/test/com/jogamp/opengl/test/junit/util/MiscUtils.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestInitConcurrent01NEWT.java
similarity index 50%
copy from src/test/com/jogamp/opengl/test/junit/util/MiscUtils.java
copy to src/test/com/jogamp/opengl/test/junit/jogl/acore/TestInitConcurrent01NEWT.java
index 9cbeabb..719d1fc 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/MiscUtils.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestInitConcurrent01NEWT.java
@@ -26,47 +26,59 @@
* or implied, of JogAmp Community.
*/
+package com.jogamp.opengl.test.junit.jogl.acore;
-package com.jogamp.opengl.test.junit.util;
+import java.io.IOException;
-import java.lang.reflect.*;
+import org.junit.Test;
-public class MiscUtils {
- public static int atoi(String str, int def) {
- try {
- return Integer.parseInt(str);
- } catch (Exception ex) {
- ex.printStackTrace();
- }
- return def;
+import com.jogamp.common.os.Platform;
+
+/**
+ * Concurrent initialization and lock-free rendering using shared NEWT Display EDT instances.
+ * <p>
+ * Rendering is always lock-free and independent of the EDT, however shared NEWT Display instances
+ * perform lifecycle actions (window creation etc) with locking.
+ * </p>
+ */
+public class TestInitConcurrent01NEWT extends InitConcurrentBaseNEWT {
+ static boolean mainRun = false;
+
+ @Test
+ public void test02TwoThreads() throws InterruptedException {
+ runJOGLTasks(2, true);
+ }
+
+ @Test
+ public void test02FourThreads() throws InterruptedException {
+ runJOGLTasks(4, true);
}
- public static long atol(String str, long def) {
- try {
- return Long.parseLong(str);
- } catch (Exception ex) {
- ex.printStackTrace();
+ @Test
+ public void test16SixteenThreads() throws InterruptedException {
+ if( !mainRun &&
+ Platform.getCPUFamily() != Platform.CPUFamily.ARM &&
+ Platform.getOSType() != Platform.OSType.WINDOWS ) {
+ runJOGLTasks(16, true);
+ } else {
+ runJOGLTasks( 6, true);
}
- return def;
}
-
- public static boolean setFieldIfExists(Object instance, String fieldName, Object value) {
- try {
- Field f = instance.getClass().getField(fieldName);
- if(value instanceof Boolean || f.getType().isInstance(value)) {
- f.set(instance, value);
- return true;
- } else {
- System.out.println(instance.getClass()+" '"+fieldName+"' field not assignable with "+value.getClass()+", it's a: "+f.getType());
+
+ public static void main(String args[]) throws IOException {
+ mainRun = true;
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-normalRun")) {
+ mainRun = false;
+ } else if(args[i].equals("-time")) {
+ i++;
+ try {
+ duration = Integer.parseInt(args[i]);
+ } catch (Exception ex) { ex.printStackTrace(); }
}
- } catch (IllegalAccessException ex) {
- throw new RuntimeException(ex);
- } catch (NoSuchFieldException nsfe) {
- // OK - throw new RuntimeException(instance.getClass()+" has no '"+fieldName+"' field", nsfe);
}
- return false;
+ String tstname = TestInitConcurrent01NEWT.class.getName();
+ org.junit.runner.JUnitCore.main(tstname);
}
-}
-
-
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestInitConcurrent02NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestInitConcurrent02NEWT.java
new file mode 100644
index 0000000..f2871a6
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestInitConcurrent02NEWT.java
@@ -0,0 +1,96 @@
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community OR
+ * CONTRIBUTORS 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.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.opengl.test.junit.jogl.acore;
+
+import java.io.IOException;
+
+import org.junit.Test;
+
+import com.jogamp.common.os.Platform;
+
+/**
+ * Concurrent and lock-free initialization and rendering using exclusive NEWT Display EDT instances.
+ * <p>
+ * Rendering is always lock-free and independent of the EDT, however exclusive NEWT Display instances
+ * perform lifecycle actions (window creation etc) w/o locking.
+ * </p>
+ */
+public class TestInitConcurrent02NEWT extends InitConcurrentBaseNEWT {
+ static boolean mainRun = false;
+
+ @Test
+ public void test02TwoThreads() throws InterruptedException {
+ if(!mainRun) {
+ System.err.println("Disabled for auto unit test until further analysis - Windows/ATI driver crash");
+ return;
+ }
+ runJOGLTasks(2, false);
+ }
+
+ @Test
+ public void test02FourThreads() throws InterruptedException {
+ if(!mainRun) {
+ System.err.println("Disabled for auto unit test until further analysis - Windows/ATI driver crash");
+ return;
+ }
+ runJOGLTasks(4, false);
+ }
+
+ @Test
+ public void test16SixteenThreads() throws InterruptedException {
+ if(!mainRun) {
+ System.err.println("Disabled for auto unit test until further analysis - Windows/ATI driver crash");
+ return;
+ }
+ if( !mainRun &&
+ Platform.getCPUFamily() != Platform.CPUFamily.ARM &&
+ Platform.getOSType() != Platform.OSType.WINDOWS ) {
+ runJOGLTasks(16, false);
+ } else {
+ runJOGLTasks( 6, false);
+ }
+ }
+
+ public static void main(String args[]) throws IOException {
+ mainRun = true;
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-normalRun")) {
+ mainRun = false;
+ } else if(args[i].equals("-time")) {
+ i++;
+ try {
+ duration = Integer.parseInt(args[i]);
+ } catch (Exception ex) { ex.printStackTrace(); }
+ }
+ }
+ String tstname = TestInitConcurrent02NEWT.class.getName();
+ org.junit.runner.JUnitCore.main(tstname);
+ }
+
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestNEWTCloseX11DisplayBug565.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestNEWTCloseX11DisplayBug565.java
index 33a9b77..c1b7464 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestNEWTCloseX11DisplayBug565.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestNEWTCloseX11DisplayBug565.java
@@ -11,12 +11,14 @@ import javax.media.opengl.DefaultGLCapabilitiesChooser;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLOffscreenAutoDrawable;
import javax.media.opengl.GLPbuffer;
import javax.media.opengl.GLProfile;
/**
* Tests the closing the device of GLWindow and GLPBuffer in JOGL
*/
+ at SuppressWarnings("deprecation")
public class TestNEWTCloseX11DisplayBug565 {
@Test
@@ -59,7 +61,7 @@ public class TestNEWTCloseX11DisplayBug565 {
@Test
- public void testX11WindowMemoryLeakOffscreenWindow() throws Exception {
+ public void testX11WindowMemoryLeakGLPbuffer() throws Exception {
GLProfile.initSingleton(); // ensure shared resource runner is done
try {
for ( int j = 0; j < 10; j++ ) {
@@ -100,6 +102,48 @@ public class TestNEWTCloseX11DisplayBug565 {
}
}
+ @Test
+ public void testX11WindowMemoryLeakFBOAutoDrawable() throws Exception {
+ GLProfile.initSingleton(); // ensure shared resource runner is done
+ try {
+ for ( int j = 0; j < 10; j++ ) {
+ final int open0;
+ if(NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(false)) {
+ open0 = X11Util.getOpenDisplayConnectionNumber();
+ } else {
+ open0 = 0;
+ }
+ final GLProfile glp = GLProfile.getDefault( );
+ GLCapabilitiesImmutable caps = new GLCapabilities( glp );
+
+
+ GLOffscreenAutoDrawable buffer = GLDrawableFactory.getFactory( glp ).createOffscreenAutoDrawable(
+ null,
+ caps,
+ new DefaultGLCapabilitiesChooser(),
+ 256,
+ 256,
+ null
+ );
+ buffer.display();
+ buffer.destroy();
+
+ if(NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(false)) {
+ final int openD = X11Util.getOpenDisplayConnectionNumber() - open0;
+ if(openD > 0) {
+ X11Util.dumpOpenDisplayConnections();
+ X11Util.dumpPendingDisplayConnections();
+ Assert.assertEquals("New display connection didn't close", 0, openD);
+ }
+ }
+ }
+ }
+ catch ( Exception e ) {
+ e.printStackTrace();
+ Assert.fail(e.getMessage());
+ }
+ }
+
public static void main(String args[]) {
org.junit.runner.JUnitCore.main(TestNEWTCloseX11DisplayBug565.class.getName());
}
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingOffscreenLayer01GLCanvasAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestOffscreenLayer01GLCanvasAWT.java
similarity index 70%
rename from src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingOffscreenLayer01GLCanvasAWT.java
rename to src/test/com/jogamp/opengl/test/junit/jogl/acore/TestOffscreenLayer01GLCanvasAWT.java
index 4542fa4..9040716 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingOffscreenLayer01GLCanvasAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestOffscreenLayer01GLCanvasAWT.java
@@ -26,19 +26,22 @@
* or implied, of JogAmp Community.
*/
-package com.jogamp.opengl.test.junit.newt.parenting;
+package com.jogamp.opengl.test.junit.jogl.acore;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Frame;
+import java.io.BufferedReader;
import java.io.IOException;
+import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import javax.media.opengl.GLAnimatorControl;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLProfile;
import javax.media.opengl.awt.GLCanvas;
import jogamp.nativewindow.jawt.JAWTUtil;
@@ -56,11 +59,16 @@ import com.jogamp.opengl.test.junit.util.MiscUtils;
import com.jogamp.opengl.test.junit.util.UITestCase;
import com.jogamp.opengl.util.Animator;
-public class TestParentingOffscreenLayer01GLCanvasAWT extends UITestCase {
+public class TestOffscreenLayer01GLCanvasAWT extends UITestCase {
+ static boolean singleBuffer = false;
+ static boolean useMSAA = false;
+ static boolean addComp = true;
+ static int swapInterval = 1;
+ static boolean shallUseOffscreenPBufferLayer = false;
+ static boolean noAnimation = false;
static Dimension frameSize0;
static Dimension frameSize1;
static Dimension preferredGLSize;
- static Dimension minGLSize;
static long durationPerTest = 1000;
@BeforeClass
@@ -68,7 +76,6 @@ public class TestParentingOffscreenLayer01GLCanvasAWT extends UITestCase {
frameSize0 = new Dimension(500,300);
frameSize1 = new Dimension(800,600);
preferredGLSize = new Dimension(400,200);
- minGLSize = new Dimension(200,100);
}
private void setupFrameAndShow(final Frame f, java.awt.Component comp) throws InterruptedException, InvocationTargetException {
@@ -90,10 +97,12 @@ public class TestParentingOffscreenLayer01GLCanvasAWT extends UITestCase {
javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
+ f.pack();
f.validate();
f.setVisible(true);
}});
}
+
private void end(GLAnimatorControl actrl, final Frame f, Window w) throws InterruptedException, InvocationTargetException {
actrl.stop();
javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
@@ -114,49 +123,67 @@ public class TestParentingOffscreenLayer01GLCanvasAWT extends UITestCase {
}
@Test
- public void testOnscreenLayerGLCanvas_Onscreen() throws InterruptedException, InvocationTargetException {
- testOffscreenLayerGLCanvas_Impl(false);
+ public void test01_GLDefault() throws InterruptedException, InvocationTargetException {
+ testOffscreenLayerGLCanvas_Impl(null);
}
@Test
- public void testOffscreenLayerGLCanvas_OffscreenLayerWithOnscreenClass() throws InterruptedException, InvocationTargetException {
- testOffscreenLayerGLCanvas_Impl(true);
- }
-
- private void testOffscreenLayerGLCanvas_Impl(boolean offscreenLayer) throws InterruptedException, InvocationTargetException {
- if(!offscreenLayer && JAWTUtil.isOffscreenLayerRequired()) {
- System.err.println("onscreen layer n/a");
+ public void test01_GL3() throws InterruptedException, InvocationTargetException {
+ if( !GLProfile.isAvailable(GLProfile.GL3) ) {
+ System.err.println("GL3 n/a");
return;
}
- if(offscreenLayer && !JAWTUtil.isOffscreenLayerSupported()) {
+ testOffscreenLayerGLCanvas_Impl(GLProfile.get(GLProfile.GL3));
+ }
+
+ private void testOffscreenLayerGLCanvas_Impl(GLProfile glp) throws InterruptedException, InvocationTargetException {
+ if(!JAWTUtil.isOffscreenLayerSupported()) {
System.err.println("offscreen layer n/a");
return;
}
final Frame frame1 = new Frame("AWT Parent Frame");
- GLCapabilities glCaps = new GLCapabilities(null);
- final GLCanvas glc = new GLCanvas(glCaps);
- glc.setShallUseOffscreenLayer(offscreenLayer); // trigger offscreen layer - if supported
+ GLCapabilities caps = new GLCapabilities(glp);
+ if(singleBuffer) {
+ caps.setDoubleBuffered(false);
+ }
+ if(useMSAA) {
+ caps.setNumSamples(4);
+ caps.setSampleBuffers(true);
+ }
+ if(shallUseOffscreenPBufferLayer) {
+ caps.setPBuffer(true);
+ caps.setOnscreen(true); // simulate normal behavior ..
+ }
+ final GLCanvas glc = new GLCanvas(caps);
+ glc.setShallUseOffscreenLayer(true); // trigger offscreen layer - if supported
glc.setPreferredSize(preferredGLSize);
- glc.setMinimumSize(minGLSize);
+ glc.setMinimumSize(preferredGLSize);
+ glc.setSize(preferredGLSize);
- GLEventListener demo1 = new GearsES2(1);
+ GearsES2 demo1 = new GearsES2(swapInterval);
+ if(noAnimation) {
+ demo1.setDoRotation(false);
+ }
glc.addGLEventListener(demo1);
frame1.setSize(frameSize0);
setupFrameAndShow(frame1, glc);
Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glc, true));
Assert.assertEquals(true, AWTRobotUtil.waitForVisible(glc, true));
- Assert.assertEquals(JAWTUtil.isOffscreenLayerSupported() && offscreenLayer,
- glc.isOffscreenLayerSurfaceEnabled());
+ Assert.assertEquals(true, glc.isOffscreenLayerSurfaceEnabled());
GLAnimatorControl animator1 = new Animator(glc);
- animator1.start();
+ if(!noAnimation) {
+ animator1.start();
+ }
+ animator1.setUpdateFPSFrames(60, System.err);
Thread.sleep(durationPerTest/2);
javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
frame1.setSize(frameSize1);
+ frame1.pack();
frame1.validate();
}});
@@ -187,12 +214,33 @@ public class TestParentingOffscreenLayer01GLCanvasAWT extends UITestCase {
}
public static void main(String args[]) throws IOException {
+ boolean waitForKey = false;
for(int i=0; i<args.length; i++) {
if(args[i].equals("-time")) {
durationPerTest = atoi(args[++i]);
+ } else if(args[i].equals("-vsync")) {
+ i++;
+ swapInterval = MiscUtils.atoi(args[i], swapInterval);
+ } else if(args[i].equals("-layeredPBuffer")) {
+ shallUseOffscreenPBufferLayer = true;
+ } else if(args[i].equals("-msaa")) {
+ useMSAA = true;
+ } else if(args[i].equals("-single")) {
+ singleBuffer = true;
+ } else if(args[i].equals("-still")) {
+ noAnimation = true;
+ } else if(args[i].equals("-wait")) {
+ waitForKey = true;
}
}
- String tstname = TestParentingOffscreenLayer01GLCanvasAWT.class.getName();
+ if(waitForKey) {
+ BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
+ System.err.println("Press enter to continue");
+ try {
+ System.err.println(stdin.readLine());
+ } catch (IOException e) { }
+ }
+ String tstname = TestOffscreenLayer01GLCanvasAWT.class.getName();
/*
org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(new String[] {
tstname,
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingOffscreenLayer02NewtCanvasAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestOffscreenLayer02NewtCanvasAWT.java
similarity index 68%
rename from src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingOffscreenLayer02NewtCanvasAWT.java
rename to src/test/com/jogamp/opengl/test/junit/jogl/acore/TestOffscreenLayer02NewtCanvasAWT.java
index 6a1980b..e4a3bce 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingOffscreenLayer02NewtCanvasAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestOffscreenLayer02NewtCanvasAWT.java
@@ -26,19 +26,22 @@
* or implied, of JogAmp Community.
*/
-package com.jogamp.opengl.test.junit.newt.parenting;
+package com.jogamp.opengl.test.junit.jogl.acore;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Frame;
+import java.io.BufferedReader;
import java.io.IOException;
+import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import javax.media.opengl.GLAnimatorControl;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLProfile;
import jogamp.nativewindow.jawt.JAWTUtil;
@@ -50,16 +53,22 @@ import com.jogamp.newt.Window;
import com.jogamp.newt.awt.NewtCanvasAWT;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+import com.jogamp.opengl.test.junit.newt.parenting.NewtAWTReparentingKeyAdapter;
import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
import com.jogamp.opengl.test.junit.util.MiscUtils;
import com.jogamp.opengl.test.junit.util.UITestCase;
import com.jogamp.opengl.util.Animator;
-public class TestParentingOffscreenLayer02NewtCanvasAWT extends UITestCase {
+public class TestOffscreenLayer02NewtCanvasAWT extends UITestCase {
+ static boolean singleBuffer = false;
+ static boolean useMSAA = false;
+ static boolean addComp = true;
+ static int swapInterval = 1;
+ static boolean shallUseOffscreenPBufferLayer = false;
+ static boolean noAnimation = false;
static Dimension frameSize0;
static Dimension frameSize1;
static Dimension preferredGLSize;
- static Dimension minGLSize;
static long durationPerTest = 1000;
@BeforeClass
@@ -67,7 +76,6 @@ public class TestParentingOffscreenLayer02NewtCanvasAWT extends UITestCase {
frameSize0 = new Dimension(500,300);
frameSize1 = new Dimension(800,600);
preferredGLSize = new Dimension(400,200);
- minGLSize = new Dimension(200,100);
}
private void setupFrameAndShow(final Frame f, java.awt.Component comp) throws InterruptedException, InvocationTargetException {
@@ -89,10 +97,12 @@ public class TestParentingOffscreenLayer02NewtCanvasAWT extends UITestCase {
javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
+ f.pack();
f.validate();
f.setVisible(true);
}});
}
+
private void end(GLAnimatorControl actrl, final Frame f, Window w) throws InterruptedException, InvocationTargetException {
actrl.stop();
javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
@@ -105,49 +115,50 @@ public class TestParentingOffscreenLayer02NewtCanvasAWT extends UITestCase {
}
@Test
- public void testOnscreenLayerNewtCanvas_Onscreen() throws InterruptedException, InvocationTargetException {
- if(!JAWTUtil.isOffscreenLayerRequired()) {
- testOffscreenLayerNewtCanvas_Impl(false, false);
- } else {
- System.err.println("onscreen layer n/a");
- }
+ public void test01_GLDefault() throws InterruptedException, InvocationTargetException {
+ testOffscreenLayerNewtCanvas_Impl(null);
}
- // @Test
- public void testOffscreenLayerNewtCanvas_OffscreenLayerWithOffscreenClass() throws InterruptedException, InvocationTargetException {
- if(JAWTUtil.isOffscreenLayerSupported()) {
- testOffscreenLayerNewtCanvas_Impl(true, true);
- } else {
- System.err.println("offscreen layer n/a");
- }
+ @Test
+ public void test02_GL3() throws InterruptedException, InvocationTargetException {
+ if( !GLProfile.isAvailable(GLProfile.GL3) ) {
+ System.err.println("GL3 n/a");
+ return;
+ }
+ testOffscreenLayerNewtCanvas_Impl(GLProfile.get(GLProfile.GL3));
}
- @Test
- public void testOffscreenLayerNewtCanvas_OffscreenLayerWithOnscreenClass() throws InterruptedException, InvocationTargetException {
- if(JAWTUtil.isOffscreenLayerSupported()) {
- testOffscreenLayerNewtCanvas_Impl(true, false);
- } else {
+ private void testOffscreenLayerNewtCanvas_Impl(GLProfile glp) throws InterruptedException, InvocationTargetException {
+ if(!JAWTUtil.isOffscreenLayerSupported()) {
System.err.println("offscreen layer n/a");
+ return;
}
- }
-
- private void testOffscreenLayerNewtCanvas_Impl(boolean offscreenLayer, boolean offscreenClass) throws InterruptedException, InvocationTargetException {
final Frame frame1 = new Frame("AWT Parent Frame");
- GLCapabilities glCaps = new GLCapabilities(null);
- if(offscreenClass) {
- glCaps.setOnscreen(false);
- glCaps.setPBuffer(true);
+ GLCapabilities caps = new GLCapabilities(glp);
+ if(singleBuffer) {
+ caps.setDoubleBuffered(false);
}
-
- GLWindow glWindow1 = GLWindow.create(glCaps);
+ if(useMSAA) {
+ caps.setNumSamples(4);
+ caps.setSampleBuffers(true);
+ }
+ if(shallUseOffscreenPBufferLayer) {
+ caps.setPBuffer(true);
+ caps.setOnscreen(true); // get native NEWT Window, not OffscreenWindow
+ }
+ GLWindow glWindow1 = GLWindow.create(caps);
final NewtCanvasAWT newtCanvasAWT1 = new NewtCanvasAWT(glWindow1);
- newtCanvasAWT1.setShallUseOffscreenLayer(offscreenLayer); // trigger offscreen layer - if supported
+ newtCanvasAWT1.setShallUseOffscreenLayer(true); // trigger offscreen layer - if supported
newtCanvasAWT1.setPreferredSize(preferredGLSize);
- newtCanvasAWT1.setMinimumSize(minGLSize);
+ newtCanvasAWT1.setMinimumSize(preferredGLSize);
+ newtCanvasAWT1.setSize(preferredGLSize);
- GLEventListener demo1 = new GearsES2(1);
+ GearsES2 demo1 = new GearsES2(swapInterval);
+ if(noAnimation) {
+ demo1.setDoRotation(false);
+ }
setDemoFields(demo1, glWindow1, false);
glWindow1.addGLEventListener(demo1);
glWindow1.addKeyListener(new NewtAWTReparentingKeyAdapter(frame1, newtCanvasAWT1, glWindow1));
@@ -157,16 +168,19 @@ public class TestParentingOffscreenLayer02NewtCanvasAWT extends UITestCase {
Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glWindow1, true));
Assert.assertEquals(true, AWTRobotUtil.waitForVisible(glWindow1, true));
Assert.assertEquals(newtCanvasAWT1.getNativeWindow(),glWindow1.getParent());
- Assert.assertEquals(JAWTUtil.isOffscreenLayerSupported() && offscreenLayer,
- newtCanvasAWT1.isOffscreenLayerSurfaceEnabled());
+ Assert.assertEquals(true, newtCanvasAWT1.isOffscreenLayerSurfaceEnabled());
GLAnimatorControl animator1 = new Animator(glWindow1);
- animator1.start();
+ if(!noAnimation) {
+ animator1.start();
+ }
+ animator1.setUpdateFPSFrames(60, System.err);
Thread.sleep(durationPerTest/2);
javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
frame1.setSize(frameSize1);
+ frame1.pack();
frame1.validate();
}});
@@ -197,12 +211,33 @@ public class TestParentingOffscreenLayer02NewtCanvasAWT extends UITestCase {
}
public static void main(String args[]) throws IOException {
+ boolean waitForKey = false;
for(int i=0; i<args.length; i++) {
if(args[i].equals("-time")) {
durationPerTest = atoi(args[++i]);
+ } else if(args[i].equals("-vsync")) {
+ i++;
+ swapInterval = MiscUtils.atoi(args[i], swapInterval);
+ } else if(args[i].equals("-layeredPBuffer")) {
+ shallUseOffscreenPBufferLayer = true;
+ } else if(args[i].equals("-msaa")) {
+ useMSAA = true;
+ } else if(args[i].equals("-single")) {
+ singleBuffer = true;
+ } else if(args[i].equals("-still")) {
+ noAnimation = true;
+ } else if(args[i].equals("-wait")) {
+ waitForKey = true;
}
}
- String tstname = TestParentingOffscreenLayer02NewtCanvasAWT.class.getName();
+ if(waitForKey) {
+ BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
+ System.err.println("Press enter to continue");
+ try {
+ System.err.println(stdin.readLine());
+ } catch (IOException e) { }
+ }
+ String tstname = TestOffscreenLayer02NewtCanvasAWT.class.getName();
/*
org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(new String[] {
tstname,
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestPBufferDeadlockAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestPBufferDeadlockAWT.java
index 3a25d12..90934f1 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestPBufferDeadlockAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestPBufferDeadlockAWT.java
@@ -45,6 +45,7 @@ import org.junit.Test;
import com.jogamp.common.util.RunnableTask;
import com.jogamp.opengl.test.junit.util.UITestCase;
+ at SuppressWarnings("deprecation")
public class TestPBufferDeadlockAWT extends UITestCase {
static GLProfile glp;
static int width, height;
@@ -100,6 +101,7 @@ public class TestPBufferDeadlockAWT extends UITestCase {
}
});
Assert.assertTrue(done[0]);
+ pbuffer.destroy();
}
@Test(timeout = 2000) // 2s timeout
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestPMVMatrix01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestPMVMatrix01NEWT.java
new file mode 100644
index 0000000..c44a82a
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestPMVMatrix01NEWT.java
@@ -0,0 +1,442 @@
+/**
+ * Copyright 2012 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community OR
+ * CONTRIBUTORS 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.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.opengl.test.junit.jogl.acore;
+
+import java.nio.FloatBuffer;
+
+import javax.media.opengl.GL2ES1;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLProfile;
+import javax.media.opengl.fixedfunc.GLMatrixFunc;
+
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.jogamp.common.os.Platform;
+import com.jogamp.opengl.FloatUtil;
+import com.jogamp.opengl.test.junit.util.MiscUtils;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+import com.jogamp.opengl.util.PMVMatrix;
+
+public class TestPMVMatrix01NEWT extends UITestCase {
+
+ static final float epsilon = 0.00001f;
+
+ // matrix 2 rows x 3 columns - In row major order
+ static FloatBuffer matrix2x3R = FloatBuffer.wrap( new float[] { 1.0f, 2.0f, 3.0f,
+ 4.0f, 5.0f, 6.0f } );
+
+ // matrix 2 rows x 3 columns - In column major order
+ static FloatBuffer matrix2x3C = FloatBuffer.wrap( new float[] { 1.0f, 4.0f,
+ 2.0f, 5.0f,
+ 3.0f, 6.0f } );
+
+ // matrix 3 rows x 2 columns - In row major order
+ static FloatBuffer matrix3x2R = FloatBuffer.wrap( new float[] { 1.0f, 2.0f,
+ 3.0f, 4.0f,
+ 5.0f, 6.0f } );
+
+ // matrix 3 rows x 2 columns - In column major order
+ static FloatBuffer matrix3x2C = FloatBuffer.wrap( new float[] { 1.0f, 3.0f, 5.0f,
+ 2.0f, 4.0f, 6.0f } );
+
+ // Translated xyz 123 - Row - In row major order !
+ static FloatBuffer translated123R = FloatBuffer.wrap( new float[] { 1.0f, 0.0f, 0.0f, 1.0f,
+ 0.0f, 1.0f, 0.0f, 2.0f,
+ 0.0f, 0.0f, 1.0f, 3.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f } );
+
+ // Translated xyz 123 - Column - In column major order !
+ static FloatBuffer translated123C = FloatBuffer.wrap( new float[] { 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 1.0f, 2.0f, 3.0f, 1.0f } );
+
+ // Translated xyz 123 - Inverse - In column major order !
+ static FloatBuffer translated123I = FloatBuffer.wrap( new float[] { 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ -1.0f, -2.0f, -3.0f, 1.0f } );
+
+ // Translated xyz 123 - Inverse and Transposed - In column major order !
+ static FloatBuffer translated123IT = FloatBuffer.wrap( new float[] { 1.0f, 0.0f, 0.0f, -1.0f,
+ 0.0f, 1.0f, 0.0f, -2.0f,
+ 0.0f, 0.0f, 1.0f, -3.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f } );
+
+ @Test
+ public void test00MatrixToString() {
+ final String s4x4Cpmv = PMVMatrix.matrixToString(null, "%10.5f", translated123C).toString();
+ final String s4x4Cflu = FloatUtil.matrixToString(null, null, "%10.5f", translated123C, 0, 4, 4, false).toString();
+ final String s4x4Rflu = FloatUtil.matrixToString(null, null, "%10.5f", translated123R, 0, 4, 4, true).toString();
+ System.err.println("PMV-C-O 4x4: ");
+ System.err.println(s4x4Cpmv);
+ System.err.println();
+ System.err.println("FLU-C-O 4x4: ");
+ System.err.println(s4x4Cflu);
+ System.err.println();
+ System.err.println("FLU-R-O 4x4: ");
+ System.err.println(s4x4Rflu);
+ System.err.println();
+ Assert.assertEquals(s4x4Cpmv, s4x4Cflu);
+ Assert.assertEquals(s4x4Cflu, s4x4Rflu);
+
+ final String s2x3Rflu = FloatUtil.matrixToString(null, null, "%10.5f", matrix2x3R, 0, 2, 3, true).toString();
+ final String s2x3Cflu = FloatUtil.matrixToString(null, null, "%10.5f", matrix2x3C, 0, 2, 3, false).toString();
+ System.err.println("FLU-R-O 2x3: ");
+ System.err.println(s2x3Rflu);
+ System.err.println();
+ System.err.println("FLU-C-O 2x3: ");
+ System.err.println(s2x3Cflu);
+ System.err.println();
+ Assert.assertEquals(s2x3Cflu, s2x3Rflu);
+
+ final String s3x2Rflu = FloatUtil.matrixToString(null, null, "%10.5f", matrix3x2R, 0, 3, 2, true).toString();
+ final String s3x2Cflu = FloatUtil.matrixToString(null, null, "%10.5f", matrix3x2C, 0, 3, 2, false).toString();
+ System.err.println("FLU-R-O 3x2: ");
+ System.err.println(s3x2Rflu);
+ System.err.println();
+ System.err.println("FLU-C-O 3x2: ");
+ System.err.println(s3x2Cflu);
+ System.err.println();
+ Assert.assertEquals(s3x2Cflu, s3x2Rflu);
+ }
+
+ /**
+ * Test using traditional access workflow, i.e. 1) operation 2) get-matrix references
+ * <p>
+ * The Mvi and Mvit dirty-bits and request-mask will be validated.
+ * </p>
+ */
+ @SuppressWarnings("deprecation")
+ @Test
+ public void test01MviUpdateTraditionalAccess() {
+ FloatBuffer p, mv, mvi, mvit;
+ boolean b;
+ final PMVMatrix pmv = new PMVMatrix(true);
+ // System.err.println("P0: "+pmv.toString());
+
+ Assert.assertTrue("Dirty bits clean, "+pmv.toString(), 0 != pmv.getDirtyBits());
+ Assert.assertEquals("Request bits not zero, "+pmv.toString(), 0, pmv.getRequestMask());
+
+ //
+ // Action #0
+ //
+ final FloatBuffer ident;
+ {
+ pmv.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
+ pmv.glLoadIdentity();
+ ident = pmv.glGetPMatrixf();
+
+ pmv.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
+ pmv.glLoadIdentity();
+ }
+ Assert.assertTrue("Modified bits zero", 0 != pmv.getModifiedBits(true)); // clear & test
+ Assert.assertTrue("Dirty bits clean, "+pmv.toString(), 0 != pmv.getDirtyBits());
+ Assert.assertEquals("Request bits not zero, "+pmv.toString(), 0, pmv.getRequestMask());
+
+ //
+ // Action #1
+ //
+ pmv.glTranslatef(1f, 2f, 3f); // all dirty !
+ Assert.assertTrue("Modified bits zero", 0 != pmv.getModifiedBits(true)); // clear & test
+ Assert.assertTrue("Dirty bits clean, "+pmv.toString(), 0 != pmv.getDirtyBits());
+ Assert.assertEquals("Request bits not zero, "+pmv.toString(), 0, pmv.getRequestMask());
+ // System.err.println("P1: "+pmv.toString());
+
+ b = pmv.update(); // will not clean dirty bits, since no request has been made -> false
+ Assert.assertEquals("Update has been perfomed, but non requested", false, b);
+ Assert.assertTrue("Dirty bits clean, "+pmv.toString(), 0 != pmv.getDirtyBits());
+ Assert.assertEquals("Request bits not zero, "+pmv.toString(), 0, pmv.getRequestMask());
+ // System.err.println("P2: "+pmv.toString());
+
+ //
+ // Get
+ //
+ p = pmv.glGetPMatrixf();
+ MiscUtils.assertFloatBufferEquals("P not identity, "+pmv.toString(), ident, p, epsilon);
+ mv = pmv.glGetMvMatrixf();
+ MiscUtils.assertFloatBufferEquals("Mv not translated123, "+pmv.toString(), translated123C, mv, epsilon);
+ mvi = pmv.glGetMviMatrixf();
+ MiscUtils.assertFloatBufferEquals("Mvi not translated123, "+pmv.toString(), translated123I, mvi, epsilon);
+ Assert.assertEquals("Remaining dirty bits not Mvit, "+pmv.toString(), PMVMatrix.DIRTY_INVERSE_TRANSPOSED_MODELVIEW, pmv.getDirtyBits());
+ Assert.assertEquals("Request bit Mvi not set, "+pmv.toString(), PMVMatrix.DIRTY_INVERSE_MODELVIEW, pmv.getRequestMask());
+ // System.err.println("P3: "+pmv.toString());
+
+ mvit = pmv.glGetMvitMatrixf();
+ MiscUtils.assertFloatBufferEquals("Mvit not translated123, "+pmv.toString()+pmv.toString(), translated123IT, mvit, epsilon);
+ Assert.assertTrue("Dirty bits not clean, "+pmv.toString(), 0 == pmv.getDirtyBits());
+ Assert.assertEquals("Request bits Mvi and Mvit not set, "+pmv.toString(), PMVMatrix.DIRTY_INVERSE_MODELVIEW | PMVMatrix.DIRTY_INVERSE_TRANSPOSED_MODELVIEW, pmv.getRequestMask());
+ // System.err.println("P4: "+pmv.toString());
+
+ //
+ // Action #2
+ //
+ pmv.glLoadIdentity(); // all dirty
+ Assert.assertTrue("Modified bits zero", 0 != pmv.getModifiedBits(true)); // clear & test
+ Assert.assertTrue("Dirty bits clean, "+pmv.toString(), 0 != pmv.getDirtyBits());
+ Assert.assertEquals("Request bits Mvi and Mvit not set, "+pmv.toString(), PMVMatrix.DIRTY_INVERSE_MODELVIEW | PMVMatrix.DIRTY_INVERSE_TRANSPOSED_MODELVIEW, pmv.getRequestMask());
+ MiscUtils.assertFloatBufferEquals("P not identity, "+pmv.toString(), ident, p, epsilon);
+ MiscUtils.assertFloatBufferEquals("Mv not identity, "+pmv.toString(), ident, mv, epsilon);
+ MiscUtils.assertFloatBufferNotEqual("Mvi already identity w/o update, "+pmv.toString(), ident, mvi, epsilon);
+ MiscUtils.assertFloatBufferNotEqual("Mvit already identity w/o update, "+pmv.toString(), ident, mvit, epsilon);
+ MiscUtils.assertFloatBufferEquals("Mvi not translated123, "+pmv.toString()+pmv.toString(), translated123I, mvi, epsilon);
+ MiscUtils.assertFloatBufferEquals("Mvit not translated123, "+pmv.toString()+pmv.toString(), translated123IT, mvit, epsilon);
+
+ b = pmv.update(); // will clean dirty bits, since request has been made -> true
+ Assert.assertEquals("Update has not been perfomed, but requested", true, b);
+ Assert.assertTrue("Dirty bits not clean, "+pmv.toString(), 0 == pmv.getDirtyBits());
+ Assert.assertEquals("Request bits Mvi and Mvit not set, "+pmv.toString(), PMVMatrix.DIRTY_INVERSE_MODELVIEW | PMVMatrix.DIRTY_INVERSE_TRANSPOSED_MODELVIEW, pmv.getRequestMask());
+ MiscUtils.assertFloatBufferEquals("Mvi not identity after update, "+pmv.toString(), ident, mvi, epsilon);
+ MiscUtils.assertFloatBufferEquals("Mvit not identity after update, "+pmv.toString(), ident, mvit, epsilon);
+ }
+
+ /**
+ * Test using shader access workflow, i.e. 1) get-matrix references 2) operations
+ * <p>
+ * The Mvi and Mvit dirty-bits and request-mask will be validated.
+ * </p>
+ */
+ @SuppressWarnings("deprecation")
+ @Test
+ public void test02MviUpdateShaderAccess() {
+ final FloatBuffer p, mv, mvi, mvit;
+ boolean b;
+ final PMVMatrix pmv = new PMVMatrix(true);
+ // System.err.println("P0: "+pmv.toString());
+
+ Assert.assertTrue("Dirty bits clean, "+pmv.toString(), 0 != pmv.getDirtyBits());
+ Assert.assertEquals("Request bits not zero, "+pmv.toString(), 0, pmv.getRequestMask());
+
+ //
+ // Action #0
+ //
+ final FloatBuffer ident;
+ {
+ pmv.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
+ pmv.glLoadIdentity();
+ ident = pmv.glGetPMatrixf();
+
+ pmv.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
+ pmv.glLoadIdentity();
+ }
+ // System.err.println("P0: "+pmv.toString());
+ Assert.assertTrue("Modified bits zero", 0 != pmv.getModifiedBits(true)); // clear & test
+ Assert.assertTrue("Dirty bits clean, "+pmv.toString(), 0 != pmv.getDirtyBits());
+ Assert.assertEquals("Request bits not zero, "+pmv.toString(), 0, pmv.getRequestMask());
+ // System.err.println("P1: "+pmv.toString());
+
+ //
+ // Get
+ //
+ p = pmv.glGetPMatrixf();
+ MiscUtils.assertFloatBufferEquals("P not identity, "+pmv.toString(), ident, p, epsilon);
+ mv = pmv.glGetMvMatrixf();
+ MiscUtils.assertFloatBufferEquals("Mv not identity, "+pmv.toString(), ident, mv, epsilon);
+ Assert.assertTrue("Dirty bits clean, "+pmv.toString(), 0 != pmv.getDirtyBits());
+ Assert.assertEquals("Request bits not zero, "+pmv.toString(), 0, pmv.getRequestMask());
+
+ mvi = pmv.glGetMviMatrixf();
+ MiscUtils.assertFloatBufferEquals("Mvi not identity, "+pmv.toString(), ident, mvi, epsilon);
+ Assert.assertEquals("Remaining dirty bits not Mvit, "+pmv.toString(), PMVMatrix.DIRTY_INVERSE_TRANSPOSED_MODELVIEW, pmv.getDirtyBits());
+ Assert.assertEquals("Request bit Mvi not set, "+pmv.toString(), PMVMatrix.DIRTY_INVERSE_MODELVIEW, pmv.getRequestMask());
+
+ mvit = pmv.glGetMvitMatrixf();
+ MiscUtils.assertFloatBufferEquals("Mvi not identity, "+pmv.toString(), ident, mvit, epsilon);
+ Assert.assertTrue("Dirty bits not clean, "+pmv.toString(), 0 == pmv.getDirtyBits());
+ Assert.assertEquals("Request bits Mvi and Mvit not set, "+pmv.toString(), PMVMatrix.DIRTY_INVERSE_MODELVIEW | PMVMatrix.DIRTY_INVERSE_TRANSPOSED_MODELVIEW, pmv.getRequestMask());
+
+ //
+ // Action #1
+ //
+ pmv.glTranslatef(1f, 2f, 3f); // all dirty !
+ Assert.assertTrue("Modified bits zero", 0 != pmv.getModifiedBits(true)); // clear & test
+ Assert.assertTrue("Dirty bits clean, "+pmv.toString(), 0 != pmv.getDirtyBits());
+ MiscUtils.assertFloatBufferEquals("P not identity, "+pmv.toString()+pmv.toString(), ident, p, epsilon);
+ MiscUtils.assertFloatBufferEquals("Mv not translated123, "+pmv.toString()+pmv.toString(), translated123C, mv, epsilon);
+ MiscUtils.assertFloatBufferNotEqual("Mvi already translated123 w/o update, "+pmv.toString()+pmv.toString(), translated123I, mvi, epsilon);
+ MiscUtils.assertFloatBufferNotEqual("Mvit already translated123 w/o update, "+pmv.toString()+pmv.toString(), translated123IT, mvit, epsilon);
+ MiscUtils.assertFloatBufferEquals("Mvi not identity, "+pmv.toString()+pmv.toString(), ident, mvi, epsilon);
+ MiscUtils.assertFloatBufferEquals("Mvit not identity, "+pmv.toString()+pmv.toString(), ident, mvit, epsilon);
+
+ b = pmv.update(); // will clean dirty bits, since all requests has been made -> true
+ Assert.assertEquals("Update has not been perfomed, but requested", true, b);
+ Assert.assertTrue("Dirty bits not clean, "+pmv.toString(), 0 == pmv.getDirtyBits());
+ Assert.assertEquals("Request bits Mvi and Mvit not set, "+pmv.toString(), PMVMatrix.DIRTY_INVERSE_MODELVIEW | PMVMatrix.DIRTY_INVERSE_TRANSPOSED_MODELVIEW, pmv.getRequestMask());
+ MiscUtils.assertFloatBufferEquals("Mvi not translated123, "+pmv.toString()+pmv.toString(), translated123I, mvi, epsilon);
+ MiscUtils.assertFloatBufferEquals("Mvit not translated123, "+pmv.toString()+pmv.toString(), translated123IT, mvit, epsilon);
+ // System.err.println("P2: "+pmv.toString());
+ }
+
+ @SuppressWarnings("unused")
+ @Test
+ public void test03MvTranslate() {
+ final FloatBuffer pmvMv, pmvMvi, pmvMvit;
+ {
+ final PMVMatrix pmv = new PMVMatrix(true);
+ pmv.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
+ pmv.glLoadIdentity();
+ pmv.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
+ pmv.glLoadIdentity();
+ pmv.glTranslatef(5f, 6f, 7f);
+
+ pmvMv = pmv.glGetMvMatrixf();
+ pmvMvi = pmv.glGetMviMatrixf();
+ pmvMvit = pmv.glGetMvitMatrixf();
+ }
+
+ final FloatBuffer glMv = FloatBuffer.allocate(16);
+ {
+ GL2ES1 gl = dc.glc.getGL().getGL2ES1();
+ gl.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
+ gl.glLoadIdentity();
+ gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
+ gl.glLoadIdentity();
+ gl.glTranslatef(5f, 6f, 7f);
+
+ gl.glGetFloatv(GLMatrixFunc.GL_MODELVIEW_MATRIX, glMv);
+ }
+ // System.err.println(PMVMatrix.matrixToString(null, "%10.5f", glMv, pmvMv).toString());
+
+ MiscUtils.assertFloatBufferEquals("Arrays not equal, expected"+Platform.NEWLINE+PMVMatrix.matrixToString(null, "%10.5f", glMv).toString()+
+ ", actual"+Platform.NEWLINE+PMVMatrix.matrixToString(null, "%10.5f", pmvMv).toString(),
+ glMv, pmvMv, epsilon);
+
+ // System.err.println("pmvMvi: "+Platform.NEWLINE+PMVMatrix.matrixToString(null, "%10.5f", pmvMvi));
+ // System.err.println("pmvMvit: "+Platform.NEWLINE+PMVMatrix.matrixToString(null, "%10.5f", pmvMvit));
+ }
+
+ @SuppressWarnings("unused")
+ @Test
+ public void test04MvTranslateRotate() {
+ final FloatBuffer pmvMv, pmvMvi, pmvMvit;
+ {
+ final PMVMatrix pmv = new PMVMatrix(true);
+ pmv.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
+ pmv.glLoadIdentity();
+ pmv.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
+ pmv.glLoadIdentity();
+ pmv.glTranslatef(5f, 6f, 7f);
+ pmv.glRotatef(90f, 1f, 0f, 0f);
+
+ pmvMv = pmv.glGetMvMatrixf();
+ pmvMvi = pmv.glGetMviMatrixf();
+ pmvMvit = pmv.glGetMvitMatrixf();
+ }
+
+ final FloatBuffer glMv = FloatBuffer.allocate(16);
+ {
+ GL2ES1 gl = dc.glc.getGL().getGL2ES1();
+ gl.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
+ gl.glLoadIdentity();
+ gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
+ gl.glLoadIdentity();
+ gl.glTranslatef(5f, 6f, 7f);
+ gl.glRotatef(90f, 1f, 0f, 0f);
+
+ gl.glGetFloatv(GLMatrixFunc.GL_MODELVIEW_MATRIX, glMv);
+ }
+ // System.err.println(PMVMatrix.matrixToString(null, "%10.5f", glMv, pmvMv).toString());
+
+ MiscUtils.assertFloatBufferEquals("Arrays not equal, expected"+Platform.NEWLINE+PMVMatrix.matrixToString(null, "%10.5f", glMv).toString()+
+ ", actual"+Platform.NEWLINE+PMVMatrix.matrixToString(null, "%10.5f", pmvMv).toString(),
+ glMv, pmvMv, epsilon);
+
+ // System.err.println("pmvMvi: "+Platform.NEWLINE+PMVMatrix.matrixToString(null, "%10.5f", pmvMvi));
+ // System.err.println("pmvMvit: "+Platform.NEWLINE+PMVMatrix.matrixToString(null, "%10.5f", pmvMvit));
+ }
+
+ static DrawableContext dc;
+
+ @BeforeClass
+ public static void setup() throws Throwable {
+ try {
+ dc = createOffscreenDrawableAndCurrentFFPContext();
+ } catch (Throwable t) {
+ setTestSupported(false);
+ throw t;
+ }
+ }
+
+ @AfterClass
+ public static void cleanup() {
+ destroyDrawableContext(dc);
+ }
+
+ static class DrawableContext {
+ DrawableContext(GLDrawable d, GLContext glc) {
+ this.d = d;
+ this.glc = glc;
+ }
+ GLDrawable d;
+ GLContext glc;
+ }
+
+ private static DrawableContext createOffscreenDrawableAndCurrentFFPContext() throws Throwable {
+ GLProfile glp = GLProfile.getMaxFixedFunc(true);
+ GLCapabilities glCaps = new GLCapabilities(glp);
+ glCaps.setOnscreen(false);
+ glCaps.setPBuffer(true);
+ GLDrawableFactory factory = GLDrawableFactory.getFactory(glp);
+ GLDrawable d = factory.createOffscreenDrawable(null, glCaps, null, 64, 64);
+ d.setRealized(true);
+ GLContext glc = null;
+ try {
+ glc = d.createContext(null);
+ Assert.assertTrue("Context could not be made current", GLContext.CONTEXT_NOT_CURRENT < glc.makeCurrent());
+ return new DrawableContext(d, glc);
+ } catch (Throwable t) {
+ if(null != glc) {
+ glc.destroy();
+ }
+ d.setRealized(false);
+ throw t;
+ }
+ }
+
+ private static void destroyDrawableContext(DrawableContext dc) {
+ if(null != dc.glc) {
+ dc.glc.destroy();
+ dc.glc = null;
+ }
+ if(null != dc.d) {
+ dc.d.setRealized(false);
+ dc.d = null;
+ }
+ }
+
+ public static void main(String args[]) {
+ org.junit.runner.JUnitCore.main(TestPMVMatrix01NEWT.class.getName());
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestPMVMatrix02NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestPMVMatrix02NEWT.java
new file mode 100644
index 0000000..4e959d4
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestPMVMatrix02NEWT.java
@@ -0,0 +1,109 @@
+/**
+ * Copyright 2012 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community OR
+ * CONTRIBUTORS 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.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.opengl.test.junit.jogl.acore;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import com.jogamp.opengl.util.PMVMatrix;
+
+import javax.media.opengl.fixedfunc.GLMatrixFunc;
+import java.nio.FloatBuffer;
+
+import static org.junit.Assert.assertArrayEquals;
+
+/**
+ * @author Thomas De Bodt
+ */
+public class TestPMVMatrix02NEWT {
+
+ private PMVMatrix fMat;
+
+ @Before
+ public void setUp() throws Exception {
+ fMat = new PMVMatrix();
+ }
+
+ @Test
+ public void testLookAtNegZIsNoOp() throws Exception {
+ fMat.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
+ // Look towards -z
+ fMat.gluLookAt(
+ 0, 0, 0,
+ 0, 0, -1,
+ 0, 1, 0
+ );
+ FloatBuffer mvMatrix = fMat.glGetMvMatrixf();
+ float[] mvMatrixArr = new float[16];
+ mvMatrix.asReadOnlyBuffer().get(mvMatrixArr);
+ assertArrayEquals(
+ /**
+ * The 3 rows of the matrix (= the 3 columns of the array/buffer) should be: side, up, -forward.
+ */
+ new float[] {
+ 1, 0, 0, 0,
+ 0, 1, 0, 0,
+ 0, 0, 1, 0,
+ 0, 0, 0, 1
+ },
+ mvMatrixArr,
+ 1e-6f
+ );
+ }
+ @Test
+ public void testLookAtPosY() throws Exception {
+ fMat.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
+ // Look towards +y
+ fMat.gluLookAt(
+ 0, 0, 0,
+ 0, 1, 0,
+ 0, 0, 1
+ );
+ FloatBuffer mvMatrix = fMat.glGetMvMatrixf();
+ float[] mvMatrixArr = new float[16];
+ mvMatrix.asReadOnlyBuffer().get(mvMatrixArr);
+ assertArrayEquals(
+ /**
+ * The 3 rows of the matrix (= the 3 columns of the array/buffer) should be: side, up, -forward.
+ */
+ new float[] {
+ 1, 0, 0, 0,
+ 0, 0, -1, 0,
+ 0, 1, 0, 0,
+ 0, 0, 0, 1
+ },
+ mvMatrixArr,
+ 1e-6f
+ );
+ }
+
+ public static void main(String args[]) {
+ org.junit.runner.JUnitCore.main(TestPMVMatrix02NEWT.class.getName());
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestPointsNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestPointsNEWT.java
new file mode 100644
index 0000000..0ac75d4
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestPointsNEWT.java
@@ -0,0 +1,156 @@
+/**
+ * Copyright 2011 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community OR
+ * CONTRIBUTORS 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.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.opengl.test.junit.jogl.acore;
+
+import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+
+import com.jogamp.opengl.test.junit.jogl.demos.PointsDemo;
+import com.jogamp.opengl.test.junit.jogl.demos.es1.PointsDemoES1;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.PointsDemoES2;
+
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLProfile;
+
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.AfterClass;
+import org.junit.Test;
+
+public class TestPointsNEWT extends UITestCase {
+ static int width, height;
+
+ @BeforeClass
+ public static void initClass() {
+ width = 512;
+ height = 512;
+ }
+
+ @AfterClass
+ public static void releaseClass() {
+ }
+
+ protected void runTestGL0(GLCapabilities caps, PointsDemo demo) throws InterruptedException {
+ GLWindow glWindow = GLWindow.create(caps);
+ Assert.assertNotNull(glWindow);
+ glWindow.setTitle(getSimpleTestName("."));
+
+ glWindow.addGLEventListener(demo);
+ final SnapshotGLEventListener snap = new SnapshotGLEventListener();
+ snap.setPostSNDetail(demo.getClass().getSimpleName());
+ glWindow.addGLEventListener(snap);
+
+ glWindow.setSize(width, height);
+ glWindow.setVisible(true);
+
+ demo.setSmoothPoints(false);
+ snap.setMakeSnapshot();
+ snap.setPostSNDetail("flat");
+ glWindow.display();
+
+ demo.setSmoothPoints(true);
+ snap.setMakeSnapshot();
+ snap.setPostSNDetail("smooth");
+ glWindow.display();
+
+ demo.setPointParams(2f, 40f, 0.01f, 0.0f, 0.01f, 1f);
+ snap.setMakeSnapshot();
+ snap.setPostSNDetail("attn0");
+ glWindow.display();
+
+ glWindow.removeGLEventListener(demo);
+
+ glWindow.destroy();
+ }
+
+ protected void runTestGL(GLCapabilities caps, PointsDemo demo, boolean forceFFPEmu) throws InterruptedException {
+ // final PointsDemoES2 demo01 = new PointsDemoES2();
+ runTestGL0(caps, demo);
+ }
+
+ @Test
+ public void test01FFP__GL2() throws InterruptedException {
+ if(!GLProfile.isAvailable(GLProfile.GL2)) { System.err.println("GL2 n/a"); return; }
+ GLCapabilities caps = new GLCapabilities(GLProfile.get(GLProfile.GL2));
+ runTestGL(caps, new PointsDemoES1(), false);
+ }
+
+ @Test
+ public void test02FFP__ES1() throws InterruptedException {
+ if(!GLProfile.isAvailable(GLProfile.GLES1)) { System.err.println("GLES1 n/a"); return; }
+ GLCapabilities caps = new GLCapabilities(GLProfile.get(GLProfile.GLES1));
+ runTestGL(caps, new PointsDemoES1(), false);
+ }
+
+ @Test
+ public void test03FFP__ES2() throws InterruptedException {
+ if(!GLProfile.isAvailable(GLProfile.GLES2)) { System.err.println("GLES2 n/a"); return; }
+ GLCapabilities caps = new GLCapabilities(GLProfile.get(GLProfile.GLES2));
+ PointsDemoES1 demo = new PointsDemoES1();
+ demo.setForceFFPEmu(true, false, false, false);
+ runTestGL(caps, demo, false);
+ }
+
+ @Test
+ public void test04FFP__GL2ES2() throws InterruptedException {
+ if(!GLProfile.isAvailable(GLProfile.GL2ES2)) { System.err.println("GL2ES2 n/a"); return; }
+ GLCapabilities caps = new GLCapabilities(GLProfile.get(GLProfile.GL2ES2));
+ PointsDemoES1 demo = new PointsDemoES1();
+ demo.setForceFFPEmu(true, false, false, false);
+ runTestGL(caps, demo, false);
+ }
+
+ @Test
+ public void test11GLSL_GL2() throws InterruptedException {
+ if(!GLProfile.isAvailable(GLProfile.GL2)) { System.err.println("GL2 n/a"); return; }
+ GLCapabilities caps = new GLCapabilities(GLProfile.get(GLProfile.GL2));
+ runTestGL(caps, new PointsDemoES2(), false);
+ }
+
+ @Test
+ public void test12GLSL_ES2() throws InterruptedException {
+ if(!GLProfile.isAvailable(GLProfile.GLES2)) { System.err.println("GLES2 n/a"); return; }
+ GLCapabilities caps = new GLCapabilities(GLProfile.get(GLProfile.GLES2));
+ runTestGL(caps, new PointsDemoES2(), false); // should be FFPEmu implicit
+ }
+
+ static long duration = 1000; // ms
+
+ public static void main(String args[]) {
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-time")) {
+ i++;
+ try {
+ duration = Integer.parseInt(args[i]);
+ } catch (Exception ex) { ex.printStackTrace(); }
+ }
+ }
+ org.junit.runner.JUnitCore.main(TestPointsNEWT.class.getName());
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListAWT.java
index 60502ba..67b70e1 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListAWT.java
@@ -30,11 +30,10 @@ package com.jogamp.opengl.test.junit.jogl.acore;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLDrawableFactory;
-import javax.media.opengl.GLPbuffer;
+import javax.media.opengl.GLOffscreenAutoDrawable;
import javax.media.opengl.GLProfile;
import javax.media.opengl.awt.GLCanvas;
-import com.jogamp.common.os.Platform;
import com.jogamp.opengl.util.Animator;
import com.jogamp.opengl.test.junit.util.UITestCase;
@@ -53,17 +52,11 @@ public class TestSharedContextListAWT extends UITestCase {
static GLProfile glp;
static GLCapabilities caps;
static int width, height;
- GLPbuffer sharedDrawable;
+ GLOffscreenAutoDrawable sharedDrawable;
Gears sharedGears;
@BeforeClass
public static void initClass() {
- if(Platform.CPUFamily.X86 != Platform.CPU_ARCH.family) { // FIXME
- // FIXME: Turns out on some mobile GL drivers and platforms
- // using shared context is instable, Linux ARM (Omap4, Tegra2, Mesa3d, ..)
- setTestSupported(false);
- return;
- }
if(GLProfile.isAvailable(GLProfile.GL2)) {
glp = GLProfile.get(GLProfile.GL2);
Assert.assertNotNull(glp);
@@ -77,7 +70,7 @@ public class TestSharedContextListAWT extends UITestCase {
}
private void initShared() {
- sharedDrawable = GLDrawableFactory.getFactory(glp).createGLPbuffer(null, caps, null, width, height, null);
+ sharedDrawable = GLDrawableFactory.getFactory(glp).createOffscreenAutoDrawable(null, caps, null, width, height, null);
Assert.assertNotNull(sharedDrawable);
sharedGears = new Gears();
Assert.assertNotNull(sharedGears);
@@ -159,10 +152,6 @@ public class TestSharedContextListAWT extends UITestCase {
}
animator.stop();
- // here we go again: On AMD/X11 the create/destroy sequence must be the same
- // even though this is agains the chicken/egg logic
- releaseShared();
-
try {
javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
@@ -182,8 +171,7 @@ public class TestSharedContextListAWT extends UITestCase {
Assume.assumeNoException( throwable );
}
- // see above ..
- //releaseShared();
+ releaseShared();
}
static long duration = 500; // ms
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListNEWT.java
index 39367d1..78c8fd0 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListNEWT.java
@@ -30,13 +30,12 @@ package com.jogamp.opengl.test.junit.jogl.acore;
import java.io.IOException;
-import com.jogamp.common.os.Platform;
import com.jogamp.newt.opengl.GLWindow;
import javax.media.nativewindow.util.InsetsImmutable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLDrawableFactory;
-import javax.media.opengl.GLPbuffer;
+import javax.media.opengl.GLOffscreenAutoDrawable;
import javax.media.opengl.GLProfile;
import com.jogamp.opengl.util.Animator;
@@ -52,17 +51,11 @@ public class TestSharedContextListNEWT extends UITestCase {
static GLProfile glp;
static GLCapabilities caps;
static int width, height;
- GLPbuffer sharedDrawable;
+ GLOffscreenAutoDrawable sharedDrawable;
Gears sharedGears;
@BeforeClass
public static void initClass() {
- if(Platform.CPUFamily.X86 != Platform.CPU_ARCH.family) { // FIXME
- // FIXME: Turns out on some mobile GL drivers and platforms
- // using shared context is instable, Linux ARM (Omap4, Tegra2, Mesa3d, ..)
- setTestSupported(false);
- return;
- }
if(GLProfile.isAvailable(GLProfile.GL2)) {
glp = GLProfile.get(GLProfile.GL2);
Assert.assertNotNull(glp);
@@ -76,7 +69,7 @@ public class TestSharedContextListNEWT extends UITestCase {
}
private void initShared() {
- sharedDrawable = GLDrawableFactory.getFactory(glp).createGLPbuffer(null, caps, null, width, height, null);
+ sharedDrawable = GLDrawableFactory.getFactory(glp).createOffscreenAutoDrawable(null, caps, null, width, height, null);
Assert.assertNotNull(sharedDrawable);
sharedGears = new Gears();
Assert.assertNotNull(sharedGears);
@@ -134,16 +127,11 @@ public class TestSharedContextListNEWT extends UITestCase {
}
animator.stop();
- // here we go again: On AMD/X11 the create/destroy sequence must be the same
- // even though this is against the chicken/egg logic here ..
- releaseShared();
-
f1.destroy();
f2.destroy();
f3.destroy();
- // see above ..
- // releaseShared();
+ releaseShared();
}
static long duration = 500; // ms
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListNEWT2.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListNEWT2.java
index 7dca314..7893c51 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListNEWT2.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListNEWT2.java
@@ -30,7 +30,6 @@ package com.jogamp.opengl.test.junit.jogl.acore;
import java.io.IOException;
-import com.jogamp.common.os.Platform;
import com.jogamp.newt.opengl.GLWindow;
import javax.media.nativewindow.util.InsetsImmutable;
@@ -55,12 +54,6 @@ public class TestSharedContextListNEWT2 extends UITestCase {
@BeforeClass
public static void initClass() {
- if(Platform.CPUFamily.X86 != Platform.CPU_ARCH.family) { // FIXME
- // FIXME: Turns out on some mobile GL drivers and platforms
- // using shared context is instable, Linux ARM (Omap4, Tegra2, Mesa3d, ..)
- setTestSupported(false);
- return;
- }
if(GLProfile.isAvailable(GLProfile.GL2)) {
glp = GLProfile.get(GLProfile.GL2);
Assert.assertNotNull(glp);
@@ -135,16 +128,11 @@ public class TestSharedContextListNEWT2 extends UITestCase {
e.printStackTrace();
}
- // here we go again: On AMD/X11 the create/destroy sequence must be the same
- // even though this is against the chicken/egg logic here ..
- releaseShared();
-
f1.destroy();
f2.destroy();
f3.destroy();
- // see above ..
- // releaseShared();
+ releaseShared();
}
static long duration = 2000; // ms
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextNewtAWTBug523.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextNewtAWTBug523.java
index bc2eddb..7894f3e 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextNewtAWTBug523.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextNewtAWTBug523.java
@@ -45,7 +45,7 @@ import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLEventListener;
-import javax.media.opengl.GLPbuffer;
+import javax.media.opengl.GLOffscreenAutoDrawable;
import javax.media.opengl.GLProfile;
import javax.media.opengl.awt.GLCanvas;
import javax.media.opengl.glu.GLU;
@@ -64,7 +64,6 @@ import org.junit.BeforeClass;
import org.junit.Test;
import com.jogamp.common.nio.Buffers;
-import com.jogamp.common.os.Platform;
import com.jogamp.newt.awt.NewtCanvasAWT;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
@@ -118,26 +117,20 @@ public class TestSharedContextNewtAWTBug523 extends UITestCase {
@BeforeClass
public static void initClass() {
- if(Platform.CPUFamily.X86 != Platform.CPU_ARCH.family) { // FIXME
- // FIXME: Turns out on some mobile GL drivers and platforms
- // using shared context is instable, Linux ARM (Omap4, Tegra2, Mesa3d, ..)
- setTestSupported(false);
- return;
- }
if(!GLProfile.isAvailable(GLProfile.GL2)) {
setTestSupported(false);
}
}
- static private GLPbuffer initShared(GLCapabilities caps) {
- GLPbuffer sharedDrawable = GLDrawableFactory.getFactory(caps.getGLProfile()).createGLPbuffer(null, caps, null, 64, 64, null);
+ static private GLOffscreenAutoDrawable initShared(GLCapabilities caps) {
+ final GLOffscreenAutoDrawable sharedDrawable = GLDrawableFactory.getFactory(caps.getGLProfile()).createOffscreenAutoDrawable(null, caps, null, 64, 64, null);
Assert.assertNotNull(sharedDrawable);
// init and render one frame, which will setup the Gears display lists
sharedDrawable.display();
return sharedDrawable;
}
- static private void releaseShared(GLPbuffer sharedDrawable) {
+ static private void releaseShared(GLOffscreenAutoDrawable sharedDrawable) {
if(null != sharedDrawable) {
sharedDrawable.destroy();
}
@@ -522,7 +515,7 @@ public class TestSharedContextNewtAWTBug523 extends UITestCase {
glCapabilities.setSampleBuffers(true);
glCapabilities.setNumSamples(4);
- final GLPbuffer sharedDrawable;
+ final GLOffscreenAutoDrawable sharedDrawable;
final GLContext sharedContext;
if(shareContext) {
sharedDrawable = initShared(glCapabilities);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES1NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES1NEWT.java
index 707bd5a..6f108d8 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES1NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES1NEWT.java
@@ -28,13 +28,12 @@
package com.jogamp.opengl.test.junit.jogl.acore;
-import com.jogamp.common.os.Platform;
import com.jogamp.newt.opengl.GLWindow;
import javax.media.nativewindow.util.InsetsImmutable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLDrawableFactory;
-import javax.media.opengl.GLPbuffer;
+import javax.media.opengl.GLOffscreenAutoDrawable;
import javax.media.opengl.GLProfile;
import com.jogamp.opengl.util.Animator;
@@ -50,17 +49,11 @@ public class TestSharedContextVBOES1NEWT extends UITestCase {
static GLProfile glp;
static GLCapabilities caps;
static int width, height;
- GLPbuffer sharedDrawable;
+ GLOffscreenAutoDrawable sharedDrawable;
GearsES1 sharedGears;
@BeforeClass
public static void initClass() {
- if(Platform.CPUFamily.X86 != Platform.CPU_ARCH.family) { // FIXME
- // FIXME: Turns out on some mobile GL drivers and platforms
- // using shared context is instable, Linux ARM (Omap4, Tegra2, Mesa3d, ..)
- setTestSupported(false);
- return;
- }
if(GLProfile.isAvailable(GLProfile.GL2ES1)) {
glp = GLProfile.get(GLProfile.GL2ES1);
Assert.assertNotNull(glp);
@@ -74,7 +67,7 @@ public class TestSharedContextVBOES1NEWT extends UITestCase {
}
private void initShared() {
- sharedDrawable = GLDrawableFactory.getFactory(glp).createGLPbuffer(null, caps, null, width, height, null);
+ sharedDrawable = GLDrawableFactory.getFactory(glp).createOffscreenAutoDrawable(null, caps, null, width, height, null);
Assert.assertNotNull(sharedDrawable);
sharedGears = new GearsES1();
Assert.assertNotNull(sharedGears);
@@ -132,16 +125,11 @@ public class TestSharedContextVBOES1NEWT extends UITestCase {
}
animator.stop();
- // here we go again: On AMD/X11 the create/destroy sequence must be the same
- // even though this is agains the chicken/egg logic here ..
- releaseShared();
-
f1.destroy();
f2.destroy();
f3.destroy();
- // see above ..
- // releaseShared();
+ releaseShared();
}
static long duration = 500; // ms
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES2NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES2NEWT.java
index ce2bd77..4aa977a 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES2NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES2NEWT.java
@@ -29,12 +29,13 @@
package com.jogamp.opengl.test.junit.jogl.acore;
import com.jogamp.common.os.Platform;
+import com.jogamp.common.util.VersionNumber;
import com.jogamp.newt.opengl.GLWindow;
import javax.media.nativewindow.util.InsetsImmutable;
+import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLDrawableFactory;
-import javax.media.opengl.GLPbuffer;
import javax.media.opengl.GLProfile;
import com.jogamp.opengl.util.Animator;
@@ -50,17 +51,11 @@ public class TestSharedContextVBOES2NEWT extends UITestCase {
static GLProfile glp;
static GLCapabilities caps;
static int width, height;
- GLPbuffer sharedDrawable;
+ GLAutoDrawable sharedDrawable;
GearsES2 sharedGears;
@BeforeClass
public static void initClass() {
- if(Platform.CPUFamily.X86 != Platform.CPU_ARCH.family) { // FIXME
- // FIXME: Turns out on some mobile GL drivers and platforms
- // using shared context is instable, Linux ARM (Omap4, Tegra2, Mesa3d, ..)
- setTestSupported(false);
- return;
- }
if(GLProfile.isAvailable(GLProfile.GL2ES2)) {
glp = GLProfile.get(GLProfile.GL2ES2);
Assert.assertNotNull(glp);
@@ -73,8 +68,16 @@ public class TestSharedContextVBOES2NEWT extends UITestCase {
}
}
- private void initShared() {
- sharedDrawable = GLDrawableFactory.getFactory(glp).createGLPbuffer(null, caps, null, width, height, null);
+ private void initShared(boolean onscreen) {
+ if(onscreen) {
+ GLWindow glWindow = GLWindow.create(caps);
+ Assert.assertNotNull(glWindow);
+ glWindow.setSize(width, height);
+ glWindow.setVisible(true);
+ sharedDrawable = glWindow;
+ } else {
+ sharedDrawable = GLDrawableFactory.getFactory(glp).createOffscreenAutoDrawable(null, caps, null, width, height, null);
+ }
Assert.assertNotNull(sharedDrawable);
sharedGears = new GearsES2();
Assert.assertNotNull(sharedGears);
@@ -86,6 +89,7 @@ public class TestSharedContextVBOES2NEWT extends UITestCase {
private void releaseShared() {
Assert.assertNotNull(sharedDrawable);
sharedDrawable.destroy();
+ sharedDrawable = null;
}
protected GLWindow runTestGL(Animator animator, int x, int y, boolean useShared, boolean vsync) throws InterruptedException {
@@ -93,7 +97,7 @@ public class TestSharedContextVBOES2NEWT extends UITestCase {
Assert.assertNotNull(glWindow);
glWindow.setTitle("Shared Gears NEWT Test: "+x+"/"+y+" shared "+useShared);
if(useShared) {
- glWindow.setSharedContext(sharedDrawable.getContext());
+ glWindow.setSharedContext(sharedDrawable.getContext());
}
glWindow.setSize(width, height);
@@ -105,46 +109,120 @@ public class TestSharedContextVBOES2NEWT extends UITestCase {
glWindow.addGLEventListener(gears);
animator.add(glWindow);
-
+ animator.start();
glWindow.setVisible(true);
Assert.assertTrue(AWTRobotUtil.waitForRealized(glWindow, true));
Assert.assertTrue(AWTRobotUtil.waitForVisible(glWindow, true));
-
+
glWindow.setPosition(x, y);
return glWindow;
}
@Test
- public void test01() throws InterruptedException {
- initShared();
+ public void testCommonAnimatorSharedOnscreen() throws InterruptedException {
+ initShared(true);
Animator animator = new Animator();
GLWindow f1 = runTestGL(animator, 0, 0, true, false);
InsetsImmutable insets = f1.getInsets();
GLWindow f2 = runTestGL(animator, f1.getX()+width+insets.getTotalWidth(),
f1.getY()+0, true, false);
GLWindow f3 = runTestGL(animator, f1.getX()+0,
- f1.getY()+height+insets.getTotalHeight(), false, true);
- animator.setUpdateFPSFrames(1, null);
- animator.start();
- while(animator.isAnimating() && animator.getTotalFPSDuration()<duration) {
- Thread.sleep(100);
+ f1.getY()+height+insets.getTotalHeight(), true, false);
+ try {
+ Thread.sleep(duration);
+ } catch(Exception e) {
+ e.printStackTrace();
}
animator.stop();
- // here we go again: On AMD/X11 the create/destroy sequence must be the same
- // even though this is agains the chicken/egg logic here ..
+ f1.destroy();
+ f2.destroy();
+ f3.destroy();
+ Assert.assertTrue(AWTRobotUtil.waitForVisible(f1, false));
+ Assert.assertTrue(AWTRobotUtil.waitForRealized(f1, false));
+ Assert.assertTrue(AWTRobotUtil.waitForVisible(f2, false));
+ Assert.assertTrue(AWTRobotUtil.waitForRealized(f2, false));
+ Assert.assertTrue(AWTRobotUtil.waitForVisible(f3, false));
+ Assert.assertTrue(AWTRobotUtil.waitForRealized(f3, false));
+
releaseShared();
+ }
+
+ @Test
+ public void testCommonAnimatorSharedOffscreen() throws InterruptedException {
+ initShared(false);
+ Animator animator = new Animator();
+ GLWindow f1 = runTestGL(animator, 0, 0, true, false);
+ InsetsImmutable insets = f1.getInsets();
+ GLWindow f2 = runTestGL(animator, f1.getX()+width+insets.getTotalWidth(),
+ f1.getY()+0, true, false);
+ GLWindow f3 = runTestGL(animator, f1.getX()+0,
+ f1.getY()+height+insets.getTotalHeight(), true, false);
+ try {
+ Thread.sleep(duration);
+ } catch(Exception e) {
+ e.printStackTrace();
+ }
+ animator.stop();
f1.destroy();
f2.destroy();
f3.destroy();
+ Assert.assertTrue(AWTRobotUtil.waitForVisible(f1, false));
+ Assert.assertTrue(AWTRobotUtil.waitForRealized(f1, false));
+ Assert.assertTrue(AWTRobotUtil.waitForVisible(f2, false));
+ Assert.assertTrue(AWTRobotUtil.waitForRealized(f2, false));
+ Assert.assertTrue(AWTRobotUtil.waitForVisible(f3, false));
+ Assert.assertTrue(AWTRobotUtil.waitForRealized(f3, false));
- // see above ..
- // releaseShared();
+ releaseShared();
}
+
+ @Test
+ public void testEachWithAnimatorSharedOffscreen() throws InterruptedException {
+ VersionNumber osx1070 = new VersionNumber(10,7,0);
+ if( Platform.getOSType() == Platform.OSType.MACOS && Platform.getOSVersionNumber().compareTo(osx1070) > 0 ) {
+ // instable on OSX .. driver/OS bug when multi threading (3 animator)
+ System.err.println("Shared context w/ 3 context each running in there own thread is instable here on OSX 10.7.4/NVidia,");
+ System.err.println("SIGSEGV @ glDrawArrays / glBindBuffer .. any shared VBO.");
+ System.err.println("Seems to run fine on 10.6.8/NVidia.");
+ return;
+ }
+ initShared(false);
+ Animator animator1 = new Animator();
+ Animator animator2 = new Animator();
+ Animator animator3 = new Animator();
+ GLWindow f1 = runTestGL(animator1, 0, 0, true, false);
+ InsetsImmutable insets = f1.getInsets();
+ GLWindow f2 = runTestGL(animator2, f1.getX()+width+insets.getTotalWidth(),
+ f1.getY()+0, true, false);
+ GLWindow f3 = runTestGL(animator3, f1.getX()+0,
+ f1.getY()+height+insets.getTotalHeight(), true, false);
+
+ try {
+ Thread.sleep(duration);
+ } catch(Exception e) {
+ e.printStackTrace();
+ }
+ animator1.stop();
+ animator2.stop();
+ animator3.stop();
+
+ f1.destroy();
+ f2.destroy();
+ f3.destroy();
+ Assert.assertTrue(AWTRobotUtil.waitForVisible(f1, false));
+ Assert.assertTrue(AWTRobotUtil.waitForRealized(f1, false));
+ Assert.assertTrue(AWTRobotUtil.waitForVisible(f2, false));
+ Assert.assertTrue(AWTRobotUtil.waitForRealized(f2, false));
+ Assert.assertTrue(AWTRobotUtil.waitForVisible(f3, false));
+ Assert.assertTrue(AWTRobotUtil.waitForRealized(f3, false));
- static long duration = 500; // ms
+ releaseShared();
+ }
+
+ static long duration = 2000; // ms
public static void main(String args[]) {
for(int i=0; i<args.length; i++) {
@@ -155,6 +233,10 @@ public class TestSharedContextVBOES2NEWT extends UITestCase {
} catch (Exception ex) { ex.printStackTrace(); }
}
}
+ /**
+ BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
+ System.err.println("Press enter to continue");
+ System.err.println(stdin.readLine()); */
org.junit.runner.JUnitCore.main(TestSharedContextVBOES2NEWT.class.getName());
}
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES2NEWT2.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES2NEWT2.java
deleted file mode 100644
index 8911e73..0000000
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES2NEWT2.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/**
- * Copyright 2010 JogAmp Community. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are
- * permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- *
- * 2. 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.
- *
- * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community OR
- * CONTRIBUTORS 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.
- *
- * The views and conclusions contained in the software and documentation are those of the
- * authors and should not be interpreted as representing official policies, either expressed
- * or implied, of JogAmp Community.
- */
-
-package com.jogamp.opengl.test.junit.jogl.acore;
-
-import java.io.IOException;
-
-import com.jogamp.common.os.Platform;
-import com.jogamp.newt.opengl.GLWindow;
-
-import javax.media.nativewindow.util.InsetsImmutable;
-import javax.media.opengl.GLCapabilities;
-import javax.media.opengl.GLProfile;
-import com.jogamp.opengl.util.Animator;
-
-import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
-import com.jogamp.opengl.test.junit.util.UITestCase;
-import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
-
-import org.junit.Assert;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-public class TestSharedContextVBOES2NEWT2 extends UITestCase {
- static GLProfile glp;
- static GLCapabilities caps;
- static int width, height;
- GLWindow sharedDrawable;
- GearsES2 sharedGears;
-
- @BeforeClass
- public static void initClass() {
- if(Platform.CPUFamily.X86 != Platform.CPU_ARCH.family) { // FIXME
- // FIXME: Turns out on some mobile GL drivers and platforms
- // using shared context is instable, Linux ARM (Omap4, Tegra2, Mesa3d, ..)
- setTestSupported(false);
- return;
- }
- if(GLProfile.isAvailable(GLProfile.GL2ES2)) {
- glp = GLProfile.get(GLProfile.GL2ES2);
- Assert.assertNotNull(glp);
- caps = new GLCapabilities(glp);
- Assert.assertNotNull(caps);
- width = 256;
- height = 256;
- } else {
- setTestSupported(false);
- }
- }
-
- private void initShared() {
- sharedDrawable = GLWindow.create(caps);
- Assert.assertNotNull(sharedDrawable);
- // sharedGears = new Gears(0);
- sharedGears = new GearsES2(0);
- Assert.assertNotNull(sharedGears);
- sharedDrawable.addGLEventListener(sharedGears);
- sharedDrawable.setSize(width, height);
- sharedDrawable.setVisible(true);
- // init and render one frame, which will setup the Gears display lists
- sharedDrawable.display();
- }
-
- private void releaseShared() {
- Assert.assertNotNull(sharedDrawable);
- sharedDrawable.destroy();
- sharedDrawable = null;
- }
-
- protected GLWindow runTestGL(Animator animator, int x, int y, boolean useShared, boolean vsync) throws InterruptedException {
- GLWindow glWindow = GLWindow.create(caps);
-
- Assert.assertNotNull(glWindow);
- glWindow.setTitle("Shared Gears NEWT Test: "+x+"/"+y+" shared "+useShared);
- if(useShared) {
- glWindow.setSharedContext(sharedDrawable.getContext());
- }
-
- glWindow.setSize(width, height);
-
- GearsES2 gears = new GearsES2(vsync ? 1 : 0);
- if(useShared) {
- gears.setGears(sharedGears.getGear1(), sharedGears.getGear2(), sharedGears.getGear3());
- }
- glWindow.addGLEventListener(gears);
-
- animator.add(glWindow);
- animator.start();
- glWindow.setVisible(true);
-
- Assert.assertTrue(AWTRobotUtil.waitForRealized(glWindow, true));
- Assert.assertTrue(AWTRobotUtil.waitForVisible(glWindow, true));
- glWindow.setPosition(x, y);
-
- return glWindow;
- }
-
- @Test
- public void test01() throws InterruptedException {
- initShared();
- GLWindow f1 = runTestGL(new Animator(), 0, 0, true, false);
- InsetsImmutable insets = f1.getInsets();
- GLWindow f2 = runTestGL(new Animator(), f1.getX()+width+insets.getTotalWidth(),
- f1.getY()+0, true, false);
- GLWindow f3 = runTestGL(new Animator(), f1.getX()+0,
- f1.getY()+height+insets.getTotalHeight(), true, false);
-
- try {
- Thread.sleep(duration);
- } catch(Exception e) {
- e.printStackTrace();
- }
-
- // here we go again: On AMD/X11 the create/destroy sequence must be the same
- // even though this is against the chicken/egg logic here ..
- releaseShared();
-
- f1.destroy();
- f2.destroy();
- f3.destroy();
-
- // see above ..
- // releaseShared();
- }
-
- static long duration = 2000; // ms
-
- public static void main(String args[]) throws IOException {
- for(int i=0; i<args.length; i++) {
- if(args[i].equals("-time")) {
- i++;
- try {
- duration = Integer.parseInt(args[i]);
- } catch (Exception ex) { ex.printStackTrace(); }
- }
- }
- /**
- BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
- System.err.println("Press enter to continue");
- System.err.println(stdin.readLine()); */
- org.junit.runner.JUnitCore.main(TestSharedContextVBOES2NEWT2.class.getName());
- }
-}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownCompleteAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownCompleteAWT.java
index 9f2820a..976885d 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownCompleteAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownCompleteAWT.java
@@ -93,12 +93,12 @@ public class TestShutdownCompleteAWT extends UITestCase {
long t1 = System.nanoTime();
runTestGL();
long t2 = System.nanoTime();
- GLProfile.shutdown(GLProfile.ShutdownType.COMPLETE);
+ GLProfile.shutdown();
long t3 = System.nanoTime();
System.err.println("Total: "+ (t3-t0)/1e6 +"ms");
System.err.println(" GLProfile.initSingleton(): "+ (t1-t0)/1e6 +"ms");
System.err.println(" Demo Code: "+ (t2-t1)/1e6 +"ms");
- System.err.println(" GLProfile.shutdown(COMPLETE): "+ (t3-t2)/1e6 +"ms");
+ System.err.println(" GLProfile.shutdown(): "+ (t3-t2)/1e6 +"ms");
}
@Test
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownCompleteNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownCompleteNEWT.java
index b21ad5b..f376cd6 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownCompleteNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownCompleteNEWT.java
@@ -48,8 +48,12 @@ public class TestShutdownCompleteNEWT extends UITestCase {
static long duration = 300; // ms
- protected void runTestGL() throws InterruptedException {
- GLWindow glWindow = GLWindow.create(new GLCapabilities(GLProfile.getGL2ES2()));
+ protected void runTestGL(boolean onscreen) throws InterruptedException {
+ GLCapabilities caps = new GLCapabilities(GLProfile.getGL2ES2());
+ caps.setOnscreen(onscreen);
+ caps.setPBuffer(!onscreen);
+
+ GLWindow glWindow = GLWindow.create(caps);
Assert.assertNotNull(glWindow);
glWindow.setTitle("Gears NEWT Test");
@@ -82,19 +86,19 @@ public class TestShutdownCompleteNEWT extends UITestCase {
GLProfile.initSingleton();
long t1 = System.nanoTime();
if(!initOnly) {
- runTestGL();
+ runTestGL(true);
}
long t2 = System.nanoTime();
if(glInfo) {
System.err.println(JoglVersion.getDefaultOpenGLInfo(null, null, false).toString());
}
long t3 = System.nanoTime();
- GLProfile.shutdown(GLProfile.ShutdownType.COMPLETE);
+ GLProfile.shutdown();
long t4 = System.nanoTime();
System.err.println("Total: "+ (t3-t0)/1e6 +"ms");
System.err.println(" GLProfile.initSingleton(): "+ (t1-t0)/1e6 +"ms");
System.err.println(" Demo Code: "+ (t2-t1)/1e6 +"ms");
- System.err.println(" GLProfile.shutdown(COMPLETE): "+ (t4-t3)/1e6 +"ms");
+ System.err.println(" GLProfile.shutdown(): "+ (t4-t3)/1e6 +"ms");
}
@Test
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownSharedAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownSharedAWT.java
deleted file mode 100644
index 3274ea8..0000000
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownSharedAWT.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/**
- * Copyright 2010 JogAmp Community. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are
- * permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- *
- * 2. 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.
- *
- * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community OR
- * CONTRIBUTORS 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.
- *
- * The views and conclusions contained in the software and documentation are those of the
- * authors and should not be interpreted as representing official policies, either expressed
- * or implied, of JogAmp Community.
- */
-
-package com.jogamp.opengl.test.junit.jogl.acore;
-
-import java.awt.Frame;
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-
-import javax.media.opengl.GLCapabilities;
-import javax.media.opengl.GLProfile;
-import javax.media.opengl.awt.GLCanvas;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
-import com.jogamp.opengl.test.junit.util.UITestCase;
-import com.jogamp.opengl.util.Animator;
-
-public class TestShutdownSharedAWT extends UITestCase {
-
- static long duration = 300; // ms
-
- protected void runTestGL() throws InterruptedException, InvocationTargetException {
- final Frame frame = new Frame("Gears AWT Test");
- Assert.assertNotNull(frame);
-
- final GLCanvas glCanvas = new GLCanvas(new GLCapabilities(GLProfile.getGL2ES2()));
- Assert.assertNotNull(glCanvas);
- frame.add(glCanvas);
- frame.setSize(256, 256);
-
- glCanvas.addGLEventListener(new GearsES2(1));
-
- Animator animator = new Animator(glCanvas);
-
- javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
- public void run() {
- frame.setVisible(true);
- }});
- animator.setUpdateFPSFrames(60, System.err);
- animator.start();
- Assert.assertEquals(true, animator.isAnimating());
- Assert.assertEquals(true, glCanvas.isVisible());
- Assert.assertEquals(true, glCanvas.isDisplayable());
-
- while(animator.isAnimating() && animator.getTotalFPSDuration()<duration) {
- Thread.sleep(100);
- }
- Assert.assertEquals(true, glCanvas.isRealized());
-
- animator.stop();
- Assert.assertEquals(false, animator.isAnimating());
- frame.setVisible(false);
- Assert.assertEquals(false, frame.isVisible());
- javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
- public void run() {
- frame.remove(glCanvas);
- frame.dispose();
- }});
- }
-
- protected void oneLife() throws InterruptedException, InvocationTargetException {
- long t0 = System.nanoTime();
- GLProfile.initSingleton();
- long t1 = System.nanoTime();
- runTestGL();
- long t2 = System.nanoTime();
- GLProfile.shutdown(GLProfile.ShutdownType.SHARED_ONLY);
- long t3 = System.nanoTime();
- System.err.println("Total: "+ (t3-t0)/1e6 +"ms");
- System.err.println(" GLProfile.initSingleton(): "+ (t1-t0)/1e6 +"ms");
- System.err.println(" Demo Code: "+ (t2-t1)/1e6 +"ms");
- System.err.println(" GLProfile.shutdown(SHARED): "+ (t3-t2)/1e6 +"ms");
- }
-
- @Test
- public void test01OneLife() throws InterruptedException, InvocationTargetException {
- oneLife();
- }
-
- @Test
- public void test01AnotherLife() throws InterruptedException, InvocationTargetException {
- oneLife();
- }
-
- @Test
- public void test01TwoLifes() throws InterruptedException, InvocationTargetException {
- oneLife();
- oneLife();
- }
-
- public static void main(String args[]) throws IOException {
- String tstname = TestShutdownSharedAWT.class.getName();
- org.junit.runner.JUnitCore.main(tstname);
- }
-
-}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownSharedNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownSharedNEWT.java
deleted file mode 100644
index 8db7dff..0000000
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownSharedNEWT.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/**
- * Copyright 2010 JogAmp Community. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are
- * permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- *
- * 2. 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.
- *
- * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community OR
- * CONTRIBUTORS 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.
- *
- * The views and conclusions contained in the software and documentation are those of the
- * authors and should not be interpreted as representing official policies, either expressed
- * or implied, of JogAmp Community.
- */
-
-package com.jogamp.opengl.test.junit.jogl.acore;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-
-import javax.media.opengl.GLCapabilities;
-import javax.media.opengl.GLProfile;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-import com.jogamp.newt.opengl.GLWindow;
-import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
-import com.jogamp.opengl.test.junit.util.UITestCase;
-import com.jogamp.opengl.util.Animator;
-
-public class TestShutdownSharedNEWT extends UITestCase {
-
- static long duration = 300; // ms
-
- protected void runTestGL() throws InterruptedException {
- GLWindow glWindow = GLWindow.create(new GLCapabilities(GLProfile.getGL2ES2()));
- Assert.assertNotNull(glWindow);
- glWindow.setTitle("Gears NEWT Test");
-
- glWindow.addGLEventListener(new GearsES2());
-
- Animator animator = new Animator(glWindow);
-
- glWindow.setSize(256, 256);
- glWindow.setVisible(true);
- animator.setUpdateFPSFrames(60, System.err);
- animator.start();
- Assert.assertEquals(true, animator.isAnimating());
- Assert.assertEquals(true, glWindow.isVisible());
- Assert.assertEquals(true, glWindow.isNativeValid());
- Assert.assertEquals(true, glWindow.isRealized());
-
- while(animator.isAnimating() && animator.getTotalFPSDuration()<duration) {
- Thread.sleep(100);
- }
-
- animator.stop();
- glWindow.destroy();
- }
-
- protected void oneLife() throws InterruptedException {
- long t0 = System.nanoTime();
- GLProfile.initSingleton();
- long t1 = System.nanoTime();
- runTestGL();
- long t2 = System.nanoTime();
- GLProfile.shutdown(GLProfile.ShutdownType.SHARED_ONLY);
- long t3 = System.nanoTime();
- System.err.println("Total: "+ (t3-t0)/1e6 +"ms");
- System.err.println(" GLProfile.initSingleton(): "+ (t1-t0)/1e6 +"ms");
- System.err.println(" Demo Code: "+ (t2-t1)/1e6 +"ms");
- System.err.println(" GLProfile.shutdown(SHARED): "+ (t3-t2)/1e6 +"ms");
- }
-
- @Test
- public void test01OneLife() throws InterruptedException {
- oneLife();
- }
-
- @Test
- public void test01AnotherLife() throws InterruptedException {
- oneLife();
- }
-
- @Test
- public void test01TwoLifes() throws InterruptedException {
- oneLife();
- oneLife();
- }
-
- public static void main(String args[]) throws IOException {
- boolean waitForKey = false;
-
- for(int i=0; i<args.length; i++) {
- if(args[i].equals("-wait")) {
- waitForKey = true;
- }
- }
-
- if(waitForKey) {
- BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
- System.err.println("Press enter to continue");
- try {
- System.err.println(stdin.readLine());
- } catch (IOException e) { }
- }
-
- String tstname = TestShutdownSharedNEWT.class.getName();
- org.junit.runner.JUnitCore.main(tstname);
- }
-
-}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestAWT01GLn.java b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestAWT01GLn.java
index 64a1a01..e1048c2 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestAWT01GLn.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestAWT01GLn.java
@@ -40,49 +40,23 @@ import java.awt.Frame;
import org.junit.Assert;
import org.junit.Assume;
-import org.junit.Before;
import org.junit.BeforeClass;
-import org.junit.After;
import org.junit.Test;
public class TestAWT01GLn extends UITestCase {
- Frame frame=null;
- GLCanvas glCanvas=null;
-
@BeforeClass
public static void startup() {
System.out.println("GLProfile "+GLProfile.glAvailabilityToString());
}
- @Before
- public void init() {
- frame = new Frame("Texture Test");
- Assert.assertNotNull(frame);
- }
-
- @After
- public void release() {
- Assert.assertNotNull(frame);
- Assert.assertNotNull(glCanvas);
- try {
- javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
- public void run() {
- frame.setVisible(false);
- frame.remove(glCanvas);
- frame.dispose();
- }});
- } catch (Throwable t) {
- t.printStackTrace();
- Assume.assumeNoException(t);
- }
- frame=null;
- glCanvas=null;
- }
-
protected void runTestGL(GLCapabilities caps) throws InterruptedException {
- glCanvas = new GLCanvas(caps);
+ final Frame frame = new Frame("Texture Test");
+ Assert.assertNotNull(frame);
+
+ final GLCanvas glCanvas = new GLCanvas(caps);
Assert.assertNotNull(glCanvas);
+
glCanvas.addGLEventListener(new GearsES2());
frame.add(glCanvas);
@@ -110,6 +84,18 @@ public class TestAWT01GLn extends UITestCase {
Thread.sleep(500); // 500 ms
animator.stop();
+
+ try {
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ frame.setVisible(false);
+ frame.remove(glCanvas);
+ frame.dispose();
+ }});
+ } catch (Throwable t) {
+ t.printStackTrace();
+ Assume.assumeNoException(t);
+ }
}
@Test
@@ -136,6 +122,18 @@ public class TestAWT01GLn extends UITestCase {
}
}
+ @Test
+ public void test02ES2() throws InterruptedException {
+ if(GLProfile.isAvailable(GLProfile.GLES2)) {
+ GLProfile glprofile = GLProfile.get(GLProfile.GLES2);
+ System.out.println( "GLProfile GLES2: " + glprofile );
+ GLCapabilities caps = new GLCapabilities(glprofile);
+ runTestGL(caps);
+ } else {
+ System.out.println("GLES2 n/a");
+ }
+ }
+
public static void main(String args[]) {
org.junit.runner.JUnitCore.main(TestAWT01GLn.class.getName());
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug461OffscreenSupersamplingSwingAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug461FBOSupersamplingSwingAWT.java
similarity index 92%
copy from src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug461OffscreenSupersamplingSwingAWT.java
copy to src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug461FBOSupersamplingSwingAWT.java
index 6a315c6..42949af 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug461OffscreenSupersamplingSwingAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug461FBOSupersamplingSwingAWT.java
@@ -40,7 +40,7 @@ import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLEventListener;
-import javax.media.opengl.GLPbuffer;
+import javax.media.opengl.GLOffscreenAutoDrawable;
import javax.media.opengl.GLProfile;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
@@ -57,9 +57,10 @@ import com.jogamp.opengl.test.junit.util.UITestCase;
*
* @author Wade Walker (from code sample provided by Owen Dimond)
*/
-public class TestBug461OffscreenSupersamplingSwingAWT extends UITestCase implements GLEventListener {
+ at SuppressWarnings("deprecation")
+public class TestBug461FBOSupersamplingSwingAWT extends UITestCase implements GLEventListener {
JFrame jframe;
- GLPbuffer offScreenBuffer;
+ GLOffscreenAutoDrawable offScreenBuffer;
private void render(GLAutoDrawable drawable) {
GL2 gl = drawable.getGL().getGL2();
@@ -140,7 +141,7 @@ public class TestBug461OffscreenSupersamplingSwingAWT extends UITestCase impleme
glCap.setStencilBits(1);
//makes a new buffer
- offScreenBuffer = fac.createGLPbuffer(GLProfile.getDefaultDevice(), glCap, null, 200, 200, null);
+ offScreenBuffer = fac.createOffscreenAutoDrawable(GLProfile.getDefaultDevice(), glCap, null, 200, 200, null);
Assert.assertNotNull(offScreenBuffer);
offScreenBuffer.addGLEventListener(this);
offScreenBuffer.display();
@@ -148,10 +149,11 @@ public class TestBug461OffscreenSupersamplingSwingAWT extends UITestCase impleme
public void run() {
jframe.setVisible(true);
}});
+ offScreenBuffer.destroy();
}
public static void main(String args[]) {
- org.junit.runner.JUnitCore.main(TestBug461OffscreenSupersamplingSwingAWT.class.getName());
+ org.junit.runner.JUnitCore.main(TestBug461FBOSupersamplingSwingAWT.class.getName());
}
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug461OffscreenSupersamplingSwingAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug461PBufferSupersamplingSwingAWT.java
similarity index 95%
rename from src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug461OffscreenSupersamplingSwingAWT.java
rename to src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug461PBufferSupersamplingSwingAWT.java
index 6a315c6..5b7052c 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug461OffscreenSupersamplingSwingAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug461PBufferSupersamplingSwingAWT.java
@@ -57,7 +57,8 @@ import com.jogamp.opengl.test.junit.util.UITestCase;
*
* @author Wade Walker (from code sample provided by Owen Dimond)
*/
-public class TestBug461OffscreenSupersamplingSwingAWT extends UITestCase implements GLEventListener {
+ at SuppressWarnings("deprecation")
+public class TestBug461PBufferSupersamplingSwingAWT extends UITestCase implements GLEventListener {
JFrame jframe;
GLPbuffer offScreenBuffer;
@@ -148,10 +149,11 @@ public class TestBug461OffscreenSupersamplingSwingAWT extends UITestCase impleme
public void run() {
jframe.setVisible(true);
}});
+ offScreenBuffer.destroy();
}
public static void main(String args[]) {
- org.junit.runner.JUnitCore.main(TestBug461OffscreenSupersamplingSwingAWT.class.getName());
+ org.junit.runner.JUnitCore.main(TestBug461PBufferSupersamplingSwingAWT.class.getName());
}
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug572AWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug572AWT.java
new file mode 100644
index 0000000..b3abc41
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug572AWT.java
@@ -0,0 +1,127 @@
+/**
+ * Copyright 2012 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community OR
+ * CONTRIBUTORS 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.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.opengl.test.junit.jogl.awt;
+
+import java.awt.Window;
+import java.lang.reflect.InvocationTargetException;
+
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLProfile;
+import javax.media.opengl.awt.GLCanvas;
+import javax.swing.JFrame;
+import javax.swing.SwingUtilities;
+
+import junit.framework.Assert;
+
+import org.junit.Assume;
+import org.junit.Test;
+
+import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+
+/**
+ * Tests context creation + display on various kinds of Window implementations.
+ */
+public class TestBug572AWT extends UITestCase {
+
+ protected void runTestGL() throws InterruptedException, InvocationTargetException {
+ final Window window = new JFrame(this.getSimpleTestName(" - "));
+ final GLCapabilities caps = new GLCapabilities(GLProfile.getGL2ES2());
+ final GLCanvas glCanvas = new GLCanvas(caps);
+ final SnapshotGLEventListener snapshooter = new SnapshotGLEventListener();
+ snapshooter.setMakeSnapshotAlways(true);
+ glCanvas.addGLEventListener(new GearsES2());
+ glCanvas.addGLEventListener(snapshooter);
+ window.add(glCanvas);
+
+ // Revalidate size/layout.
+ // Always validate if component added/removed.
+ // Ensure 1st paint of GLCanvas will have a valid size, hence drawable gets created.
+ window.setSize(512, 512);
+ window.validate();
+
+ window.setVisible(true);
+ System.err.println("XXXX-0 "+glCanvas.getDelegatedDrawable().isRealized()+", "+glCanvas);
+
+ // Immediately displayable after issuing initial setVisible(true) .. even not within AWT-EDT ?
+ Assert.assertTrue("GLCanvas didn't become displayable", glCanvas.isDisplayable());
+ Assert.assertTrue("GLCanvas didn't become realized", glCanvas.isRealized());
+
+ // Would be required if not immediately displayable ...
+ // Assert.assertTrue("GLCanvas didn't become displayable and realized", AWTRobotUtil.waitForRealized(glCanvas, true));
+ // System.err.println("XXXX-1 "+glCanvas.getDelegatedDrawable().isRealized()+", "+glCanvas);
+
+ // The AWT-EDT reshape/repaint events happen offthread later ..
+ System.err.println("XXXX-1 reshapeCount "+snapshooter.getReshapeCount());
+ System.err.println("XXXX-1 displayCount "+snapshooter.getDisplayCount());
+
+ // Wait unitl AWT-EDT has issued reshape/repaint
+ for (int wait=0; wait<AWTRobotUtil.POLL_DIVIDER &&
+ ( 0 == snapshooter.getReshapeCount() || 0 == snapshooter.getDisplayCount() );
+ wait++) {
+ Thread.sleep(AWTRobotUtil.TIME_SLICE);
+ }
+ System.err.println("XXXX-2 reshapeCount "+snapshooter.getReshapeCount());
+ System.err.println("XXXX-2 displayCount "+snapshooter.getDisplayCount());
+
+ Assert.assertTrue("GLCanvas didn't reshape", snapshooter.getReshapeCount()>0);
+ Assert.assertTrue("GLCanvas didn't display", snapshooter.getDisplayCount()>0);
+
+ // After initial 'setVisible(true)' all AWT manipulation needs to be done
+ // via the AWT EDT, according to the AWT spec.
+
+ Runnable cleanup = new Runnable() {
+ public void run() {
+ System.err.println("cleaning up...");
+ window.setVisible(false);
+ try {
+ window.removeAll();
+ } catch (Throwable t) {
+ Assume.assumeNoException(t);
+ t.printStackTrace();
+ }
+ window.dispose();
+ }
+
+ };
+
+ // AWT / Swing on EDT..
+ SwingUtilities.invokeAndWait(cleanup);
+ }
+
+ @Test
+ public void test01() throws InterruptedException, InvocationTargetException {
+ runTestGL();
+ }
+
+ public static void main(String args[]) {
+ org.junit.runner.JUnitCore.main(TestBug572AWT.class.getName());
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug611AWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug611AWT.java
new file mode 100644
index 0000000..b6a7639
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug611AWT.java
@@ -0,0 +1,81 @@
+
+package com.jogamp.opengl.test.junit.jogl.awt;
+
+import java.awt.Desktop;
+import java.io.File;
+
+import javax.media.opengl.GLProfile;
+
+import org.junit.Test;
+
+import com.jogamp.common.os.Platform;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+
+/**
+ * As reported in Bug 611, on Windows XP is a performance issue:
+ * After JOGL initialization there seems to be a huge time lag
+ * when trying to open the Desktop folder.
+ * <p>
+ * Test disabled since showing the Desktop folder will
+ * disturb the 'desktop' .. if there is another way to show
+ * the performance bug, pls do so.
+ * </p>
+ * <p>
+ * Since Windows XP is out of life .. we may not care ..
+ * </p>
+ */
+public class TestBug611AWT extends UITestCase {
+
+ @Test
+ public void test00() {
+ // make junit happy
+ }
+
+ // @Test
+ public void test01() {
+ try {
+ // System.setProperty("jogamp.gluegen.UseTempJarCache", "false");
+ GLProfile.initSingleton();
+ Desktop desktop;
+ if (Desktop.isDesktopSupported()) {
+ desktop = Desktop.getDesktop();
+ } else {
+ desktop = null;
+ }
+ if(null != desktop) {
+ String home = System.getProperty("user.home");
+ File homeFolder = null;
+ if(null != home) {
+ {
+ File tst = new File(home + "/Desktop");
+ if( tst.canRead() ) {
+ homeFolder = tst;
+ }
+ }
+ if(null == homeFolder) {
+ File tst = new File(home);
+ if( tst.canRead() ) {
+ homeFolder = tst;
+ }
+ }
+ }
+ if(null == homeFolder) {
+ if(Platform.getOSType() == Platform.OSType.WINDOWS) {
+ homeFolder = new File("c:\\");
+ } else {
+ homeFolder = new File("/");
+ }
+ }
+ if(null != homeFolder) {
+ desktop.open(homeFolder);
+ }
+ }
+ } catch(Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ public static void main(String args[]) {
+ org.junit.runner.JUnitCore.main(TestBug611AWT.class.getName());
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestJScrollPaneMixHwLw01AWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestJScrollPaneMixHwLw01AWT.java
new file mode 100644
index 0000000..bb525c9
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestJScrollPaneMixHwLw01AWT.java
@@ -0,0 +1,172 @@
+package com.jogamp.opengl.test.junit.jogl.awt;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.GraphicsConfiguration;
+import java.awt.Rectangle;
+import java.awt.ScrollPane;
+import java.awt.Shape;
+import java.io.IOException;
+
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLProfile;
+import javax.media.opengl.awt.GLCanvas;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import javax.swing.WindowConstants;
+
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.Test;
+
+import com.jogamp.common.util.ReflectionUtil;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+import com.jogamp.opengl.test.junit.util.MiscUtils;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+import com.jogamp.opengl.util.Animator;
+
+/**
+ * Documenting Bug 586
+ *
+ * <p>
+ * JScrollPane cannot mix hw/lw components, only if setting property '-Dsun.awt.disableMixing=true'.
+ * </p>
+ * <p>
+ * You can use ScrollPane, or maybe a slider and fwd the panning to the GLCanvas,
+ * which could change it's GL viewport accordingly.
+ * </p>
+ * See git commit '8df12ca151dfc577c90b485d4ebfe491b88e55aa'.
+ */
+public class TestJScrollPaneMixHwLw01AWT extends UITestCase {
+ static long durationPerTest = 500;
+
+ static {
+ // too late: use at cmd-line '-Dsun.awt.disableMixing=true' works
+ // System.setProperty("sun.awt.disableMixing", "true");
+ }
+
+ /**
+ * Doesn't work either ..
+ */
+ @SuppressWarnings("serial")
+ public static class TransparentJScrollPane extends JScrollPane {
+
+ public TransparentJScrollPane(Component view) {
+ super(view);
+
+ setOpaque(false);
+
+ try {
+ ReflectionUtil.callStaticMethod(
+ "com.sun.awt.AWTUtilities", "setComponentMixingCutoutShape",
+ new Class<?>[] { Component.class, Shape.class },
+ new Object[] { this, new Rectangle() } ,
+ GraphicsConfiguration.class.getClassLoader());
+ System.err.println("com.sun.awt.AWTUtilities.setComponentMixingCutoutShape(..) passed");
+ } catch (RuntimeException re) {
+ System.err.println("com.sun.awt.AWTUtilities.setComponentMixingCutoutShape(..) failed: "+re.getMessage());
+ }
+ }
+
+ @Override
+ public void setOpaque(boolean isOpaque) {
+ }
+ }
+
+ protected void runTestGL(GLCapabilities caps, boolean useJScroll) throws InterruptedException {
+ final JFrame frame = new JFrame("Mix Hw/Lw Swing");
+ Assert.assertNotNull(frame);
+
+ final Dimension f_sz = new Dimension(600,400);
+ final Dimension glc_sz = new Dimension(500,600);
+
+ final GLCanvas glCanvas = new GLCanvas(caps);
+ Assert.assertNotNull(glCanvas);
+ glCanvas.addGLEventListener(new GearsES2());
+ glCanvas.setPreferredSize(glc_sz);
+
+ JPanel panel = new JPanel(new BorderLayout());
+ panel.setOpaque(false);
+ if(useJScroll) {
+ final JScrollPane scrollPane = new TransparentJScrollPane(glCanvas);
+ panel.add(scrollPane, BorderLayout.CENTER);
+ } else {
+ ScrollPane scrollPane = new ScrollPane();
+ scrollPane.add(glCanvas);
+ panel.add(scrollPane, BorderLayout.CENTER);
+ }
+
+ JTextArea textArea = new JTextArea();
+ textArea.setText("Test\nTest\nTest\nTest\n");
+
+ panel.add(textArea, BorderLayout.NORTH);
+
+ frame.add(panel);
+ frame.setLocationRelativeTo(null);
+ frame.setTitle("GLCanvas in JScrollPane example");
+ frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
+
+ try {
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ frame.setSize(f_sz);
+ frame.setVisible(true);
+ }});
+ } catch (Throwable t) {
+ t.printStackTrace();
+ Assume.assumeNoException(t);
+ }
+
+ Animator animator = new Animator(glCanvas);
+ animator.start();
+
+ Thread.sleep(durationPerTest);
+
+ animator.stop();
+
+ try {
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ frame.setVisible(false);
+ frame.dispose();
+ }});
+ } catch (Throwable t) {
+ t.printStackTrace();
+ Assume.assumeNoException(t);
+ }
+ }
+
+ // @Test doesn't work
+ public void test01JScrollPane() throws InterruptedException {
+ GLProfile glp = GLProfile.getGL2ES2();
+ GLCapabilities caps = new GLCapabilities(glp);
+ runTestGL(caps, true);
+ }
+
+ @Test
+ public void test01ScrollPane() throws InterruptedException {
+ GLProfile glp = GLProfile.getGL2ES2();
+ GLCapabilities caps = new GLCapabilities(glp);
+ runTestGL(caps, false);
+ }
+
+ public static void main(String args[]) throws IOException {
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-time")) {
+ durationPerTest = MiscUtils.atol(args[++i], durationPerTest);
+ }
+ }
+ /**
+ BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
+ System.err.println("Press enter to continue");
+ System.err.println(stdin.readLine());
+ */
+ System.out.println("durationPerTest: "+durationPerTest);
+ String tstname = TestJScrollPaneMixHwLw01AWT.class.getName();
+ org.junit.runner.JUnitCore.main(tstname);
+ }
+
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestBug605FlippedImageAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestBug605FlippedImageAWT.java
new file mode 100644
index 0000000..b949bc3
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestBug605FlippedImageAWT.java
@@ -0,0 +1,185 @@
+/**
+ * Copyright 2012 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community OR
+ * CONTRIBUTORS 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.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+package com.jogamp.opengl.test.junit.jogl.caps;
+
+import java.io.File;
+import java.io.IOException;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLProfile;
+
+import com.jogamp.opengl.util.awt.Screenshot;
+import com.jogamp.opengl.util.texture.TextureIO;
+
+import java.awt.image.BufferedImage;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+
+import com.jogamp.opengl.test.junit.util.UITestCase;
+
+public class TestBug605FlippedImageAWT extends UITestCase {
+ class FlippedImageTest implements GLEventListener {
+ public void display(GLAutoDrawable drawable) {
+ GL2 gl = drawable.getGL().getGL2();
+
+ gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT | GL.GL_STENCIL_BUFFER_BIT | GL2.GL_ACCUM_BUFFER_BIT );
+
+ gl.glMatrixMode(GL2.GL_PROJECTION);
+ gl.glLoadIdentity();
+ gl.glMatrixMode(GL2.GL_MODELVIEW);
+ gl.glLoadIdentity();
+
+ // red below
+ gl.glColor3f(1, 0, 0);
+ gl.glRectf(-1, -1, 1, 0);
+
+ // green above
+ gl.glColor3f(0, 1, 0);
+ gl.glRectf(-1, 0, 1, 1);
+ gl.glFinish();
+
+ final GLCapabilitiesImmutable caps = drawable.getChosenGLCapabilities();
+ if(caps.getAccumGreenBits() > 0) {
+ gl.glAccum(GL2.GL_ACCUM, 1.0f);
+ gl.glAccum(GL2.GL_RETURN, 1.0f);
+ }
+ gl.glFinish();
+
+ final int width = drawable.getWidth();
+ final int height = drawable.getHeight();
+
+ final String fname = getSnapshotFilename(0, null, caps, width, height, false, TextureIO.PNG, null);
+ try {
+ Screenshot.writeToFile(new File(fname), width, height, false);
+ } catch (GLException e) {
+ throw e;
+ } catch (IOException e) {
+ throw new GLException(e);
+ }
+ testFlipped(width, height);
+ }
+
+ public void init(GLAutoDrawable drawable) {
+ final GL gl = drawable.getGL();
+ System.err.println("GL_RENDERER: "+gl.glGetString(GL.GL_RENDERER));
+ System.err.println("GL_VERSION: "+gl.glGetString(GL.GL_VERSION));
+ }
+ public void reshape(GLAutoDrawable glDrawable, int x, int y, int w, int h) {}
+ public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {}
+ public void dispose(GLAutoDrawable drawable) {}
+ }
+
+ static final int green = 0x0000ff00; // above
+ static final int red = 0x00ff0000; // below
+
+ private void testFlipped(int width, int height) {
+ // Default origin 0/0 is lower left corner, so is the memory layout
+ // However AWT origin 0/0 is upper left corner
+ final BufferedImage image = Screenshot.readToBufferedImage(width, height);
+
+ final int below = image.getRGB(0, height-1) & 0x00ffffff;
+ System.err.println("below: 0x"+Integer.toHexString(below));
+
+ final int above = image.getRGB(0, 0) & 0x00ffffff;
+ System.err.println("above: 0x"+Integer.toHexString(above));
+
+ if (above == green && below == red) {
+ System.out.println("Image right side up");
+ } else if (above == red && below == green) {
+ Assert.assertTrue("Image is flipped", false);
+ } else {
+ Assert.assertTrue("Error in test", false);
+ }
+ }
+
+ private void test(GLCapabilitiesImmutable caps) {
+
+ final GLDrawableFactory glFactory = GLDrawableFactory.getFactory(caps.getGLProfile());
+ final GLAutoDrawable glad = glFactory.createOffscreenAutoDrawable(null, caps, null, 256, 256, null);
+ final FlippedImageTest tglel = new FlippedImageTest();
+ glad.addGLEventListener(tglel);
+
+ // 1 frame incl. snapshot to memory & file
+ glad.display();
+ System.err.println("XXX "+glad.getChosenGLCapabilities());
+ System.err.println("XXX "+glad.getContext().getGLVersion());
+
+ glad.destroy();
+ }
+
+ @Test
+ public void test01DefaultFBO() {
+ final GLProfile glp = GLProfile.get(GLProfile.GL2);
+ final GLCapabilities caps = new GLCapabilities(glp);
+ caps.setFBO(true);
+ test(caps);
+ }
+
+ @Test
+ public void test01StencilFBO() {
+ final GLProfile glp = GLProfile.get(GLProfile.GL2);
+ final GLCapabilities caps = new GLCapabilities(glp);
+ caps.setStencilBits(8);
+ caps.setFBO(true);
+ test(caps);
+ }
+
+ @Test
+ public void test01DefaultPBuffer() {
+ final GLProfile glp = GLProfile.get(GLProfile.GL2);
+ final GLCapabilities caps = new GLCapabilities(glp);
+ caps.setPBuffer(true);
+ test(caps);
+ }
+
+ @Test
+ public void test01AccumStencilPBuffer() {
+ final GLProfile glp = GLProfile.get(GLProfile.GL2);
+ final GLCapabilities caps = new GLCapabilities(glp);
+ caps.setAccumRedBits(16);
+ caps.setAccumGreenBits(16);
+ caps.setAccumBlueBits(16);
+ caps.setStencilBits(8);
+ caps.setPBuffer(true);
+ test(caps);
+ }
+
+ public static void main(String[] args) {
+ org.junit.runner.JUnitCore.main(TestBug605FlippedImageAWT.class.getName());
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestBug605FlippedImageNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestBug605FlippedImageNEWT.java
new file mode 100644
index 0000000..837d94c
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestBug605FlippedImageNEWT.java
@@ -0,0 +1,176 @@
+/**
+ * Copyright 2012 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community OR
+ * CONTRIBUTORS 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.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+package com.jogamp.opengl.test.junit.jogl.caps;
+
+import java.nio.ByteBuffer;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLProfile;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+
+import com.jogamp.opengl.test.junit.util.UITestCase;
+import com.jogamp.opengl.util.GLReadBufferUtil;
+
+public class TestBug605FlippedImageNEWT extends UITestCase {
+ static class FlippedImageTest implements GLEventListener {
+ public void display(GLAutoDrawable drawable) {
+ GL2 gl = drawable.getGL().getGL2();
+
+ gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT | GL.GL_STENCIL_BUFFER_BIT | GL2.GL_ACCUM_BUFFER_BIT );
+
+ gl.glMatrixMode(GL2.GL_PROJECTION);
+ gl.glLoadIdentity();
+ gl.glMatrixMode(GL2.GL_MODELVIEW);
+ gl.glLoadIdentity();
+
+ // red below
+ gl.glColor3f(1, 0, 0);
+ gl.glRectf(-1, -1, 1, 0);
+
+ // green above
+ gl.glColor3f(0, 1, 0);
+ gl.glRectf(-1, 0, 1, 1);
+ gl.glFinish();
+
+ final GLCapabilitiesImmutable caps = drawable.getChosenGLCapabilities();
+ if(caps.getAccumGreenBits() > 0) {
+ gl.glAccum(GL2.GL_ACCUM, 1.0f);
+ gl.glAccum(GL2.GL_RETURN, 1.0f);
+ }
+ gl.glFinish();
+ }
+
+ public void init(GLAutoDrawable drawable) {
+ final GL gl = drawable.getGL();
+ System.err.println("GL_RENDERER: "+gl.glGetString(GL.GL_RENDERER));
+ System.err.println("GL_VERSION: "+gl.glGetString(GL.GL_VERSION));
+ }
+ public void reshape(GLAutoDrawable glDrawable, int x, int y, int w, int h) {}
+ public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {}
+ public void dispose(GLAutoDrawable drawable) {}
+ }
+
+ static final int green = 0x0000ff00; // above
+ static final int red = 0x00ff0000; // below
+
+ private int getRGB(ByteBuffer bb, int o) {
+ return ( (int)bb.get(o+0) & 0x000000ff ) << 16 |
+ ( (int)bb.get(o+1) & 0x000000ff ) << 8 |
+ ( (int)bb.get(o+2) & 0x000000ff );
+ }
+
+ private void testFlipped(ByteBuffer bb, int width, int height, int comp) {
+ // Default origin 0/0 is lower left corner, so is the memory layout
+
+ // x=0, y=0: RGB -> _RGB [high-byte .. low-byte]
+ final int below = getRGB(bb, 0);
+ System.err.println("below: 0x"+Integer.toHexString(below));
+
+ // x=0, y=height-1: RGB -> _RGB [high-byte .. low-byte]
+ final int above= getRGB(bb, ( height - 1 ) * ( width * comp ));
+ System.err.println("above: 0x"+Integer.toHexString(above));
+
+ if (above == green && below == red) {
+ System.out.println("Image right side up");
+ } else if (above == red && below == green) {
+ Assert.assertTrue("Image is flipped", false);
+ } else {
+ Assert.assertTrue("Error in test", false);
+ }
+ }
+
+ private void test(GLCapabilitiesImmutable caps) {
+ final GLReadBufferUtil rbu = new GLReadBufferUtil(false, false);
+ final GLDrawableFactory glFactory = GLDrawableFactory.getFactory(caps.getGLProfile());
+ final GLAutoDrawable glad = glFactory.createOffscreenAutoDrawable(null, caps, null, 256, 256, null);
+ final FlippedImageTest tglel = new FlippedImageTest();
+ glad.addGLEventListener(tglel);
+ final SnapshotGLEventListener snap = new SnapshotGLEventListener(rbu);
+ glad.addGLEventListener(snap);
+ snap.setMakeSnapshotAlways(true);
+
+ // 1 frame incl. snapshot to memory & file
+ glad.display();
+ System.err.println("XXX "+glad.getChosenGLCapabilities());
+ System.err.println("XXX "+glad.getContext().getGLVersion());
+ testFlipped(rbu.getPixelBuffer(), glad.getWidth(), glad.getHeight(), 3);
+
+ glad.destroy();
+ }
+
+ @Test
+ public void test01DefaultFBO() {
+ final GLProfile glp = GLProfile.get(GLProfile.GL2);
+ final GLCapabilities caps = new GLCapabilities(glp);
+ caps.setFBO(true);
+ test(caps);
+ }
+
+ @Test
+ public void test01StencilFBO() {
+ final GLProfile glp = GLProfile.get(GLProfile.GL2);
+ final GLCapabilities caps = new GLCapabilities(glp);
+ caps.setStencilBits(8);
+ caps.setFBO(true);
+ test(caps);
+ }
+
+ @Test
+ public void test01DefaultPBuffer() {
+ final GLProfile glp = GLProfile.get(GLProfile.GL2);
+ final GLCapabilities caps = new GLCapabilities(glp);
+ caps.setPBuffer(true);
+ test(caps);
+ }
+
+ @Test
+ public void test01AccumStencilPBuffer() {
+ final GLProfile glp = GLProfile.get(GLProfile.GL2);
+ final GLCapabilities caps = new GLCapabilities(glp);
+ caps.setAccumRedBits(16);
+ caps.setAccumGreenBits(16);
+ caps.setAccumBlueBits(16);
+ caps.setStencilBits(8);
+ caps.setPBuffer(true);
+ test(caps);
+ }
+
+ public static void main(String[] args) {
+ org.junit.runner.JUnitCore.main(TestBug605FlippedImageNEWT.class.getName());
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES1AWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES1AWT.java
index 478bd45..c5bdfb5 100755
--- a/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES1AWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES1AWT.java
@@ -108,7 +108,7 @@ public class TestMultisampleES1AWT extends UITestCase {
public void init(GLAutoDrawable drawable) {}
public void dispose(GLAutoDrawable drawable) {}
public void display(GLAutoDrawable drawable) {
- snapshot(getSimpleTestName("."), displayCount++, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
+ snapshot(displayCount++, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
}
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { }
});
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES1NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES1NEWT.java
index ed8e2bd..5bbd673 100755
--- a/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES1NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES1NEWT.java
@@ -133,7 +133,7 @@ public class TestMultisampleES1NEWT extends UITestCase {
public void init(GLAutoDrawable drawable) {}
public void dispose(GLAutoDrawable drawable) {}
public void display(GLAutoDrawable drawable) {
- snapshot(getSimpleTestName("."), displayCount++, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
+ snapshot(displayCount++, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
}
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { }
});
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES2NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES2NEWT.java
index 02fcae6..c2e3215 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES2NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES2NEWT.java
@@ -126,7 +126,7 @@ public class TestMultisampleES2NEWT extends UITestCase {
public void init(GLAutoDrawable drawable) {}
public void dispose(GLAutoDrawable drawable) {}
public void display(GLAutoDrawable drawable) {
- snapshot(getSimpleTestName("."), displayCount++, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
+ snapshot(displayCount++, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
}
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { }
});
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/GearsObject.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/GearsObject.java
index b098e1d..44a74a3 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/GearsObject.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/GearsObject.java
@@ -117,18 +117,20 @@ public abstract class GearsObject {
s[4] = 0; // sin(0f)
c[4] = 1; // cos(0f)
+
+ final int vboUsage = GL.GL_STATIC_DRAW;
- frontFace = createInterleaved(6, GL.GL_FLOAT, false, 4*teeth+2, GL.GL_STATIC_DRAW);
+ frontFace = createInterleaved(6, GL.GL_FLOAT, false, 4*teeth+2, vboUsage);
addInterleavedVertexAndNormalArrays(frontFace, 3);
- backFace = createInterleaved(6, GL.GL_FLOAT, false, 4*teeth+2, GL.GL_STATIC_DRAW);
+ backFace = createInterleaved(6, GL.GL_FLOAT, false, 4*teeth+2, vboUsage);
addInterleavedVertexAndNormalArrays(backFace, 3);
- frontSide = createInterleaved(6, GL.GL_FLOAT, false, 6*teeth, GL.GL_STATIC_DRAW);
+ frontSide = createInterleaved(6, GL.GL_FLOAT, false, 6*teeth, vboUsage);
addInterleavedVertexAndNormalArrays(frontSide, 3);
- backSide = createInterleaved(6, GL.GL_FLOAT, false, 6*teeth, GL.GL_STATIC_DRAW);
+ backSide = createInterleaved(6, GL.GL_FLOAT, false, 6*teeth, vboUsage);
addInterleavedVertexAndNormalArrays(backSide, 3);
- outwardFace = createInterleaved(6, GL.GL_FLOAT, false, 4*4*teeth+2, GL.GL_STATIC_DRAW);
+ outwardFace = createInterleaved(6, GL.GL_FLOAT, false, 4*4*teeth+2, vboUsage);
addInterleavedVertexAndNormalArrays(outwardFace, 3);
- insideRadiusCyl = createInterleaved(6, GL.GL_FLOAT, false, 2*teeth+2, GL.GL_STATIC_DRAW);
+ insideRadiusCyl = createInterleaved(6, GL.GL_FLOAT, false, 2*teeth+2, vboUsage);
addInterleavedVertexAndNormalArrays(insideRadiusCyl, 3);
for (i = 0; i < teeth; i++) {
diff --git a/src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/PointsDemo.java
similarity index 69%
copy from src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java
copy to src/test/com/jogamp/opengl/test/junit/jogl/demos/PointsDemo.java
index 30f9660..4f2e415 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/PointsDemo.java
@@ -1,5 +1,5 @@
/**
- * Copyright 2010 JogAmp Community. All rights reserved.
+ * Copyright 2012 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
@@ -25,20 +25,24 @@
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of JogAmp Community.
*/
+package com.jogamp.opengl.test.junit.jogl.demos;
-package javax.media.nativewindow;
+import javax.media.opengl.GLEventListener;
-import jogamp.nativewindow.Debug;
+public abstract class PointsDemo implements GLEventListener {
+ int swapInterval = 0;
+ final int edge = 8; // 8*8
+
+ public PointsDemo(int swapInterval) {
+ this.swapInterval = swapInterval;
+ }
-/**
- * Marker for a singleton global recursive blocking lock implementation,
- * optionally locking a native windowing toolkit as well.
- * <br>
- * One use case is the AWT locking on X11, see {@link jogamp.nativewindow.jawt.JAWTToolkitLock}.
- */
-public interface ToolkitLock {
- public static final boolean TRACE_LOCK = Debug.isPropertyDefined("nativewindow.debug.ToolkitLock.TraceLock", true);
-
- public void lock();
- public void unlock();
+ public PointsDemo() {
+ this.swapInterval = 1;
+ }
+
+ public abstract void setSmoothPoints(boolean v);
+
+ public abstract void setPointParams(float minSize, float maxSize, float distAttenConst, float distAttenLinear, float distAttenQuadratic, float fadeThreshold);
+
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/GearsES1.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/GearsES1.java
index e81d1b4..5186fd7 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/GearsES1.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/GearsES1.java
@@ -24,8 +24,10 @@ package com.jogamp.opengl.test.junit.jogl.demos.es1;
import javax.media.nativewindow.NativeWindow;
import javax.media.opengl.GL;
import javax.media.opengl.GL2ES1;
+import javax.media.opengl.GL2ES2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLPipelineFactory;
import javax.media.opengl.GLProfile;
import com.jogamp.newt.Window;
@@ -36,12 +38,21 @@ import com.jogamp.newt.event.MouseAdapter;
import com.jogamp.newt.event.MouseEvent;
import com.jogamp.newt.event.MouseListener;
import com.jogamp.opengl.test.junit.jogl.demos.GearsObject;
+import com.jogamp.opengl.util.glsl.fixedfunc.FixedFuncUtil;
+import com.jogamp.opengl.util.glsl.fixedfunc.ShaderSelectionMode;
/**
* GearsES1.java <BR>
* @author Brian Paul (converted to Java by Ron Cemer and Sven Gothel) <P>
*/
public class GearsES1 implements GLEventListener {
+ private boolean debugFFPEmu = false;
+ private boolean verboseFFPEmu = false;
+ private boolean traceFFPEmu = false;
+ private boolean forceFFPEmu = false;
+ private boolean debug = false ;
+ private boolean trace = false ;
+
private final float pos[] = { 5.0f, 5.0f, 10.0f, 0.0f };
private float view_rotx = 20.0f, view_roty = 30.0f, view_rotz = 0.0f;
@@ -62,6 +73,13 @@ public class GearsES1 implements GLEventListener {
this.swapInterval = 1;
}
+ public void setForceFFPEmu(boolean forceFFPEmu, boolean verboseFFPEmu, boolean debugFFPEmu, boolean traceFFPEmu) {
+ this.forceFFPEmu = forceFFPEmu;
+ this.verboseFFPEmu = verboseFFPEmu;
+ this.debugFFPEmu = debugFFPEmu;
+ this.traceFFPEmu = traceFFPEmu;
+ }
+
public void setGears(GearsObject g1, GearsObject g2, GearsObject g3) {
gear1 = g1;
gear2 = g2;
@@ -90,14 +108,42 @@ public class GearsES1 implements GLEventListener {
// drawable.setGL(new DebugGL(drawable.getGL()));
GL _gl = drawable.getGL();
- // GL2ES1 gl = FixedFuncUtil.wrapFixedFuncEmul(_gl /*, true*/);
- GL2ES1 gl = _gl.getGL2ES1();
+ if(debugFFPEmu) {
+ // Debug ..
+ _gl = _gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Debug", GL2ES2.class, _gl, null) );
+ debug = false;
+ }
+ if(traceFFPEmu) {
+ // Trace ..
+ _gl = _gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Trace", GL2ES2.class, _gl, new Object[] { System.err } ) );
+ trace = false;
+ }
+ GL2ES1 gl = FixedFuncUtil.wrapFixedFuncEmul(_gl, ShaderSelectionMode.AUTO, null, forceFFPEmu, verboseFFPEmu);
+
+ if(debug) {
+ try {
+ // Debug ..
+ gl = (GL2ES1) gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Debug", GL2ES1.class, gl, null) );
+ } catch (Exception e) {e.printStackTrace();}
+ }
+ if(trace) {
+ try {
+ // Trace ..
+ gl = (GL2ES1) gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Trace", GL2ES1.class, gl, new Object[] { System.err } ) );
+ } catch (Exception e) {e.printStackTrace();}
+ }
+
+ System.err.println("GearsES1 init on "+Thread.currentThread());
System.err.println("Chosen GLCapabilities: " + drawable.getChosenGLCapabilities());
System.err.println("INIT GL IS: " + gl.getClass().getName());
System.err.println("GL_VENDOR: " + gl.glGetString(GL.GL_VENDOR));
System.err.println("GL_RENDERER: " + gl.glGetString(GL.GL_RENDERER));
System.err.println("GL_VERSION: " + gl.glGetString(GL.GL_VERSION));
+ System.err.println("GL GLSL: "+gl.hasGLSL()+", has-compiler: "+gl.isFunctionAvailable("glCompileShader")+", version "+(gl.hasGLSL() ? gl.glGetString(GL2ES2.GL_SHADING_LANGUAGE_VERSION) : "none"));
+ System.err.println("GL FBO: basic "+ gl.hasBasicFBOSupport()+", full "+gl.hasFullFBOSupport());
+ System.err.println("GL Profile: "+gl.getGLProfile());
+ System.err.println("GL:" + gl + ", " + gl.getContext().getGLVersion());
gl.glLightfv(GL2ES1.GL_LIGHT0, GL2ES1.GL_POSITION, pos, 0);
gl.glEnable(GL.GL_CULL_FACE);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/GearsObjectES1.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/GearsObjectES1.java
index 1208dad..8276c6b 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/GearsObjectES1.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/GearsObjectES1.java
@@ -47,10 +47,9 @@ public class GearsObjectES1 extends GearsObject {
}
@Override
- public void addInterleavedVertexAndNormalArrays(GLArrayDataServer array,
- int components) {
- array.addFixedSubArray(GLPointerFunc.GL_VERTEX_ARRAY, 3, GL.GL_ARRAY_BUFFER);
- array.addFixedSubArray(GLPointerFunc.GL_NORMAL_ARRAY, 3, GL.GL_ARRAY_BUFFER);
+ public void addInterleavedVertexAndNormalArrays(GLArrayDataServer array, int components) {
+ array.addFixedSubArray(GLPointerFunc.GL_VERTEX_ARRAY, components, GL.GL_ARRAY_BUFFER);
+ array.addFixedSubArray(GLPointerFunc.GL_NORMAL_ARRAY, components, GL.GL_ARRAY_BUFFER);
}
private void draw(GL2ES1 gl, GLArrayDataServer array, int mode) {
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/MultisampleDemoES1.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/MultisampleDemoES1.java
index aad5658..4b4c7f2 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/MultisampleDemoES1.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/MultisampleDemoES1.java
@@ -77,11 +77,12 @@ public class MultisampleDemoES1 implements GLEventListener {
if (multisample) {
gl.glDisable(GL.GL_MULTISAMPLE);
}
- immModeSink = ImmModeSink.createFixed(gl, GL.GL_STATIC_DRAW, 40,
- 3, GL.GL_FLOAT, // vertex
- 0, GL.GL_FLOAT, // color
- 0, GL.GL_FLOAT,// normal
- 0, GL.GL_FLOAT); // texture
+ immModeSink = ImmModeSink.createFixed(40,
+ 3, GL.GL_FLOAT, // vertex
+ 0, GL.GL_FLOAT, // color
+ 0, GL.GL_FLOAT, // normal
+ 0, GL.GL_FLOAT, // texCoords
+ GL.GL_STATIC_DRAW);
final int numSteps = 20;
final double increment = Math.PI / numSteps;
final double radius = 1;
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/OneTriangle.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/OneTriangle.java
index 8c9f53b..4b05f1a 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/OneTriangle.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/OneTriangle.java
@@ -61,11 +61,12 @@ public class OneTriangle {
// draw a triangle filling the window
gl.glLoadIdentity();
- ImmModeSink immModeSink = ImmModeSink.createFixed(gl, GL.GL_STATIC_DRAW, 3,
- 3, GL.GL_FLOAT, // vertex
- 3, GL.GL_FLOAT, // color
- 0, GL.GL_FLOAT,// normal
- 0, GL.GL_FLOAT); // texture
+ ImmModeSink immModeSink = ImmModeSink.createFixed(3*3,
+ 3, GL.GL_FLOAT, // vertex
+ 3, GL.GL_FLOAT, // color
+ 0, GL.GL_FLOAT, // normal
+ 0, GL.GL_FLOAT, // texCoords
+ GL.GL_STATIC_DRAW);
immModeSink.glBegin(GL.GL_TRIANGLES);
immModeSink.glColor3f( 1, 0, 0 );
immModeSink.glVertex2f( 0, 0 );
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/PointsDemoES1.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/PointsDemoES1.java
new file mode 100644
index 0000000..097784f
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/PointsDemoES1.java
@@ -0,0 +1,198 @@
+/**
+ * Copyright 2012 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community OR
+ * CONTRIBUTORS 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.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+package com.jogamp.opengl.test.junit.jogl.demos.es1;
+
+import java.nio.FloatBuffer;
+
+import com.jogamp.common.nio.Buffers;
+import com.jogamp.opengl.test.junit.jogl.demos.PointsDemo;
+import com.jogamp.opengl.util.GLArrayDataServer;
+import com.jogamp.opengl.util.PMVMatrix;
+import com.jogamp.opengl.util.glsl.fixedfunc.FixedFuncUtil;
+import com.jogamp.opengl.util.glsl.fixedfunc.ShaderSelectionMode;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2ES1;
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLPipelineFactory;
+import javax.media.opengl.glu.GLU;
+import javax.media.opengl.glu.gl2es1.GLUgl2es1;
+
+public class PointsDemoES1 extends PointsDemo {
+ final static GLU glu = new GLUgl2es1();
+ private boolean debugFFPEmu = false;
+ private boolean verboseFFPEmu = false;
+ private boolean traceFFPEmu = false;
+ private boolean forceFFPEmu = false;
+ private boolean debug = false ;
+ private boolean trace = false ;
+ GLArrayDataServer vertices ;
+ float[] pointSizes ;
+ private int swapInterval = 0;
+ final int edge = 8; // 8*8
+ boolean smooth = false;
+
+ public PointsDemoES1(int swapInterval) {
+ this.swapInterval = swapInterval;
+ }
+
+ public PointsDemoES1() {
+ this.swapInterval = 1;
+ }
+
+ public void setForceFFPEmu(boolean forceFFPEmu, boolean verboseFFPEmu, boolean debugFFPEmu, boolean traceFFPEmu) {
+ this.forceFFPEmu = forceFFPEmu;
+ this.verboseFFPEmu = verboseFFPEmu;
+ this.debugFFPEmu = debugFFPEmu;
+ this.traceFFPEmu = traceFFPEmu;
+ }
+
+ public void setSmoothPoints(boolean v) { smooth = v; }
+
+ public void init(GLAutoDrawable glad) {
+ GL _gl = glad.getGL();
+
+ if(debugFFPEmu) {
+ // Debug ..
+ _gl = _gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Debug", GL2ES2.class, _gl, null) );
+ debug = false;
+ }
+ if(traceFFPEmu) {
+ // Trace ..
+ _gl = _gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Trace", GL2ES2.class, _gl, new Object[] { System.err } ) );
+ trace = false;
+ }
+ GL2ES1 gl = FixedFuncUtil.wrapFixedFuncEmul(_gl, ShaderSelectionMode.AUTO, null, forceFFPEmu, verboseFFPEmu);
+
+ if(debug) {
+ try {
+ // Debug ..
+ gl = (GL2ES1) gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Debug", GL2ES1.class, gl, null) );
+ } catch (Exception e) {e.printStackTrace();}
+ }
+ if(trace) {
+ try {
+ // Trace ..
+ gl = (GL2ES1) gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Trace", GL2ES1.class, gl, new Object[] { System.err } ) );
+ } catch (Exception e) {e.printStackTrace();}
+ }
+
+ System.err.println("GL_VENDOR: " + gl.glGetString(GL.GL_VENDOR));
+ System.err.println("GL_RENDERER: " + gl.glGetString(GL.GL_RENDERER));
+ System.err.println("GL_VERSION: " + gl.glGetString(GL.GL_VERSION));
+ System.err.println("GL Profile: "+gl.getGLProfile());
+
+ // Allocate Vertex Array
+ vertices = GLArrayDataServer.createFixed(GL2ES1.GL_VERTEX_ARRAY, 3, GL.GL_FLOAT, false, edge*edge, GL.GL_STATIC_DRAW);
+ pointSizes = new float[edge*edge];
+ for(int i=0; i<edge; i++) {
+ for(int j=0; j<edge; j++) {
+ final float x = -3+j*0.7f;
+ final float y = -3+i*0.7f;
+ final float p = (i*edge+j)*0.5f;
+ // System.err.println("["+j+"/"+i+"]: "+x+"/"+y+": "+p);
+ vertices.putf(x); vertices.putf(y); vertices.putf( 0);
+ pointSizes[(i*edge+j)] = p;
+ }
+ }
+ vertices.seal(gl, true);
+ vertices.enableBuffer(gl, false);
+
+ // OpenGL Render Settings
+ gl.glEnable(GL2ES1.GL_DEPTH_TEST);
+ }
+
+ public void setPointParams(float minSize, float maxSize, float distAttenConst, float distAttenLinear, float distAttenQuadratic, float fadeThreshold) {
+ pointMinSize = minSize;
+ pointMaxSize = maxSize;
+ pointFadeThreshold = fadeThreshold;
+ pointDistAtten.put(0, distAttenConst);
+ pointDistAtten.put(1, distAttenLinear);
+ pointDistAtten.put(2, distAttenQuadratic);
+ }
+
+ /** default values */
+ private float pointMinSize = 0.0f;
+ private float pointMaxSize = 4096.0f;
+ private float pointFadeThreshold = 1.0f;
+ private final FloatBuffer pointDistAtten = Buffers.newDirectFloatBuffer(new float[] { 1.0f, 0.0f, 0.0f });
+
+ public void display(GLAutoDrawable glad) {
+ GL2ES1 gl = glad.getGL().getGL2ES1();
+ gl.glClearColor(0f, 0f, 0f, 0f);
+ gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
+ gl.glMatrixMode(GL2ES1.GL_MODELVIEW);
+ gl.glLoadIdentity();
+ gl.glTranslatef(0, 0, -10);
+
+ gl.glColor4f(1.0f, 1.0f, 1.0f, 1.0f );
+
+ vertices.enableBuffer(gl, true);
+
+ gl.glEnable ( GL.GL_BLEND );
+ gl.glBlendFunc ( GL.GL_SRC_ALPHA, GL.GL_ONE );
+ if(smooth) {
+ gl.glEnable(GL2ES1.GL_POINT_SMOOTH);
+ } else {
+ gl.glDisable(GL2ES1.GL_POINT_SMOOTH);
+ }
+ gl.glPointParameterf(GL2ES1.GL_POINT_SIZE_MIN, pointMinSize );
+ gl.glPointParameterf(GL2ES1.GL_POINT_SIZE_MAX, pointMaxSize );
+ gl.glPointParameterf(GL2ES1.GL_POINT_FADE_THRESHOLD_SIZE, pointFadeThreshold);
+ gl.glPointParameterfv(GL2ES1.GL_POINT_DISTANCE_ATTENUATION, pointDistAtten );
+
+ for(int i=edge*edge-1; i>=0; i--) {
+ gl.glPointSize(pointSizes[i]);
+ gl.glDrawArrays(GL.GL_POINTS, i, 1);
+ }
+
+ vertices.enableBuffer(gl, false);
+ }
+
+ public void reshape(GLAutoDrawable glad, int x, int y, int width, int height) {
+ // Thread.dumpStack();
+ GL2ES1 gl = glad.getGL().getGL2ES1();
+
+ if(-1 != swapInterval) {
+ gl.setSwapInterval(swapInterval); // in case switching the drawable (impl. may bound attribute there)
+ }
+
+ // Set location in front of camera
+ gl.glMatrixMode(PMVMatrix.GL_PROJECTION);
+ gl.glLoadIdentity();
+ glu.gluPerspective(45.0F, ( (float) width / (float) height ) / 1.0f, 1.0F, 100.0F);
+ //gl.glOrthof(-4.0f, 4.0f, -4.0f, 4.0f, 1.0f, 100.0f);
+ }
+
+ public void dispose(GLAutoDrawable glad) {
+ GL2ES1 gl = glad.getGL().getGL2ES1();
+ vertices.destroy(gl);
+ vertices = null;
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/RedSquareES1.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/RedSquareES1.java
index 8d1c708..37ed83e 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/RedSquareES1.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/RedSquareES1.java
@@ -10,11 +10,14 @@ import com.jogamp.opengl.util.glsl.fixedfunc.*;
public class RedSquareES1 implements GLEventListener {
- public static boolean glDebugEmu = false;
- public static boolean glDebug = false ;
- public static boolean glTrace = false ;
public static boolean oneThread = false;
public static boolean useAnimator = false;
+ private boolean debugFFPEmu = false;
+ private boolean verboseFFPEmu = false;
+ private boolean traceFFPEmu = false;
+ private boolean forceFFPEmu = false;
+ private boolean debug = false ;
+ private boolean trace = false ;
private int swapInterval = 0;
long startTime = 0;
@@ -28,6 +31,13 @@ public class RedSquareES1 implements GLEventListener {
this.swapInterval = 1;
}
+ public void setForceFFPEmu(boolean forceFFPEmu, boolean verboseFFPEmu, boolean debugFFPEmu, boolean traceFFPEmu) {
+ this.forceFFPEmu = forceFFPEmu;
+ this.verboseFFPEmu = verboseFFPEmu;
+ this.debugFFPEmu = debugFFPEmu;
+ this.traceFFPEmu = traceFFPEmu;
+ }
+
// FIXME: we must add storage of the pointers in the GL state to
// the GLImpl classes. The need for this can be seen by making
// these variables method local instead of instance members. The
@@ -42,44 +52,41 @@ public class RedSquareES1 implements GLEventListener {
System.err.println(Thread.currentThread()+" RedSquareES1.init ...");
GL _gl = drawable.getGL();
- if(glDebugEmu) {
- try {
- // Debug ..
- _gl = _gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Debug", GL2ES2.class, _gl, null) );
-
- if(glTrace) {
- // Trace ..
- _gl = _gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Trace", GL2ES2.class, _gl, new Object[] { System.err } ) );
- }
- } catch (Exception e) {e.printStackTrace();}
- glDebug = false;
- glTrace = false;
+ if(debugFFPEmu) {
+ // Debug ..
+ _gl = _gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Debug", GL2ES2.class, _gl, null) );
+ debug = false;
}
-
- GL2ES1 gl = FixedFuncUtil.wrapFixedFuncEmul(_gl);
- if(glDebug) {
+ if(traceFFPEmu) {
+ // Trace ..
+ _gl = _gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Trace", GL2ES2.class, _gl, new Object[] { System.err } ) );
+ trace = false;
+ }
+ GL2ES1 gl = FixedFuncUtil.wrapFixedFuncEmul(_gl, ShaderSelectionMode.AUTO, null, forceFFPEmu, verboseFFPEmu);
+
+ if(debug) {
try {
// Debug ..
gl = (GL2ES1) gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Debug", GL2ES1.class, gl, null) );
} catch (Exception e) {e.printStackTrace();}
}
-
- if(glTrace) {
+ if(trace) {
try {
// Trace ..
gl = (GL2ES1) gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Trace", GL2ES1.class, gl, new Object[] { System.err } ) );
} catch (Exception e) {e.printStackTrace();}
}
- System.err.println(Thread.currentThread()+"Chosen GLCapabilities: " + drawable.getChosenGLCapabilities());
- System.err.println(Thread.currentThread()+"INIT GL IS: " + gl.getClass().getName());
- System.err.println(Thread.currentThread()+"GL_VENDOR: " + gl.glGetString(GL.GL_VENDOR));
- System.err.println(Thread.currentThread()+"GL_RENDERER: " + gl.glGetString(GL.GL_RENDERER));
- System.err.println(Thread.currentThread()+"GL_VERSION: " + gl.glGetString(GL.GL_VERSION));
-
- System.err.println(Thread.currentThread()+" GL Profile: "+gl.getGLProfile());
- System.err.println(Thread.currentThread()+" GL:" + gl);
- System.err.println(Thread.currentThread()+" GL_VERSION=" + gl.glGetString(GL.GL_VERSION));
+ System.err.println("RedSquareES1 init on "+Thread.currentThread());
+ System.err.println("Chosen GLCapabilities: " + drawable.getChosenGLCapabilities());
+ System.err.println("INIT GL IS: " + gl.getClass().getName());
+ System.err.println("GL_VENDOR: " + gl.glGetString(GL.GL_VENDOR));
+ System.err.println("GL_RENDERER: " + gl.glGetString(GL.GL_RENDERER));
+ System.err.println("GL_VERSION: " + gl.glGetString(GL.GL_VERSION));
+ System.err.println("GL GLSL: "+gl.hasGLSL()+", has-compiler: "+gl.isFunctionAvailable("glCompileShader")+", version "+(gl.hasGLSL() ? gl.glGetString(GL2ES2.GL_SHADING_LANGUAGE_VERSION) : "none"));
+ System.err.println("GL FBO: basic "+ gl.hasBasicFBOSupport()+", full "+gl.hasFullFBOSupport());
+ System.err.println("GL Profile: "+gl.getGLProfile());
+ System.err.println("GL:" + gl + ", " + gl.getContext().getGLVersion());
// Allocate vertex arrays
colors = Buffers.newDirectFloatBuffer(16);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/newt/TestGearsES1NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/newt/TestGearsES1NEWT.java
index ff168d9..9e0bbae 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/newt/TestGearsES1NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/newt/TestGearsES1NEWT.java
@@ -48,6 +48,8 @@ import org.junit.Test;
public class TestGearsES1NEWT extends UITestCase {
static int width, height;
+ static boolean forceES2 = false;
+ static boolean forceFFPEmu = false;
@BeforeClass
public static void initClass() {
@@ -59,12 +61,16 @@ public class TestGearsES1NEWT extends UITestCase {
public static void releaseClass() {
}
- protected void runTestGL(GLCapabilities caps) throws InterruptedException {
+ protected void runTestGL(GLCapabilities caps, boolean forceFFPEmu) throws InterruptedException {
GLWindow glWindow = GLWindow.create(caps);
Assert.assertNotNull(glWindow);
glWindow.setTitle("Gears NEWT Test");
- glWindow.addGLEventListener(new GearsES1());
+ final GearsES1 demo = new GearsES1();
+ demo.setForceFFPEmu(forceFFPEmu, forceFFPEmu, false, false);
+ glWindow.addGLEventListener(demo);
+ final SnapshotGLEventListener snap = new SnapshotGLEventListener();
+ glWindow.addGLEventListener(snap);
Animator animator = new Animator(glWindow);
QuitAdapter quitAdapter = new QuitAdapter();
@@ -95,6 +101,7 @@ public class TestGearsES1NEWT extends UITestCase {
glWindow.setVisible(true);
animator.setUpdateFPSFrames(1, null);
animator.start();
+ snap.setMakeSnapshot();
while(!quitAdapter.shouldQuit() && animator.isAnimating() && animator.getTotalFPSDuration()<duration) {
Thread.sleep(100);
@@ -105,13 +112,13 @@ public class TestGearsES1NEWT extends UITestCase {
}
@Test
- public void test01() throws InterruptedException {
- GLCapabilities caps = new GLCapabilities(GLProfile.getGL2ES1());
- runTestGL(caps);
+ public void test00() throws InterruptedException {
+ GLCapabilities caps = new GLCapabilities(forceES2 ? GLProfile.get(GLProfile.GLES2) : GLProfile.getGL2ES1());
+ runTestGL(caps, forceFFPEmu);
}
-
- static long duration = 500; // ms
-
+
+ static long duration = 1000; // ms
+
public static void main(String args[]) {
for(int i=0; i<args.length; i++) {
if(args[i].equals("-time")) {
@@ -119,6 +126,10 @@ public class TestGearsES1NEWT extends UITestCase {
try {
duration = Integer.parseInt(args[i]);
} catch (Exception ex) { ex.printStackTrace(); }
+ } else if(args[i].equals("-es2")) {
+ forceES2 = true;
+ } else if(args[i].equals("-ffpemu")) {
+ forceFFPEmu = true;
}
}
org.junit.runner.JUnitCore.main(TestGearsES1NEWT.class.getName());
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/newt/TestRedSquareES1NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/newt/TestRedSquareES1NEWT.java
index c327a30..b0e6b2b 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/newt/TestRedSquareES1NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/newt/TestRedSquareES1NEWT.java
@@ -48,6 +48,8 @@ import org.junit.Test;
public class TestRedSquareES1NEWT extends UITestCase {
static int width, height;
+ static boolean forceES2 = false;
+ static boolean forceFFPEmu = false;
@BeforeClass
public static void initClass() {
@@ -59,12 +61,16 @@ public class TestRedSquareES1NEWT extends UITestCase {
public static void releaseClass() {
}
- protected void runTestGL(GLCapabilities caps) throws InterruptedException {
+ protected void runTestGL(GLCapabilities caps, boolean forceFFPEmu) throws InterruptedException {
GLWindow glWindow = GLWindow.create(caps);
Assert.assertNotNull(glWindow);
glWindow.setTitle("Gears NEWT Test");
- glWindow.addGLEventListener(new RedSquareES1());
+ final RedSquareES1 demo = new RedSquareES1();
+ demo.setForceFFPEmu(forceFFPEmu, forceFFPEmu, false, false);
+ glWindow.addGLEventListener(demo);
+ final SnapshotGLEventListener snap = new SnapshotGLEventListener();
+ glWindow.addGLEventListener(snap);
Animator animator = new Animator(glWindow);
QuitAdapter quitAdapter = new QuitAdapter();
@@ -95,6 +101,7 @@ public class TestRedSquareES1NEWT extends UITestCase {
glWindow.setVisible(true);
animator.setUpdateFPSFrames(1, null);
animator.start();
+ snap.setMakeSnapshot();
while(!quitAdapter.shouldQuit() && animator.isAnimating() && animator.getTotalFPSDuration()<duration) {
Thread.sleep(100);
@@ -105,20 +112,24 @@ public class TestRedSquareES1NEWT extends UITestCase {
}
@Test
- public void test01() throws InterruptedException {
- GLCapabilities caps = new GLCapabilities(GLProfile.getGL2ES1());
- runTestGL(caps);
+ public void test00() throws InterruptedException {
+ GLCapabilities caps = new GLCapabilities(forceES2 ? GLProfile.get(GLProfile.GLES2) : GLProfile.getGL2ES1());
+ runTestGL(caps, forceFFPEmu);
}
+
+ static long duration = 1000; // ms
- static long duration = 500; // ms
-
- public static void main(String args[]) {
+ public static void main(String args[]) {
for(int i=0; i<args.length; i++) {
if(args[i].equals("-time")) {
i++;
try {
duration = Integer.parseInt(args[i]);
} catch (Exception ex) { ex.printStackTrace(); }
+ } else if(args[i].equals("-es2")) {
+ forceES2 = true;
+ } else if(args[i].equals("-ffpemu")) {
+ forceFFPEmu = true;
}
}
org.junit.runner.JUnitCore.main(TestRedSquareES1NEWT.class.getName());
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/FBOMix2DemosES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/FBOMix2DemosES2.java
index 3dfbb48..9d2c73f 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/FBOMix2DemosES2.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/FBOMix2DemosES2.java
@@ -63,9 +63,8 @@ public class FBOMix2DemosES2 implements GLEventListener {
public FBOMix2DemosES2(int swapInterval) {
demo0 = new GearsES2(-1);
- demo0.setIsFBOSlave(true);
+ demo0.setIgnoreFocus(true);
demo1 = new RedSquareES2(-1);
- demo1.setIsFBOSlave(true);
this.swapInterval = swapInterval;
st = new ShaderState();
@@ -158,26 +157,19 @@ public class FBOMix2DemosES2 implements GLEventListener {
st.useProgram(gl, false);
System.err.println("**** Init");
- resetFBOs(gl, drawable);
+ initFBOs(gl, drawable);
- fbo0.attachRenderbuffer(gl, Type.DEPTH, 24);
- fbo0.unbind(gl);
- fbo1.attachRenderbuffer(gl, Type.DEPTH, 24);
- fbo1.unbind(gl);
- gl.glEnable(GL2ES2.GL_DEPTH_TEST);
-
- numSamples=fbo0.getNumSamples();
+ gl.glEnable(GL2ES2.GL_DEPTH_TEST);
}
- /** Since we switch MSAA and non-MSAA we need to take extra care, i.e. sync msaa for both FBOs ..*/
- private void resetFBOs(GL gl, GLAutoDrawable drawable) {
+ private void initFBOs(GL gl, GLAutoDrawable drawable) {
// remove all texture attachments, since MSAA uses just color-render-buffer
// and non-MSAA uses texture2d-buffer
fbo0.detachAllColorbuffer(gl);
fbo1.detachAllColorbuffer(gl);
- fbo0.reset(gl, drawable.getWidth(), drawable.getHeight(), numSamples);
- fbo1.reset(gl, drawable.getWidth(), drawable.getHeight(), numSamples);
+ fbo0.reset(gl, drawable.getWidth(), drawable.getHeight(), numSamples, false);
+ fbo1.reset(gl, drawable.getWidth(), drawable.getHeight(), numSamples, false);
if(fbo0.getNumSamples() != fbo1.getNumSamples()) {
throw new InternalError("sample size mismatch: \n\t0: "+fbo0+"\n\t1: "+fbo1);
}
@@ -185,15 +177,38 @@ public class FBOMix2DemosES2 implements GLEventListener {
if(numSamples>0) {
fbo0.attachColorbuffer(gl, 0, true);
+ fbo0.resetSamplingSink(gl);
fbo1.attachColorbuffer(gl, 0, true);
+ fbo1.resetSamplingSink(gl);
fbo0Tex = fbo0.getSamplingSink();
fbo1Tex = fbo1.getSamplingSink();
} else {
fbo0Tex = fbo0.attachTexture2D(gl, 0, true);
fbo1Tex = fbo1.attachTexture2D(gl, 0, true);
}
+ numSamples=fbo0.getNumSamples();
+ fbo0.attachRenderbuffer(gl, Type.DEPTH, 24);
+ fbo0.unbind(gl);
+ fbo1.attachRenderbuffer(gl, Type.DEPTH, 24);
+ fbo1.unbind(gl);
}
+ private void resetFBOs(GL gl, GLAutoDrawable drawable) {
+ fbo0.reset(gl, drawable.getWidth(), drawable.getHeight(), numSamples, true);
+ fbo1.reset(gl, drawable.getWidth(), drawable.getHeight(), numSamples, true);
+ if(fbo0.getNumSamples() != fbo1.getNumSamples()) {
+ throw new InternalError("sample size mismatch: \n\t0: "+fbo0+"\n\t1: "+fbo1);
+ }
+ numSamples = fbo0.getNumSamples();
+ if(numSamples>0) {
+ fbo0Tex = fbo0.getSamplingSink();
+ fbo1Tex = fbo1.getSamplingSink();
+ } else {
+ fbo0Tex = (TextureAttachment) fbo0.getColorbuffer(0);
+ fbo1Tex = (TextureAttachment) fbo1.getColorbuffer(0);
+ }
+ }
+
@Override
public void dispose(GLAutoDrawable drawable) {
final GL2ES2 gl = drawable.getGL().getGL2ES2();
@@ -245,6 +260,8 @@ public class FBOMix2DemosES2 implements GLEventListener {
}
interleavedVBO.enableBuffer(gl, true);
+ gl.glEnable(GL.GL_TEXTURE_2D);
+
gl.glDrawArrays(GL.GL_TRIANGLE_STRIP, 0, 4);
interleavedVBO.enableBuffer(gl, false);
@@ -264,10 +281,8 @@ public class FBOMix2DemosES2 implements GLEventListener {
gl.setSwapInterval(swapInterval); // in case switching the drawable (impl. may bound attribute there)
}
- // if(drawable.getWidth() == fbo0.getWidth() && drawable.getHeight() == fbo0.getHeight() ) {
- System.err.println("**** Reshape: "+width+"x"+height);
- resetFBOs(gl, drawable);
- //}
+ System.err.println("**** Reshape: "+width+"x"+height);
+ resetFBOs(gl, drawable);
fbo0.bind(gl);
demo0.reshape(drawable, x, y, width, height);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java
index 38e8a15..e703b6f 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java
@@ -64,8 +64,9 @@ public class GearsES2 implements GLEventListener {
private KeyListener gearsKeys = new GearsKeyAdapter();
private int prevMouseX, prevMouseY;
+ private boolean doRotate = true;
private boolean isInitialized = false;
- boolean isFBOSlave = false;
+ boolean ignoreFocus = false;
public GearsES2(int swapInterval) {
this.swapInterval = swapInterval;
@@ -75,7 +76,8 @@ public class GearsES2 implements GLEventListener {
this.swapInterval = 1;
}
- public void setIsFBOSlave(boolean v) { isFBOSlave = v; }
+ public void setIgnoreFocus(boolean v) { ignoreFocus = v; }
+ public void setDoRotation(boolean rotate) { this.doRotate = rotate; }
public void setPMVUseBackingArray(boolean pmvUseBackingArray) {
this.pmvUseBackingArray = pmvUseBackingArray;
@@ -112,27 +114,35 @@ public class GearsES2 implements GLEventListener {
System.err.println(Thread.currentThread()+" GearsES2.init ...");
GL2ES2 gl = drawable.getGL().getGL2ES2();
+ System.err.println("GearsES2 init on "+Thread.currentThread());
System.err.println("Chosen GLCapabilities: " + drawable.getChosenGLCapabilities());
System.err.println("INIT GL IS: " + gl.getClass().getName());
System.err.println("GL_VENDOR: " + gl.glGetString(GL.GL_VENDOR));
System.err.println("GL_RENDERER: " + gl.glGetString(GL.GL_RENDERER));
System.err.println("GL_VERSION: " + gl.glGetString(GL.GL_VERSION));
+ System.err.println("GL GLSL: "+gl.hasGLSL()+", has-compiler: "+gl.isFunctionAvailable("glCompileShader")+", version "+(gl.hasGLSL() ? gl.glGetString(GL2ES2.GL_SHADING_LANGUAGE_VERSION) : "none")+", "+gl.getContext().getGLSLVersionNumber());
+ System.err.println("GL FBO: basic "+ gl.hasBasicFBOSupport()+", full "+gl.hasFullFBOSupport());
+ System.err.println("GL Profile: "+gl.getGLProfile());
+ System.err.println("GL Renderer Quirks:" + gl.getContext().getRendererQuirks().toString());
+ System.err.println("GL:" + gl + ", " + gl.getContext().getGLVersion());
gl.glEnable(GL.GL_DEPTH_TEST);
st = new ShaderState();
// st.setVerbose(true);
final ShaderCode vp0 = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, this.getClass(), "shader",
- "shader/bin", "gears", false);
+ "shader/bin", "gears", true);
final ShaderCode fp0 = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, this.getClass(), "shader",
- "shader/bin", "gears", false);
+ "shader/bin", "gears", true);
+ vp0.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_vp);
+ fp0.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_fp);
final ShaderProgram sp0 = new ShaderProgram();
sp0.add(gl, vp0, System.err);
sp0.add(gl, fp0, System.err);
st.attachShaderProgram(gl, sp0, true);
// Use debug pipeline
// drawable.setGL(new DebugGL(drawable.getGL()));
-
+
pmvMatrix = new PMVMatrix(pmvUseBackingArray);
st.attachObject("pmvMatrix", pmvMatrix);
pmvMatrixUniform = new GLUniformData("pmvMatrix", 4, 4, pmvMatrix.glGetPMvMvitMatrixf()); // P, Mv, Mvi and Mvit
@@ -169,7 +179,7 @@ public class GearsES2 implements GLEventListener {
} else {
gear3 = new GearsObjectES2(gear3, pmvMatrix, pmvMatrixUniform, colorU);
System.err.println("gear3 reused: "+gear3);
- }
+ }
final Object upstreamWidget = drawable.getUpstreamWidget();
if (upstreamWidget instanceof Window) {
@@ -187,7 +197,8 @@ public class GearsES2 implements GLEventListener {
}
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
- System.err.println(Thread.currentThread()+" GearsES2.reshape "+x+"/"+y+" "+width+"x"+height+", swapInterval "+swapInterval);
+ System.err.println(Thread.currentThread()+" GearsES2.reshape "+x+"/"+y+" "+width+"x"+height+", swapInterval "+swapInterval+", drawable 0x"+Long.toHexString(drawable.getHandle()));
+ // Thread.dumpStack();
GL2ES2 gl = drawable.getGL().getGL2ES2();
if(-1 != swapInterval) {
@@ -241,13 +252,15 @@ public class GearsES2 implements GLEventListener {
colorU = null;
st.destroy(gl);
st = null;
-
+
System.err.println(Thread.currentThread()+" GearsES2.dispose FIN");
}
public void display(GLAutoDrawable drawable) {
// Turn the gears' teeth
- angle += 2.0f;
+ if(doRotate) {
+ angle += 2.0f;
+ }
// Get the GL corresponding to the drawable we are animating
GL2ES2 gl = drawable.getGL().getGL2ES2();
@@ -262,7 +275,7 @@ public class GearsES2 implements GLEventListener {
gl.glEnable(GL.GL_CULL_FACE);
- if( isFBOSlave || hasFocus ) {
+ if( ignoreFocus || hasFocus ) {
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
} else {
gl.glClearColor(0.2f, 0.2f, 0.2f, 0.0f);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsObjectES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsObjectES2.java
index 82485ea..32cc4c4 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsObjectES2.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsObjectES2.java
@@ -26,7 +26,6 @@ import javax.media.opengl.GL;
import javax.media.opengl.GL2ES2;
import javax.media.opengl.GLUniformData;
-
import com.jogamp.opengl.test.junit.jogl.demos.GearsObject;
import com.jogamp.opengl.util.GLArrayDataServer;
import com.jogamp.opengl.util.PMVMatrix;
@@ -53,7 +52,7 @@ public class GearsObjectES2 extends GearsObject {
this.colorUniform = colorUniform;
}
- public GearsObjectES2(GearsObject shared,
+ public GearsObjectES2(GearsObjectES2 shared,
PMVMatrix pmvMatrix,
GLUniformData pmvMatrixUniform,
GLUniformData colorUniform)
@@ -70,10 +69,9 @@ public class GearsObjectES2 extends GearsObject {
}
@Override
- public void addInterleavedVertexAndNormalArrays(GLArrayDataServer array,
- int components) {
- array.addGLSLSubArray("vertices", 3, GL.GL_ARRAY_BUFFER);
- array.addGLSLSubArray("normals", 3, GL.GL_ARRAY_BUFFER);
+ public void addInterleavedVertexAndNormalArrays(GLArrayDataServer array, int components) {
+ array.addGLSLSubArray("vertices", components, GL.GL_ARRAY_BUFFER);
+ array.addGLSLSubArray("normals", components, GL.GL_ARRAY_BUFFER);
}
private void draw(GL2ES2 gl, GLArrayDataServer array, int mode) {
@@ -89,8 +87,11 @@ public class GearsObjectES2 extends GearsObject {
pmvMatrix.glPushMatrix();
pmvMatrix.glTranslatef(x, y, 0f);
pmvMatrix.glRotatef(angle, 0f, 0f, 1f);
- pmvMatrix.update();
- st.uniform(gl, pmvMatrixUniform);
+ if( pmvMatrix.update() ) {
+ st.uniform(gl, pmvMatrixUniform);
+ } else {
+ throw new InternalError("PMVMatrix.update() returns false after mutable operations");
+ }
colorUniform.setData(color);
st.uniform(gl, colorUniform);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/FBOMix2DemosES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/Mix2TexturesES2.java
similarity index 59%
copy from src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/FBOMix2DemosES2.java
copy to src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/Mix2TexturesES2.java
index 3dfbb48..26e7e23 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/FBOMix2DemosES2.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/Mix2TexturesES2.java
@@ -29,68 +29,49 @@ import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLUniformData;
import javax.media.opengl.fixedfunc.GLMatrixFunc;
-import com.jogamp.opengl.FBObject;
-import com.jogamp.opengl.FBObject.TextureAttachment;
-import com.jogamp.opengl.FBObject.Attachment.Type;
import com.jogamp.opengl.util.GLArrayDataServer;
import com.jogamp.opengl.util.PMVMatrix;
import com.jogamp.opengl.util.glsl.ShaderCode;
import com.jogamp.opengl.util.glsl.ShaderProgram;
import com.jogamp.opengl.util.glsl.ShaderState;
-public class FBOMix2DemosES2 implements GLEventListener {
- private final GearsES2 demo0;
- private final RedSquareES2 demo1;
+public class Mix2TexturesES2 implements GLEventListener {
private final int swapInterval;
- private int numSamples;
- private boolean demo0Only;
-
private final ShaderState st;
private final PMVMatrix pmvMatrix;
+ private final GLUniformData texUnit0, texUnit1;
- private final FBObject fbo0;
- private final FBObject fbo1;
-
- private TextureAttachment fbo0Tex;
- private TextureAttachment fbo1Tex;
-
+ private volatile int texID0, texID1;
private ShaderProgram sp0;
private GLUniformData pmvMatrixUniform;
private GLArrayDataServer interleavedVBO;
- private GLUniformData texUnit0;
- private GLUniformData texUnit1;
- public FBOMix2DemosES2(int swapInterval) {
- demo0 = new GearsES2(-1);
- demo0.setIsFBOSlave(true);
- demo1 = new RedSquareES2(-1);
- demo1.setIsFBOSlave(true);
+ public Mix2TexturesES2(int swapInterval, int texUnit0, int texUnit1) {
this.swapInterval = swapInterval;
st = new ShaderState();
// st.setVerbose(true);
pmvMatrix = new PMVMatrix();
- fbo0 = new FBObject();
- fbo1 = new FBObject();
-
- numSamples = 0;
- demo0Only = false;
+ if(0 == texUnit1) {
+ this.texUnit0 = new GLUniformData("mgl_ActiveTexture", texUnit0);
+ this.texUnit1 = null;
+ } else {
+ this.texUnit0 = new GLUniformData("mgl_Texture0", texUnit0);
+ this.texUnit1 = new GLUniformData("mgl_Texture1", texUnit1);
+ }
+ this.texID0 = 0;
+ this.texID1 = 0;
}
- public void setDemo0Only(boolean v) {
- this.demo0Only = v;
+ public void setTexID0(int texID) {
+ this.texID0 = texID;
}
- public boolean getDemo0Only() { return demo0Only; }
-
- public void setMSAA(int numSamples) {
- this.numSamples=numSamples;
+ public void setTexID1(int texID) {
+ this.texID1 = texID;
}
- public int getMSAA() { return numSamples; }
-
- public void setDoRotation(boolean rotate) { demo1.setDoRotation(rotate); }
-
+
static final String[] es2_prelude = { "#version 100\n", "precision mediump float;\n" };
static final String gl2_prelude = "#version 110\n";
@@ -98,13 +79,10 @@ public class FBOMix2DemosES2 implements GLEventListener {
public void init(GLAutoDrawable drawable) {
final GL2ES2 gl = drawable.getGL().getGL2ES2();
- demo0.init(drawable);
- demo1.init(drawable);
-
- final ShaderCode vp0 = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, FBOMix2DemosES2.class, "shader",
+ final ShaderCode vp0 = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, Mix2TexturesES2.class, "shader",
"shader/bin", "texture01_xxx", true);
- final ShaderCode fp0 = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, FBOMix2DemosES2.class, "shader",
- "shader/bin", "texture02_xxx", true);
+ final ShaderCode fp0 = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, Mix2TexturesES2.class, "shader",
+ "shader/bin", null == texUnit1 ? "texture01_xxx" : "texture02_xxx", true);
// Prelude shader code w/ GLSL profile specifics [ 1. pre-proc, 2. other ]
int fp0Pos;
@@ -148,63 +126,21 @@ public class FBOMix2DemosES2 implements GLEventListener {
interleavedVBO.enableBuffer(gl, false);
st.ownAttribute(interleavedVBO, true);
- texUnit0 = new GLUniformData("mgl_Texture0", 0);
- st.ownUniform(texUnit0);
+ st.ownUniform(texUnit0);
st.uniform(gl, texUnit0);
- texUnit1 = new GLUniformData("mgl_Texture1", 1);
- st.ownUniform(texUnit1);
- st.uniform(gl, texUnit1);
-
- st.useProgram(gl, false);
-
- System.err.println("**** Init");
- resetFBOs(gl, drawable);
-
- fbo0.attachRenderbuffer(gl, Type.DEPTH, 24);
- fbo0.unbind(gl);
- fbo1.attachRenderbuffer(gl, Type.DEPTH, 24);
- fbo1.unbind(gl);
- gl.glEnable(GL2ES2.GL_DEPTH_TEST);
+ if(null != texUnit1) {
+ st.ownUniform(texUnit1);
+ st.uniform(gl, texUnit1);
+ }
- numSamples=fbo0.getNumSamples();
+ st.useProgram(gl, false);
}
- /** Since we switch MSAA and non-MSAA we need to take extra care, i.e. sync msaa for both FBOs ..*/
- private void resetFBOs(GL gl, GLAutoDrawable drawable) {
- // remove all texture attachments, since MSAA uses just color-render-buffer
- // and non-MSAA uses texture2d-buffer
- fbo0.detachAllColorbuffer(gl);
- fbo1.detachAllColorbuffer(gl);
-
- fbo0.reset(gl, drawable.getWidth(), drawable.getHeight(), numSamples);
- fbo1.reset(gl, drawable.getWidth(), drawable.getHeight(), numSamples);
- if(fbo0.getNumSamples() != fbo1.getNumSamples()) {
- throw new InternalError("sample size mismatch: \n\t0: "+fbo0+"\n\t1: "+fbo1);
- }
- numSamples = fbo0.getNumSamples();
-
- if(numSamples>0) {
- fbo0.attachColorbuffer(gl, 0, true);
- fbo1.attachColorbuffer(gl, 0, true);
- fbo0Tex = fbo0.getSamplingSink();
- fbo1Tex = fbo1.getSamplingSink();
- } else {
- fbo0Tex = fbo0.attachTexture2D(gl, 0, true);
- fbo1Tex = fbo1.attachTexture2D(gl, 0, true);
- }
- }
-
@Override
public void dispose(GLAutoDrawable drawable) {
final GL2ES2 gl = drawable.getGL().getGL2ES2();
- demo0.dispose(drawable);
- demo1.dispose(drawable);
- fbo0.destroy(gl);
- fbo1.destroy(gl);
st.destroy(gl);
- fbo0Tex = null;
- fbo1Tex = null;
sp0 = null;
pmvMatrixUniform = null;
interleavedVBO = null;
@@ -214,44 +150,27 @@ public class FBOMix2DemosES2 implements GLEventListener {
public void display(GLAutoDrawable drawable) {
final GL2ES2 gl = drawable.getGL().getGL2ES2();
- if( fbo0.getNumSamples() != numSamples ) {
- System.err.println("**** NumSamples: "+fbo0.getNumSamples()+" -> "+numSamples);
- resetFBOs(gl, drawable);
- }
-
- if(0 < numSamples) {
- gl.glEnable(GL.GL_MULTISAMPLE);
- }
-
- fbo0.bind(gl);
- demo0.display(drawable);
- fbo0.unbind(gl);
-
- if(!demo0Only) {
- fbo1.bind(gl);
- demo1.display(drawable);
- fbo1.unbind(gl);
- }
-
st.useProgram(gl, true);
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
- gl.glActiveTexture(GL.GL_TEXTURE0 + texUnit0.intValue());
- fbo0.use(gl, fbo0Tex);
- if(!demo0Only) {
+ interleavedVBO.enableBuffer(gl, true);
+
+ if(0<texID0) {
+ gl.glActiveTexture(GL.GL_TEXTURE0 + texUnit0.intValue());
+ gl.glBindTexture(GL.GL_TEXTURE_2D, texID0);
+ }
+
+ if(0<texID1 && null != texUnit1) {
gl.glActiveTexture(GL.GL_TEXTURE0 + texUnit1.intValue());
- fbo1.use(gl, fbo1Tex);
+ gl.glBindTexture(GL.GL_TEXTURE_2D, texID1);
}
- interleavedVBO.enableBuffer(gl, true);
+
+ gl.glEnable(GL.GL_TEXTURE_2D);
gl.glDrawArrays(GL.GL_TRIANGLE_STRIP, 0, 4);
interleavedVBO.enableBuffer(gl, false);
- fbo0.unuse(gl);
- if(!demo0Only) {
- fbo1.unuse(gl);
- }
st.useProgram(gl, false);
}
@@ -264,18 +183,6 @@ public class FBOMix2DemosES2 implements GLEventListener {
gl.setSwapInterval(swapInterval); // in case switching the drawable (impl. may bound attribute there)
}
- // if(drawable.getWidth() == fbo0.getWidth() && drawable.getHeight() == fbo0.getHeight() ) {
- System.err.println("**** Reshape: "+width+"x"+height);
- resetFBOs(gl, drawable);
- //}
-
- fbo0.bind(gl);
- demo0.reshape(drawable, x, y, width, height);
- fbo0.unbind(gl);
- fbo1.bind(gl);
- demo1.reshape(drawable, x, y, width, height);
- fbo1.unbind(gl);
-
pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
pmvMatrix.glLoadIdentity();
pmvMatrix.glOrthof(-1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 10.0f);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/MultisampleDemoES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/MultisampleDemoES2.java
index 5facc1a..691e08e 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/MultisampleDemoES2.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/MultisampleDemoES2.java
@@ -74,12 +74,15 @@ public class MultisampleDemoES2 implements GLEventListener {
public void init(GLAutoDrawable glad) {
final GL2ES2 gl = glad.getGL().getGL2ES2();
+
System.err.println();
+ System.err.println("req. msaa: "+multisample);
System.err.println("Requested: " + glad.getNativeSurface().getGraphicsConfiguration().getRequestedCapabilities());
- System.err.println();
+ multisample = multisample & glad.getChosenGLCapabilities().getNumSamples() > 0 ;
System.err.println("Chosen : " + glad.getChosenGLCapabilities());
+ System.err.println("has msaa: "+multisample);
System.err.println();
-
+
final ShaderCode vp0 = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, MultisampleDemoES2.class, "shader",
"shader/bin", "mgl_default_xxx", true);
final ShaderCode fp0 = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, MultisampleDemoES2.class, "shader",
@@ -109,11 +112,12 @@ public class MultisampleDemoES2 implements GLEventListener {
// Using predef array names, see
// GLPointerFuncUtil.getPredefinedArrayIndexName(glArrayIndex);
- immModeSink = ImmModeSink.createGLSL(gl, GL.GL_STATIC_DRAW, 40,
+ immModeSink = ImmModeSink.createGLSL(40,
3, GL.GL_FLOAT, // vertex
4, GL.GL_FLOAT, // color
- 0, GL.GL_FLOAT,// normal
- 0, GL.GL_FLOAT); // texture
+ 0, GL.GL_FLOAT, // normal
+ 0, GL.GL_FLOAT, // texCoords
+ GL.GL_STATIC_DRAW);
final int numSteps = 20;
final double increment = Math.PI / numSteps;
final double radius = 1;
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/PointsDemoES2.java
similarity index 55%
copy from src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareES2.java
copy to src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/PointsDemoES2.java
index a956fe1..1e0f959 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareES2.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/PointsDemoES2.java
@@ -1,5 +1,5 @@
/**
- * Copyright 2010 JogAmp Community. All rights reserved.
+ * Copyright 2012 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
@@ -27,69 +27,75 @@
*/
package com.jogamp.opengl.test.junit.jogl.demos.es2;
-import com.jogamp.newt.Window;
+import java.nio.FloatBuffer;
+
+import com.jogamp.common.nio.Buffers;
+import com.jogamp.opengl.test.junit.jogl.demos.PointsDemo;
import com.jogamp.opengl.util.GLArrayDataServer;
import com.jogamp.opengl.util.PMVMatrix;
import com.jogamp.opengl.util.glsl.ShaderCode;
import com.jogamp.opengl.util.glsl.ShaderProgram;
import com.jogamp.opengl.util.glsl.ShaderState;
+
import javax.media.opengl.GL;
+import javax.media.opengl.GL2ES1;
import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GL2GL3;
import javax.media.opengl.GLAutoDrawable;
-import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLUniformData;
-public class RedSquareES2 implements GLEventListener {
+public class PointsDemoES2 extends PointsDemo {
ShaderState st;
PMVMatrix pmvMatrix;
GLUniformData pmvMatrixUniform;
GLArrayDataServer vertices ;
- GLArrayDataServer colors ;
- long t0;
+ GLArrayDataServer pointSizes ;
private int swapInterval = 0;
- Window window = null;
- float aspect = 1.0f;
- boolean doRotate = true;
- boolean isInitialized = false;
- boolean isFBOSlave = false;
+ final int edge = 8; // 8*8
+ /** vec4[2]: { (sz, smooth, attnMinSz, attnMaxSz), (attnCoeff(3), attnFadeTs) } */
+ private static final String mgl_PointParams = "mgl_PointParams";
+
+ /** ( pointSize, pointSmooth, attn. pointMinSize, attn. pointMaxSize ) , ( attenuation coefficients 1f 0f 0f, attenuation fade theshold 1f ) */
+ private final FloatBuffer pointParams = Buffers.newDirectFloatBuffer(new float[] { 1.0f, 0.0f, 0.0f, 4096.0f, 1.0f, 0.0f, 0.0f, 1.0f });
- public RedSquareES2(int swapInterval) {
+ public PointsDemoES2(int swapInterval) {
this.swapInterval = swapInterval;
}
- public RedSquareES2() {
+ public PointsDemoES2() {
this.swapInterval = 1;
}
+
+ public void setSmoothPoints(boolean v) {
+ pointParams.put(1, v ? 1.0f : 0.0f);
+ }
- public void setIsFBOSlave(boolean v) { isFBOSlave = v; }
- public void setAspect(float aspect) { this.aspect = aspect; }
- public void setDoRotation(boolean rotate) { this.doRotate = rotate; }
+ public void setPointParams(float minSize, float maxSize, float distAttenConst, float distAttenLinear, float distAttenQuadratic, float fadeThreshold) {
+ pointParams.put(2, minSize);
+ pointParams.put(3, maxSize);
+ pointParams.put(4+0, distAttenConst);
+ pointParams.put(4+1, distAttenLinear);
+ pointParams.put(4+2, distAttenQuadratic);
+ pointParams.put(4+3, fadeThreshold);
+ }
public void init(GLAutoDrawable glad) {
- if(isInitialized) {
- System.err.println(Thread.currentThread()+" RedSquareES2.init skipped!");
- return;
- }
- isInitialized = true;
- System.err.println(Thread.currentThread()+" RedSquareES2.init ...");
GL2ES2 gl = glad.getGL().getGL2ES2();
- System.err.println(Thread.currentThread()+"Chosen GLCapabilities: " + glad.getChosenGLCapabilities());
- System.err.println(Thread.currentThread()+"INIT GL IS: " + gl.getClass().getName());
- System.err.println(Thread.currentThread()+"GL_VENDOR: " + gl.glGetString(GL.GL_VENDOR));
- System.err.println(Thread.currentThread()+"GL_RENDERER: " + gl.glGetString(GL.GL_RENDERER));
- System.err.println(Thread.currentThread()+"GL_VERSION: " + gl.glGetString(GL.GL_VERSION));
-
- System.err.println(Thread.currentThread()+" GL Profile: "+gl.getGLProfile());
- System.err.println(Thread.currentThread()+" GL:" + gl);
- System.err.println(Thread.currentThread()+" GL_VERSION=" + gl.glGetString(GL.GL_VERSION));
+ System.err.println("GL_VENDOR: " + gl.glGetString(GL.GL_VENDOR));
+ System.err.println("GL_RENDERER: " + gl.glGetString(GL.GL_RENDERER));
+ System.err.println("GL_VERSION: " + gl.glGetString(GL.GL_VERSION));
+ System.err.println("GL GLSL: "+gl.hasGLSL()+", has-compiler: "+gl.isFunctionAvailable("glCompileShader")+", version "+(gl.hasGLSL() ? gl.glGetString(GL2ES2.GL_SHADING_LANGUAGE_VERSION) : "none"));
+ System.err.println("GL Profile: "+gl.getGLProfile());
st = new ShaderState();
st.setVerbose(true);
final ShaderCode vp0 = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, this.getClass(), "shader",
- "shader/bin", "RedSquareShader", false);
+ "shader/bin", "PointsShader", true);
final ShaderCode fp0 = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, this.getClass(), "shader",
- "shader/bin", "RedSquareShader", false);
+ "shader/bin", "PointsShader", true);
+ vp0.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_vp);
+ fp0.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_fp);
final ShaderProgram sp0 = new ShaderProgram();
sp0.add(gl, vp0, System.err);
sp0.add(gl, fp0, System.err);
@@ -105,63 +111,78 @@ public class RedSquareES2 implements GLEventListener {
st.ownUniform(pmvMatrixUniform);
st.uniform(gl, pmvMatrixUniform);
+ st.uniform(gl, new GLUniformData(mgl_PointParams, 4, pointParams));
+
+ final GLUniformData colorStaticUniform = new GLUniformData("mgl_ColorStatic", 4, Buffers.newDirectFloatBuffer(new float[] { 1.0f, 1.0f, 1.0f, 1.0f }) );
+ st.uniform(gl, colorStaticUniform);
+ st.ownUniform(colorStaticUniform);
+
// Allocate Vertex Array
- vertices = GLArrayDataServer.createGLSL("mgl_Vertex", 3, GL.GL_FLOAT, false, 4, GL.GL_STATIC_DRAW);
- vertices.putf(-2); vertices.putf( 2); vertices.putf( 0);
- vertices.putf( 2); vertices.putf( 2); vertices.putf( 0);
- vertices.putf(-2); vertices.putf(-2); vertices.putf( 0);
- vertices.putf( 2); vertices.putf(-2); vertices.putf( 0);
+ vertices = GLArrayDataServer.createGLSL("mgl_Vertex", 3, GL.GL_FLOAT, false, edge*edge, GL.GL_STATIC_DRAW);
+ pointSizes = GLArrayDataServer.createGLSL("mgl_PointSize", 1, GL.GL_FLOAT, false, edge*edge, GL.GL_STATIC_DRAW);
+ for(int i=0; i<edge; i++) {
+ for(int j=0; j<edge; j++) {
+ final float x = -3+j*0.7f;
+ final float y = -3+i*0.7f;
+ final float p = (i*edge+j)*0.5f;
+ // System.err.println("["+j+"/"+i+"]: "+x+"/"+y+": "+p);
+ vertices.putf(x); vertices.putf(y); vertices.putf( 0);
+ pointSizes.putf(p);
+ }
+ }
vertices.seal(gl, true);
st.ownAttribute(vertices, true);
vertices.enableBuffer(gl, false);
-
- // Allocate Color Array
- colors= GLArrayDataServer.createGLSL("mgl_Color", 4, GL.GL_FLOAT, false, 4, GL.GL_STATIC_DRAW);
- colors.putf(1); colors.putf(0); colors.putf(0); colors.putf(1);
- colors.putf(0); colors.putf(0); colors.putf(1); colors.putf(1);
- colors.putf(1); colors.putf(0); colors.putf(0); colors.putf(1);
- colors.putf(1); colors.putf(0); colors.putf(0); colors.putf(1);
- colors.seal(gl, true);
- st.ownAttribute(colors, true);
- colors.enableBuffer(gl, false);
-
+ pointSizes.seal(gl, true);
+ st.ownAttribute(pointSizes, true);
+ pointSizes.enableBuffer(gl, false);
+
// OpenGL Render Settings
gl.glEnable(GL2ES2.GL_DEPTH_TEST);
st.useProgram(gl, false);
-
- t0 = System.currentTimeMillis();
- System.err.println(Thread.currentThread()+" RedSquareES2.init FIN");
}
public void display(GLAutoDrawable glad) {
- long t1 = System.currentTimeMillis();
-
GL2ES2 gl = glad.getGL().getGL2ES2();
- gl.glClearColor(0, 0, 0, 0);
+ gl.glClearColor(0f, 0f, 0f, 0f);
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
st.useProgram(gl, true);
- // One rotation every four seconds
pmvMatrix.glMatrixMode(PMVMatrix.GL_MODELVIEW);
pmvMatrix.glLoadIdentity();
pmvMatrix.glTranslatef(0, 0, -10);
- if(doRotate) {
- float ang = ((float) (t1 - t0) * 360.0F) / 4000.0F;
- pmvMatrix.glRotatef(ang, 0, 0, 1);
- pmvMatrix.glRotatef(ang, 0, 1, 0);
- }
st.uniform(gl, pmvMatrixUniform);
- // Draw a square
+ GLUniformData ud = st.getUniform(mgl_PointParams);
+ if(null!=ud) {
+ // same data object
+ st.uniform(gl, ud);
+ }
+
vertices.enableBuffer(gl, true);
- colors.enableBuffer(gl, true);
- gl.glDrawArrays(GL.GL_TRIANGLE_STRIP, 0, 4);
+ pointSizes.enableBuffer(gl, true);
+
+ if(gl.isGL2GL3()) {
+ gl.glEnable(GL2GL3.GL_VERTEX_PROGRAM_POINT_SIZE);
+ }
+ if(gl.isGL2ES1()) {
+ gl.glEnable(GL2ES1.GL_POINT_SPRITE); // otherwise no gl_PointCoord
+ }
+ gl.glEnable ( GL.GL_BLEND );
+ gl.glBlendFunc ( GL.GL_SRC_ALPHA, GL.GL_ONE );
+
+ gl.glDrawArrays(GL.GL_POINTS, 0, edge*edge);
+
+ if(gl.isGL2GL3()) {
+ gl.glDisable(GL2GL3.GL_VERTEX_PROGRAM_POINT_SIZE);
+ }
+
+ pointSizes.enableBuffer(gl, false);
vertices.enableBuffer(gl, false);
- colors.enableBuffer(gl, false);
st.useProgram(gl, false);
}
public void reshape(GLAutoDrawable glad, int x, int y, int width, int height) {
- System.err.println(Thread.currentThread()+" RedSquareES2.reshape "+x+"/"+y+" "+width+"x"+height+", swapInterval "+swapInterval);
+ // Thread.dumpStack();
GL2ES2 gl = glad.getGL().getGL2ES2();
if(-1 != swapInterval) {
@@ -172,26 +193,17 @@ public class RedSquareES2 implements GLEventListener {
// Set location in front of camera
pmvMatrix.glMatrixMode(PMVMatrix.GL_PROJECTION);
pmvMatrix.glLoadIdentity();
- pmvMatrix.gluPerspective(45.0F, ( (float) width / (float) height ) / aspect, 1.0F, 100.0F);
+ pmvMatrix.gluPerspective(45.0F, ( (float) width / (float) height ) / 1.0f, 1.0F, 100.0F);
//pmvMatrix.glOrthof(-4.0f, 4.0f, -4.0f, 4.0f, 1.0f, 100.0f);
st.uniform(gl, pmvMatrixUniform);
st.useProgram(gl, false);
-
- System.err.println(Thread.currentThread()+" RedSquareES2.reshape FIN");
}
public void dispose(GLAutoDrawable glad) {
- if(!isInitialized) {
- System.err.println(Thread.currentThread()+" RedSquareES2.dispose skipped!");
- return;
- }
- isInitialized = false;
- System.err.println(Thread.currentThread()+" RedSquareES2.dispose ... ");
GL2ES2 gl = glad.getGL().getGL2ES2();
st.destroy(gl);
st = null;
pmvMatrix.destroy();
pmvMatrix = null;
- System.err.println(Thread.currentThread()+" RedSquareES2.dispose FIN");
}
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareES2.java
index a956fe1..bf1ca5c 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareES2.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareES2.java
@@ -51,7 +51,6 @@ public class RedSquareES2 implements GLEventListener {
float aspect = 1.0f;
boolean doRotate = true;
boolean isInitialized = false;
- boolean isFBOSlave = false;
public RedSquareES2(int swapInterval) {
this.swapInterval = swapInterval;
@@ -61,7 +60,6 @@ public class RedSquareES2 implements GLEventListener {
this.swapInterval = 1;
}
- public void setIsFBOSlave(boolean v) { isFBOSlave = v; }
public void setAspect(float aspect) { this.aspect = aspect; }
public void setDoRotation(boolean rotate) { this.doRotate = rotate; }
@@ -74,22 +72,26 @@ public class RedSquareES2 implements GLEventListener {
System.err.println(Thread.currentThread()+" RedSquareES2.init ...");
GL2ES2 gl = glad.getGL().getGL2ES2();
- System.err.println(Thread.currentThread()+"Chosen GLCapabilities: " + glad.getChosenGLCapabilities());
- System.err.println(Thread.currentThread()+"INIT GL IS: " + gl.getClass().getName());
- System.err.println(Thread.currentThread()+"GL_VENDOR: " + gl.glGetString(GL.GL_VENDOR));
- System.err.println(Thread.currentThread()+"GL_RENDERER: " + gl.glGetString(GL.GL_RENDERER));
- System.err.println(Thread.currentThread()+"GL_VERSION: " + gl.glGetString(GL.GL_VERSION));
-
- System.err.println(Thread.currentThread()+" GL Profile: "+gl.getGLProfile());
- System.err.println(Thread.currentThread()+" GL:" + gl);
- System.err.println(Thread.currentThread()+" GL_VERSION=" + gl.glGetString(GL.GL_VERSION));
+ System.err.println("RedSquareES2 init on "+Thread.currentThread());
+ System.err.println("Chosen GLCapabilities: " + glad.getChosenGLCapabilities());
+ System.err.println("INIT GL IS: " + gl.getClass().getName());
+ System.err.println("GL_VENDOR: " + gl.glGetString(GL.GL_VENDOR));
+ System.err.println("GL_RENDERER: " + gl.glGetString(GL.GL_RENDERER));
+ System.err.println("GL_VERSION: " + gl.glGetString(GL.GL_VERSION));
+ System.err.println("GL GLSL: "+gl.hasGLSL()+", has-compiler: "+gl.isFunctionAvailable("glCompileShader")+", version "+(gl.hasGLSL() ? gl.glGetString(GL2ES2.GL_SHADING_LANGUAGE_VERSION) : "none"));
+ System.err.println("GL FBO: basic "+ gl.hasBasicFBOSupport()+", full "+gl.hasFullFBOSupport());
+ System.err.println("GL Profile: "+gl.getGLProfile());
+ System.err.println("GL Renderer Quirks:" + gl.getContext().getRendererQuirks().toString());
+ System.err.println("GL:" + gl + ", " + gl.getContext().getGLVersion());
st = new ShaderState();
st.setVerbose(true);
final ShaderCode vp0 = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, this.getClass(), "shader",
- "shader/bin", "RedSquareShader", false);
+ "shader/bin", "RedSquareShader", true);
final ShaderCode fp0 = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, this.getClass(), "shader",
- "shader/bin", "RedSquareShader", false);
+ "shader/bin", "RedSquareShader", true);
+ vp0.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_vp);
+ fp0.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_fp);
final ShaderProgram sp0 = new ShaderProgram();
sp0.add(gl, vp0, System.err);
sp0.add(gl, fp0, System.err);
@@ -161,7 +163,8 @@ public class RedSquareES2 implements GLEventListener {
}
public void reshape(GLAutoDrawable glad, int x, int y, int width, int height) {
- System.err.println(Thread.currentThread()+" RedSquareES2.reshape "+x+"/"+y+" "+width+"x"+height+", swapInterval "+swapInterval);
+ System.err.println(Thread.currentThread()+" RedSquareES2.reshape "+x+"/"+y+" "+width+"x"+height+", swapInterval "+swapInterval+", drawable 0x"+Long.toHexString(glad.getHandle()));
+ // Thread.dumpStack();
GL2ES2 gl = glad.getGL().getGL2ES2();
if(-1 != swapInterval) {
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureDraw01ES2Listener.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureDraw01ES2Listener.java
index 6e70165..4bcb073 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureDraw01ES2Listener.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureDraw01ES2Listener.java
@@ -62,8 +62,6 @@ public class TextureDraw01ES2Listener implements GLEventListener, TextureDraw01A
this.textureData = td;
}
- static final String[] es2_prelude = { "#version 100\n", "precision mediump float;\n" };
- static final String gl2_prelude = "#version 110\n";
static final String shaderBasename = "texture01_xxx";
private void initShader(GL2ES2 gl, boolean use_program) {
@@ -72,19 +70,8 @@ public class TextureDraw01ES2Listener implements GLEventListener, TextureDraw01A
"shader", "shader/bin", shaderBasename, true);
ShaderCode rsFp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, this.getClass(),
"shader", "shader/bin", shaderBasename, true);
-
- // Prelude shader code w/ GLSL profile specifics [ 1. pre-proc, 2. other ]
- int rsFpPos;
- if(gl.isGLES2()) {
- rsVp.insertShaderSource(0, 0, es2_prelude[0]);
- rsFpPos = rsFp.insertShaderSource(0, 0, es2_prelude[0]);
- } else {
- rsVp.insertShaderSource(0, 0, gl2_prelude);
- rsFpPos = rsFp.insertShaderSource(0, 0, gl2_prelude);
- }
- if(gl.isGLES2()) {
- rsFpPos = rsFp.insertShaderSource(0, rsFpPos, es2_prelude[1]);
- }
+ rsVp.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_vp);
+ rsFp.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_fp);
// Create & Link the shader program
ShaderProgram sp = new ShaderProgram();
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2AWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2AWT.java
index b3fdaa0..07899b7 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2AWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2AWT.java
@@ -60,12 +60,16 @@ import org.junit.Test;
public class TestGearsES2AWT extends UITestCase {
static int width, height;
- static boolean firstUIActionOnProcess = false;
static boolean forceES2 = false;
+ static boolean forceGL3 = false;
static boolean shallUseOffscreenLayer = false;
+ static boolean shallUseOffscreenPBufferLayer = false;
+ static boolean useMSAA = false;
static boolean addComp = true;
+ static boolean shutdownRemoveGLCanvas = true;
+ static boolean shutdownDisposeFrame = true;
+ static boolean shutdownSystemExit = false;
static int swapInterval = 1;
- static boolean showFPS = false;
@BeforeClass
public static void initClass() {
@@ -83,7 +87,6 @@ public class TestGearsES2AWT extends UITestCase {
final GLCanvas glCanvas = new GLCanvas(caps);
Assert.assertNotNull(glCanvas);
- glCanvas.setShallUseOffscreenLayer(shallUseOffscreenLayer);
Dimension glc_sz = new Dimension(width, height);
glCanvas.setMinimumSize(glc_sz);
glCanvas.setPreferredSize(glc_sz);
@@ -112,8 +115,8 @@ public class TestGearsES2AWT extends UITestCase {
frame.pack();
frame.setVisible(true);
}});
- animator.setUpdateFPSFrames(60, System.err);
animator.start();
+ animator.setUpdateFPSFrames(60, System.err);
while(!quitAdapter.shouldQuit() /* && animator.isAnimating() */ && animator.getTotalFPSDuration()<duration) {
Thread.sleep(100);
@@ -129,14 +132,39 @@ public class TestGearsES2AWT extends UITestCase {
Assert.assertEquals(false, frame.isVisible());
javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
- frame.remove(glCanvas);
- frame.dispose();
+ if(shutdownRemoveGLCanvas) {
+ frame.remove(glCanvas);
+ }
+ if(shutdownDisposeFrame) {
+ frame.dispose();
+ }
+ if(shutdownSystemExit) {
+ System.exit(0);
+ }
}});
}
@Test
public void test01() throws InterruptedException, InvocationTargetException {
- GLCapabilities caps = new GLCapabilities(forceES2 ? GLProfile.get(GLProfile.GLES2) : GLProfile.getGL2ES2());
+ final GLProfile glp;
+ if(forceGL3) {
+ glp = GLProfile.get(GLProfile.GL3);
+ } else if(forceES2) {
+ glp = GLProfile.get(GLProfile.GLES2);
+ } else {
+ glp = GLProfile.getGL2ES2();
+ }
+ final GLCapabilities caps = new GLCapabilities(glp);
+ if(useMSAA) {
+ caps.setNumSamples(4);
+ caps.setSampleBuffers(true);
+ }
+ if(shallUseOffscreenLayer) {
+ caps.setOnscreen(false);
+ }
+ if(shallUseOffscreenPBufferLayer) {
+ caps.setPBuffer(true);
+ }
runTestGL(caps);
}
@@ -153,22 +181,34 @@ public class TestGearsES2AWT extends UITestCase {
} catch (Exception ex) { ex.printStackTrace(); }
} else if(args[i].equals("-es2")) {
forceES2 = true;
+ } else if(args[i].equals("-gl3")) {
+ forceGL3 = true;
} else if(args[i].equals("-vsync")) {
i++;
swapInterval = MiscUtils.atoi(args[i], swapInterval);
} else if(args[i].equals("-layered")) {
shallUseOffscreenLayer = true;
- } else if(args[i].equals("-showFPS")) {
- showFPS = true;
- } else if(args[i].equals("-firstUIAction")) {
- firstUIActionOnProcess = true;
+ } else if(args[i].equals("-layeredPBuffer")) {
+ shallUseOffscreenPBufferLayer = true;
+ } else if(args[i].equals("-msaa")) {
+ useMSAA = true;
} else if(args[i].equals("-wait")) {
waitForKey = true;
} else if(args[i].equals("-justGears")) {
addComp = false;
+ } else if(args[i].equals("-shutdownKeepGLCanvas")) {
+ shutdownRemoveGLCanvas = false;
+ } else if(args[i].equals("-shutdownKeepFrame")) {
+ shutdownDisposeFrame = false;
+ } else if(args[i].equals("-shutdownKeepAll")) {
+ shutdownRemoveGLCanvas = false;
+ shutdownDisposeFrame = false;
+ } else if(args[i].equals("-shutdownSystemExit")) {
+ shutdownSystemExit = true;
}
}
System.err.println("forceES2 "+forceES2);
+ System.err.println("forceGL3 "+forceGL3);
System.err.println("swapInterval "+swapInterval);
System.err.println("shallUseOffscreenLayer "+shallUseOffscreenLayer);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java
index fab5bf9..86831a6 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java
@@ -75,6 +75,7 @@ public class TestGearsES2NEWT extends UITestCase {
static long duration = 500; // ms
static boolean opaque = true;
+ static int forceAlpha = -1;
static boolean undecorated = false;
static boolean alwaysOnTop = false;
static boolean fullscreen = false;
@@ -85,8 +86,10 @@ public class TestGearsES2NEWT extends UITestCase {
static boolean mouseConfined = false;
static boolean showFPS = false;
static int loops = 1;
- static GLProfile.ShutdownType loop_shutdown = null;
+ static boolean loop_shutdown = false;
static boolean forceES2 = false;
+ static boolean forceGL3 = false;
+ static boolean mainRun = false;
@BeforeClass
public static void initClass() {
@@ -255,16 +258,41 @@ public class TestGearsES2NEWT extends UITestCase {
public void test01GL2ES2() throws InterruptedException {
for(int i=1; i<=loops; i++) {
System.err.println("Loop "+i+"/"+loops);
- GLCapabilities caps = new GLCapabilities(forceES2 ? GLProfile.get(GLProfile.GLES2) : GLProfile.getGL2ES2());
+ final GLProfile glp;
+ if(forceGL3) {
+ glp = GLProfile.get(GLProfile.GL3);
+ } else if(forceES2) {
+ glp = GLProfile.get(GLProfile.GLES2);
+ } else {
+ glp = GLProfile.getGL2ES2();
+ }
+ final GLCapabilities caps = new GLCapabilities( glp );
caps.setBackgroundOpaque(opaque);
+ if(-1 < forceAlpha) {
+ caps.setAlphaBits(forceAlpha);
+ }
runTestGL(caps, undecorated);
- if(null != loop_shutdown) {
- GLProfile.shutdown(loop_shutdown);
+ if(loop_shutdown) {
+ GLProfile.shutdown();
}
}
}
- public static void main(String args[]) throws IOException {
+ @Test
+ public void test02GL3() throws InterruptedException {
+ if(mainRun) return;
+
+ if( !GLProfile.isAvailable(GLProfile.GL3) ) {
+ System.err.println("GL3 n/a");
+ }
+ final GLProfile glp = GLProfile.get(GLProfile.GL3);
+ final GLCapabilities caps = new GLCapabilities( glp );
+ runTestGL(caps, undecorated);
+ }
+
+ public static void main(String args[]) throws IOException {
+ mainRun = true;
+
int x=0, y=0, w=640, h=480;
boolean usePos = false;
@@ -274,6 +302,9 @@ public class TestGearsES2NEWT extends UITestCase {
duration = MiscUtils.atol(args[i], duration);
} else if(args[i].equals("-translucent")) {
opaque = false;
+ } else if(args[i].equals("-forceAlpha")) {
+ i++;
+ forceAlpha = MiscUtils.atoi(args[i], 0);
} else if(args[i].equals("-undecorated")) {
undecorated = true;
} else if(args[i].equals("-atop")) {
@@ -287,6 +318,8 @@ public class TestGearsES2NEWT extends UITestCase {
swapInterval = MiscUtils.atoi(args[i], swapInterval);
} else if(args[i].equals("-es2")) {
forceES2 = true;
+ } else if(args[i].equals("-gl3")) {
+ forceGL3 = true;
} else if(args[i].equals("-wait")) {
waitForKey = true;
} else if(args[i].equals("-mouseInvisible")) {
@@ -316,12 +349,7 @@ public class TestGearsES2NEWT extends UITestCase {
i++;
loops = MiscUtils.atoi(args[i], 1);
} else if(args[i].equals("-loop-shutdown")) {
- i++;
- switch(MiscUtils.atoi(args[i], 0)) {
- case 1: loop_shutdown = GLProfile.ShutdownType.SHARED_ONLY; break;
- case 2: loop_shutdown = GLProfile.ShutdownType.COMPLETE; break;
- default: throw new IllegalArgumentException("should be [0..2], 0-off, 1-shared, 2-complete");
- }
+ loop_shutdown = true;
}
}
wsize = new Dimension(w, h);
@@ -333,6 +361,7 @@ public class TestGearsES2NEWT extends UITestCase {
System.err.println("size "+wsize);
System.err.println("screen "+screenIdx);
System.err.println("translucent "+(!opaque));
+ System.err.println("forceAlpha "+forceAlpha);
System.err.println("undecorated "+undecorated);
System.err.println("atop "+alwaysOnTop);
System.err.println("fullscreen "+fullscreen);
@@ -343,6 +372,7 @@ public class TestGearsES2NEWT extends UITestCase {
System.err.println("loops "+loops);
System.err.println("loop shutdown "+loop_shutdown);
System.err.println("forceES2 "+forceES2);
+ System.err.println("forceGL3 "+forceGL3);
if(waitForKey) {
BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestRedSquareES2NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestRedSquareES2NEWT.java
index ff231ef..dbba4fa 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestRedSquareES2NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestRedSquareES2NEWT.java
@@ -51,9 +51,11 @@ import org.junit.Test;
public class TestRedSquareES2NEWT extends UITestCase {
static int width, height;
static int loops = 1;
- static GLProfile.ShutdownType loop_shutdown = null;
+ static boolean loop_shutdown = false;
static boolean vsync = false;
static boolean forceES2 = false;
+ static boolean forceGL3 = false;
+ static boolean mainRun = false;
static boolean doRotate = true;
@BeforeClass
@@ -127,17 +129,38 @@ public class TestRedSquareES2NEWT extends UITestCase {
public void test01GL2ES2() throws InterruptedException {
for(int i=1; i<=loops; i++) {
System.err.println("Loop "+i+"/"+loops);
- GLCapabilities caps = new GLCapabilities(forceES2 ? GLProfile.get(GLProfile.GLES2) : GLProfile.getGL2ES2());
+ final GLProfile glp;
+ if(forceGL3) {
+ glp = GLProfile.get(GLProfile.GL3);
+ } else if(forceES2) {
+ glp = GLProfile.get(GLProfile.GLES2);
+ } else {
+ glp = GLProfile.getGL2ES2();
+ }
+ final GLCapabilities caps = new GLCapabilities(glp);
runTestGL(caps);
- if(null != loop_shutdown) {
- GLProfile.shutdown(loop_shutdown);
+ if(loop_shutdown) {
+ GLProfile.shutdown();
}
}
}
+
+ @Test
+ public void test02GL3() throws InterruptedException {
+ if(mainRun) return;
+
+ if( !GLProfile.isAvailable(GLProfile.GL3) ) {
+ System.err.println("GL3 n/a");
+ }
+ final GLProfile glp = GLProfile.get(GLProfile.GL3);
+ final GLCapabilities caps = new GLCapabilities( glp );
+ runTestGL(caps);
+ }
static long duration = 500; // ms
public static void main(String args[]) {
+ mainRun = true;
for(int i=0; i<args.length; i++) {
if(args[i].equals("-time")) {
i++;
@@ -146,23 +169,21 @@ public class TestRedSquareES2NEWT extends UITestCase {
} catch (Exception ex) { ex.printStackTrace(); }
} else if(args[i].equals("-es2")) {
forceES2 = true;
+ } else if(args[i].equals("-gl3")) {
+ forceGL3 = true;
} else if(args[i].equals("-norotate")) {
doRotate = false;
} else if(args[i].equals("-loops")) {
i++;
loops = MiscUtils.atoi(args[i], 1);
} else if(args[i].equals("-loop-shutdown")) {
- i++;
- switch(MiscUtils.atoi(args[i], 0)) {
- case 1: loop_shutdown = GLProfile.ShutdownType.SHARED_ONLY; break;
- case 2: loop_shutdown = GLProfile.ShutdownType.COMPLETE; break;
- default: throw new IllegalArgumentException("should be [0..2], 0-off, 1-shared, 2-complete");
- }
+ loop_shutdown = true;
}
}
System.err.println("loops "+loops);
System.err.println("loop shutdown "+loop_shutdown);
System.err.println("forceES2 "+forceES2);
+ System.err.println("forceGL3 "+forceGL3);
org.junit.runner.JUnitCore.main(TestRedSquareES2NEWT.class.getName());
}
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/PointsShader.fp b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/PointsShader.fp
new file mode 100644
index 0000000..3210762
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/PointsShader.fp
@@ -0,0 +1,47 @@
+
+#if __VERSION__ >= 130
+ #define varying in
+ out vec4 mgl_FragColor;
+#else
+ #define mgl_FragColor gl_FragColor
+#endif
+
+// [0].rgba: 0, smooth, attnMinSz, attnMaxSz
+// [1].rgba: attnCoeff(3), attnFadeTs
+uniform vec4 mgl_PointParams[2];
+
+#define pointSmooth (mgl_PointParams[0].g)
+
+varying vec4 frontColor;
+
+// #define TEST 1
+
+void main (void)
+{
+ mgl_FragColor = frontColor;
+
+ if( pointSmooth > 0.5 ) {
+ // smooth (AA)
+ const float border = 0.90; // take/give 10% for AA
+
+ // origin to 0/0, [-1/-1 .. 1/1]
+ vec2 pointPos = 2.0 * gl_PointCoord - 1.0 ;
+ float r = length( pointPos ); // one-circle sqrt(x * x + y * y), range: in-circle [0..1], out >1
+ float r1 = 1.0 - ( step(border, r) * 10.0 * ( r - border ) ) ; // [0..1]
+ #ifndef TEST
+ if( r1 < 0.0 ) {
+ discard;
+ }
+ #endif
+
+ #ifndef TEST
+ mgl_FragColor.a *= r1;
+ #else
+ mgl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
+ mgl_FragColor.r = r1 < 0.0 ? 1.0 : 0.0;
+ mgl_FragColor.g = r > 1.0 ? 1.0 : 0.0;
+ mgl_FragColor.b = r > border ? 1.0 : 0.0;
+ #endif
+ }
+}
+
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/PointsShader.vp b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/PointsShader.vp
new file mode 100644
index 0000000..4fa49b9
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/PointsShader.vp
@@ -0,0 +1,47 @@
+
+#if __VERSION__ >= 130
+ #define attribute in
+ #define varying out
+#endif
+
+uniform vec4 mgl_ColorStatic;
+uniform mat4 mgl_PMVMatrix[4]; // P, Mv, Mvi and Mvit (transpose(inverse(ModelView)) == normalMatrix)
+
+// [0].rgba: 0, smooth, attnMinSz, attnMaxSz
+// [1].rgba: attnCoeff(3), attnFadeTs
+uniform vec4 mgl_PointParams[2];
+
+#define pointSmooth (mgl_PointParams[0].g)
+#define pointSizeMin (mgl_PointParams[0].b)
+#define pointSizeMax (mgl_PointParams[0].a)
+#define pointDistanceConstantAtten (mgl_PointParams[1].r)
+#define pointDistanceLinearAtten (mgl_PointParams[1].g)
+#define pointDistanceQuadraticAtten (mgl_PointParams[1].b)
+#define pointFadeThresholdSize (mgl_PointParams[1].a)
+
+attribute vec4 mgl_Vertex;
+attribute float mgl_PointSize;
+
+varying vec4 frontColor;
+
+void main(void)
+{
+ frontColor = mgl_ColorStatic;
+
+ vec4 eyeCoord = mgl_PMVMatrix[1] * mgl_Vertex;
+ gl_Position = mgl_PMVMatrix[0] * eyeCoord;
+
+ float dist = distance(eyeCoord, vec4(0.0, 0.0, 0.0, 1.0));
+ float atten = sqrt( 1.0 / ( pointDistanceConstantAtten +
+ ( pointDistanceLinearAtten +
+ pointDistanceQuadraticAtten * dist
+ ) * dist
+ )
+ );
+ float size = clamp(mgl_PointSize * atten, pointSizeMin, pointSizeMax);
+ gl_PointSize = max(size, pointFadeThresholdSize);
+
+ float fade = min(size, pointFadeThresholdSize) / pointFadeThresholdSize;
+ frontColor.a *= fade * fade;
+}
+
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/RedSquareShader.fp b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/RedSquareShader.fp
index d3cfecd..60b9240 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/RedSquareShader.fp
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/RedSquareShader.fp
@@ -1,23 +1,16 @@
// Copyright 2010 JogAmp Community. All rights reserved.
-/**
- * AMD complains: #version must occur before any other statement in the program
-#ifdef GL_ES
- #version 100
+#if __VERSION__ >= 130
+ #define varying in
+ out vec4 mgl_FragColor;
#else
- #version 110
+ #define mgl_FragColor gl_FragColor
#endif
- */
-#ifdef GL_ES
- precision mediump float;
- precision mediump int;
-#endif
-
-varying vec4 frontColor;
+varying vec4 frontColor;
void main (void)
{
- gl_FragColor = frontColor;
+ mgl_FragColor = frontColor;
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/RedSquareShader.vp b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/RedSquareShader.vp
index bfd44c8..9283dd7 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/RedSquareShader.vp
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/RedSquareShader.vp
@@ -1,17 +1,8 @@
// Copyright 2010 JogAmp Community. All rights reserved.
-/**
- * AMD complains: #version must occur before any other statement in the program
-#ifdef GL_ES
- #version 100
-#else
- #version 110
-#endif
- */
-
-#ifdef GL_ES
- precision mediump float;
- precision mediump int;
+#if __VERSION__ >= 130
+ #define attribute in
+ #define varying out
#endif
uniform mat4 mgl_PMVMatrix[2];
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/RedSquareShader2.fp b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/RedSquareShader2.fp
index 01e4b09..25a2df2 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/RedSquareShader2.fp
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/RedSquareShader2.fp
@@ -1,26 +1,16 @@
// Copyright 2010 JogAmp Community. All rights reserved.
-/**
- * AMD complains: #version must occur before any other statement in the program
-#ifdef GL_ES
- #version 100
+#if __VERSION__ >= 130
+ #define varying in
+ out vec4 mgl_FragColor;
#else
- #version 110
+ #define mgl_FragColor gl_FragColor
#endif
- */
-#ifdef GL_ES
- #define MEDIUMP mediump
- #define HIGHP highp
-#else
- #define MEDIUMP
- #define HIGHP
-#endif
-
-varying HIGHP vec4 frontColor;
+varying vec4 frontColor;
void main (void)
{
- gl_FragColor = vec4(0.0, frontColor.g, frontColor.b, 1.0);
+ mgl_FragColor = vec4(0.0, frontColor.g, frontColor.b, 1.0);
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/default.vp b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/default.vp
index 99ad6e4..2037086 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/default.vp
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/default.vp
@@ -1,5 +1,10 @@
//Copyright 2010 JogAmp Community. All rights reserved.
+#if __VERSION__ >= 130
+ #define attribute in
+ #define varying out
+#endif
+
#ifdef GL_ES
#define MEDIUMP mediump
#define HIGHP highp
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/elektronenmultiplizierer_development.fp b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/elektronenmultiplizierer_development.fp
index 22fb65e..60f054b 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/elektronenmultiplizierer_development.fp
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/elektronenmultiplizierer_development.fp
@@ -9,6 +9,14 @@
* author: Dominik Stroehlein (DemoscenePassivist)
**/
+#if __VERSION__ >= 130
+ #define varying in
+ out vec4 mgl_FragColor;
+ #define texture2D texture
+#else
+ #define mgl_FragColor gl_FragColor
+#endif
+
#ifdef GL_ES
precision mediump float;
precision mediump sampler2D;
@@ -343,7 +351,7 @@ void main() {
color = raymarch_orbittrap_image(oglFragCoord.xy);
}
if (en==2 || en==7) {
- gl_FragColor = color;
+ mgl_FragColor = color;
} else {
//do normal rendering ...
//analog-tv distortion ...
@@ -376,6 +384,6 @@ void main() {
//tv flicker effect
color_tv *= 0.97+0.13*sin(2.5*tm);
color_tv *= br;
- gl_FragColor = vec4(color_tv,1.0);
+ mgl_FragColor = vec4(color_tv,1.0);
}
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/elektronenmultiplizierer_port.fp b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/elektronenmultiplizierer_port.fp
index d3df819..77c34f7 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/elektronenmultiplizierer_port.fp
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/elektronenmultiplizierer_port.fp
@@ -12,6 +12,14 @@
//When I wrote this, only God and I understood what I was doing ...
// ... now only God knows! X-)
+#if __VERSION__ >= 130
+ #define varying in
+ out vec4 mgl_FragColor;
+ #define texture2D texture
+#else
+ #define mgl_FragColor gl_FragColor
+#endif
+
uniform int en;
uniform float et;
uniform sampler2D fb;
@@ -209,7 +217,7 @@ void main() {
} else
n=D(c.xy);
if(en==2||en==7)
- gl_FragColor=n;
+ mgl_FragColor=n;
else {
vec2 i=c.xy/v.xy;
i.y*=-1.;
@@ -229,6 +237,6 @@ void main() {
x*=.9+.1*sin(1.5*tm+i.y*1000.);
x*=.97+.13*sin(2.5*tm);
x*=br;
- gl_FragColor=vec4(x,1.);
+ mgl_FragColor=vec4(x,1.);
}
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/gears.fp b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/gears.fp
index f41adda..14328dc 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/gears.fp
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/gears.fp
@@ -1,9 +1,11 @@
// Copyright (C) 2011 JogAmp Community. All rights reserved.
// Details see GearsES2.java
-#ifdef GL_ES
- precision mediump float;
- precision mediump int;
+#if __VERSION__ >= 130
+ #define varying in
+ out vec4 mgl_FragColor;
+#else
+ #define mgl_FragColor gl_FragColor
#endif
uniform vec4 color;
@@ -42,5 +44,5 @@ void main()
specular += color * pow(NdotHV, matShininess) * attenuation * matSpecular;
}
- gl_FragColor = ambient + diffuse + specular ;
+ mgl_FragColor = ambient + diffuse + specular ;
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/gears.vp b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/gears.vp
index b2d7708..24f4f9c 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/gears.vp
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/gears.vp
@@ -1,10 +1,11 @@
// Copyright (C) 2011 JogAmp Community. All rights reserved.
// Details see GearsES2.java
-#ifdef GL_ES
- precision mediump float;
- precision mediump int;
+#if __VERSION__ >= 130
+ #define attribute in
+ #define varying out
#endif
+
uniform mat4 pmvMatrix[4]; // P, Mv, Mvi and Mvit
uniform vec3 lightPos;
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/mgl_default_xxx.fp b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/mgl_default_xxx.fp
index a26dc97..a2abf9e 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/mgl_default_xxx.fp
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/mgl_default_xxx.fp
@@ -1,10 +1,16 @@
// Copyright 2012 JogAmp Community. All rights reserved.
+#if __VERSION__ >= 130
+ #define varying in
+ out vec4 mgl_FragColor;
+#else
+ #define mgl_FragColor gl_FragColor
+#endif
+
varying vec4 frontColor;
void main (void)
{
- gl_FragColor = frontColor;
- // gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ mgl_FragColor = frontColor;
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/mgl_default_xxx.vp b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/mgl_default_xxx.vp
index 097a73e..98e7916 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/mgl_default_xxx.vp
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/mgl_default_xxx.vp
@@ -1,5 +1,9 @@
//Copyright 2012 JogAmp Community. All rights reserved.
+#if __VERSION__ >= 130
+ #define attribute in
+ #define varying out
+#endif
uniform mat4 mgl_PMVMatrix[2]; // P, Mv
attribute vec4 mgl_Vertex;
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/ruler.fp b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/ruler.fp
index b2f4d7a..f16a3ee 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/ruler.fp
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/ruler.fp
@@ -1,5 +1,12 @@
//Copyright 2010 JogAmp Community. All rights reserved.
+#if __VERSION__ >= 130
+ #define varying in
+ out vec4 mgl_FragColor;
+#else
+ #define mgl_FragColor gl_FragColor
+#endif
+
#ifdef GL_ES
#define MEDIUMP mediump
#define HIGHP highp
@@ -19,7 +26,7 @@ void main (void)
{
MEDIUMP vec2 c = step( onev2, mod(gl_FragCoord.xy, gcu_RulerPixFreq) );
if( c.s == 0.0 || c.t == 0.0 ) {
- gl_FragColor = vec4(gcu_RulerColor, 1.0);
+ mgl_FragColor = vec4(gcu_RulerColor, 1.0);
} else {
discard;
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texsequence_xxx.fp b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texsequence_xxx.fp
index adde23d..5e7bd28 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texsequence_xxx.fp
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texsequence_xxx.fp
@@ -1,5 +1,12 @@
// Copyright 2012 JogAmp Community. All rights reserved.
+#if __VERSION__ >= 130
+ #define varying in
+ out vec4 mgl_FragColor;
+#else
+ #define mgl_FragColor gl_FragColor
+#endif
+
varying vec2 mgl_texCoord;
varying vec4 frontColor;
@@ -17,6 +24,6 @@ void main (void)
}
// mix frontColor with texture ..
- gl_FragColor = vec4(frontColor*texColor);
+ mgl_FragColor = vec4(frontColor*texColor);
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texsequence_xxx.vp b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texsequence_xxx.vp
index c521e37..1030dab 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texsequence_xxx.vp
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texsequence_xxx.vp
@@ -1,5 +1,10 @@
// Copyright 2012 JogAmp Community. All rights reserved.
+#if __VERSION__ >= 130
+ #define attribute in
+ #define varying out
+#endif
+
uniform mat4 mgl_PMVMatrix[2];
// uniform mat4 mgl_STMatrix;
attribute vec4 mgl_Vertex;
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texture01_xxx.fp b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texture01_xxx.fp
index 1a42541..c213f3a 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texture01_xxx.fp
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texture01_xxx.fp
@@ -1,5 +1,13 @@
// Copyright 2012 JogAmp Community. All rights reserved.
+#if __VERSION__ >= 130
+ #define varying in
+ out vec4 mgl_FragColor;
+ #define texture2D texture
+#else
+ #define mgl_FragColor gl_FragColor
+#endif
+
varying vec2 mgl_texCoord;
varying vec4 frontColor;
@@ -15,6 +23,6 @@ void main (void)
}
// mix frontColor with texture ..
- gl_FragColor = vec4(frontColor*texColor);
+ mgl_FragColor = vec4(frontColor*texColor);
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texture01_xxx.vp b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texture01_xxx.vp
index c521e37..1030dab 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texture01_xxx.vp
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texture01_xxx.vp
@@ -1,5 +1,10 @@
// Copyright 2012 JogAmp Community. All rights reserved.
+#if __VERSION__ >= 130
+ #define attribute in
+ #define varying out
+#endif
+
uniform mat4 mgl_PMVMatrix[2];
// uniform mat4 mgl_STMatrix;
attribute vec4 mgl_Vertex;
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texture02_xxx.fp b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texture02_xxx.fp
index d222606..10073e8 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texture02_xxx.fp
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texture02_xxx.fp
@@ -1,5 +1,13 @@
// Copyright 2012 JogAmp Community. All rights reserved.
+#if __VERSION__ >= 130
+ #define varying in
+ out vec4 mgl_FragColor;
+ #define texture2D texture
+#else
+ #define mgl_FragColor gl_FragColor
+#endif
+
varying vec2 mgl_texCoord;
varying vec4 frontColor;
@@ -13,8 +21,8 @@ void main (void)
vec4 texColor0 = texture2D(mgl_Texture0, mgl_texCoord);
vec4 texColor1 = texture2D(mgl_Texture1, mgl_texCoord);
- // gl_FragColor = ( ( texColor0 + texColor1 ) / 2.0 ) * frontColor;
- // gl_FragColor = mix(texColor0, texColor1, One/2.0) * frontColor;
- gl_FragColor = min(One, mix(texColor0, texColor1, One/2.0) * 1.6) * frontColor;
+ // mgl_FragColor = ( ( texColor0 + texColor1 ) / 2.0 ) * frontColor;
+ // mgl_FragColor = mix(texColor0, texColor1, One/2.0) * frontColor;
+ mgl_FragColor = min(One, mix(texColor0, texColor1, One/2.0) * 1.6) * frontColor;
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/Gears.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/Gears.java
index b3166b0..9c1293e 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/Gears.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/Gears.java
@@ -1,7 +1,9 @@
package com.jogamp.opengl.test.junit.jogl.demos.gl2;
+import javax.media.opengl.GL;
import javax.media.opengl.GL2;
+import javax.media.opengl.GL2ES2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
@@ -71,11 +73,16 @@ public class Gears implements GLEventListener {
GL2 gl = drawable.getGL().getGL2();
+ System.err.println("Gears (GL2) init on "+Thread.currentThread());
System.err.println("Chosen GLCapabilities: " + drawable.getChosenGLCapabilities());
System.err.println("INIT GL IS: " + gl.getClass().getName());
- System.err.println("GL_VENDOR: " + gl.glGetString(GL2.GL_VENDOR));
- System.err.println("GL_RENDERER: " + gl.glGetString(GL2.GL_RENDERER));
- System.err.println("GL_VERSION: " + gl.glGetString(GL2.GL_VERSION));
+ System.err.println("GL_VENDOR: " + gl.glGetString(GL.GL_VENDOR));
+ System.err.println("GL_RENDERER: " + gl.glGetString(GL.GL_RENDERER));
+ System.err.println("GL_VERSION: " + gl.glGetString(GL.GL_VERSION));
+ System.err.println("GL GLSL: "+gl.hasGLSL()+", has-compiler: "+gl.isFunctionAvailable("glCompileShader")+", version "+(gl.hasGLSL() ? gl.glGetString(GL2ES2.GL_SHADING_LANGUAGE_VERSION) : "none"));
+ System.err.println("GL FBO: basic "+ gl.hasBasicFBOSupport()+", full "+gl.hasFullFBOSupport());
+ System.err.println("GL Profile: "+gl.getGLProfile());
+ System.err.println("GL:" + gl + ", " + gl.getContext().getGLVersion());
float pos[] = { 5.0f, 5.0f, 10.0f, 0.0f };
float red[] = { 0.8f, 0.1f, 0.0f, 0.7f };
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/awt/TestGLJPanelAWTBug450.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/awt/TestGLJPanelAWTBug450.java
index 4f97feb..bd9b7ca 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/awt/TestGLJPanelAWTBug450.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/awt/TestGLJPanelAWTBug450.java
@@ -117,7 +117,7 @@ public class TestGLJPanelAWTBug450 extends UITestCase {
}
if(0 == f) {
System.err.println("BGR ("+r_x+"/"+r_y+"): "+byte0+", "+byte1+", "+byte2+" - OK "+(!failed));
- snapshot(getSimpleTestName("."), f, null, gl, screenshot, TextureIO.PNG, null);
+ snapshot(f, null, gl, screenshot, TextureIO.PNG, null);
}
f++;
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/newt/TestGearsNewtAWTWrapper.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/newt/TestGearsNewtAWTWrapper.java
index 62914bd..cc20cc2 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/newt/TestGearsNewtAWTWrapper.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/newt/TestGearsNewtAWTWrapper.java
@@ -33,6 +33,7 @@ import javax.media.opengl.*;
import com.jogamp.opengl.util.Animator;
+import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
import com.jogamp.opengl.test.junit.util.UITestCase;
import com.jogamp.opengl.test.junit.util.QuitAdapter;
import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
@@ -78,8 +79,25 @@ public class TestGearsNewtAWTWrapper extends UITestCase {
glWindow.addKeyListener(new TraceKeyAdapter(quitAdapter));
glWindow.addWindowListener(new TraceWindowAdapter(quitAdapter));
- glWindow.setSize(width, height);
+ int div = 3;
+ glWindow.setSize(width/div, height/div);
glWindow.setVisible(true);
+ glWindow.display();
+ Assert.assertTrue("Size not reached: Expected "+(width/div)+"x"+(height/div)+", Is "+glWindow.getWidth()+"x"+glWindow.getHeight(),
+ AWTRobotUtil.waitForSize(glWindow, width/div, height/div));
+
+ div = 2;
+ glWindow.setSize(width/div, height/div);
+ glWindow.display();
+ Assert.assertTrue("Size not reached: Expected "+(width/div)+"x"+(height/div)+", Is "+glWindow.getWidth()+"x"+glWindow.getHeight(),
+ AWTRobotUtil.waitForSize(glWindow, width/div, height/div));
+
+ div = 1;
+ glWindow.setSize(width/div, height/div);
+ glWindow.display();
+ Assert.assertTrue("Size not reached: Expected "+(width/div)+"x"+(height/div)+", Is "+glWindow.getWidth()+"x"+glWindow.getHeight(),
+ AWTRobotUtil.waitForSize(glWindow, width/div, height/div));
+
animator.setUpdateFPSFrames(1, null);
animator.start();
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/drawable/TestDrawable01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/drawable/TestDrawable01NEWT.java
deleted file mode 100644
index 731f7c8..0000000
--- a/src/test/com/jogamp/opengl/test/junit/jogl/drawable/TestDrawable01NEWT.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/**
- * Copyright 2010 JogAmp Community. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are
- * permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- *
- * 2. 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.
- *
- * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community OR
- * CONTRIBUTORS 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.
- *
- * The views and conclusions contained in the software and documentation are those of the
- * authors and should not be interpreted as representing official policies, either expressed
- * or implied, of JogAmp Community.
- */
-
-package com.jogamp.opengl.test.junit.jogl.drawable;
-
-import com.jogamp.opengl.test.junit.util.UITestCase;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.AfterClass;
-import org.junit.Test;
-
-import javax.media.opengl.*;
-
-import com.jogamp.newt.*;
-import java.io.IOException;
-
-public class TestDrawable01NEWT extends UITestCase {
- static GLProfile glp;
- static GLDrawableFactory factory;
- static int width, height;
- GLCapabilities caps;
- Window window;
- GLDrawable drawable;
- GLContext context;
-
- @BeforeClass
- public static void initClass() {
- glp = GLProfile.getDefault();
- Assert.assertNotNull(glp);
- factory = GLDrawableFactory.getFactory(glp);
- Assert.assertNotNull(factory);
- width = 640;
- height = 480;
- }
-
- @AfterClass
- public static void releaseClass() {
- Assert.assertNotNull(factory);
- factory=null;
- }
-
- @Before
- public void initTest() {
- caps = new GLCapabilities(glp);
- Assert.assertNotNull(caps);
- }
-
- void createWindow(boolean onscreen, boolean pbuffer, boolean undecorated) {
- caps.setOnscreen(onscreen);
- caps.setPBuffer(!onscreen && pbuffer);
- caps.setDoubleBuffered(onscreen);
- // System.out.println("Requested: "+caps);
-
- //
- // Create native windowing resources .. X11/Win/OSX
- //
- Display display = NewtFactory.createDisplay(null); // local display
- Assert.assertNotNull(display);
-
- Screen screen = NewtFactory.createScreen(display, 0); // screen 0
- Assert.assertNotNull(screen);
-
- window = NewtFactory.createWindow(screen, caps);
- Assert.assertNotNull(window);
- window.setUndecorated(onscreen && undecorated);
- window.setSize(width, height);
- window.setVisible(true);
- // System.out.println("Created: "+window);
-
- //
- // Create native OpenGL resources .. XGL/WGL/CGL ..
- // equivalent to GLAutoDrawable methods: setVisible(true)
- //
- GLCapabilities glCaps = (GLCapabilities) window.getGraphicsConfiguration().getChosenCapabilities();
- Assert.assertNotNull(glCaps);
- Assert.assertTrue(glCaps.getGreenBits()>5);
- Assert.assertTrue(glCaps.getBlueBits()>5);
- Assert.assertTrue(glCaps.getRedBits()>5);
- Assert.assertEquals(glCaps.isOnscreen(),onscreen);
- Assert.assertTrue(onscreen || !pbuffer || glCaps.isPBuffer()); // pass if onscreen, or !pbuffer req. or have pbuffer
- Assert.assertEquals(glCaps.getDoubleBuffered(),onscreen);
- Assert.assertTrue(glCaps.getDepthBits()>4);
-
- drawable = factory.createGLDrawable(window);
- Assert.assertNotNull(drawable);
- // System.out.println("Pre: "+drawable);
- //
- drawable.setRealized(true);
- // Assert.assertEquals(width,drawable.getWidth());
- // Assert.assertEquals(height,drawable.getHeight());
- // Assert.assertEquals(glCaps,drawable.getChosenGLCapabilities());
- Assert.assertEquals(window,drawable.getNativeSurface());
- // System.out.println("Post: "+drawable);
-
- context = drawable.createContext(null);
- Assert.assertNotNull(context);
- // System.out.println(context);
-
- int res = context.makeCurrent();
- Assert.assertTrue(GLContext.CONTEXT_CURRENT_NEW==res || GLContext.CONTEXT_CURRENT==res);
-
- // draw something ..
-
- drawable.swapBuffers();
- context.release();
-
- // System.out.println("Final: "+window);
- }
-
- void destroyWindow() {
- // GLWindow.dispose(..) sequence
- Assert.assertNotNull(context);
- context.destroy();
-
- Assert.assertNotNull(drawable);
- drawable.setRealized(false);
-
- // GLWindow.destroy(..) sequence cont..
- Assert.assertNotNull(window);
- window.destroy();
-
- drawable = null;
- context = null;
- window = null;
- }
-
- @Test
- public void testOnScreenDecorated() throws InterruptedException {
- createWindow(true, false, false);
- Thread.sleep(1000); // 1000 ms
- destroyWindow();
- }
-
- @Test
- public void testOnScreenUndecorated() throws InterruptedException {
- createWindow(true, false, true);
- Thread.sleep(1000); // 1000 ms
- destroyWindow();
- }
-
- public static void main(String args[]) throws IOException {
- String tstname = TestDrawable01NEWT.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/test/com/jogamp/opengl/test/junit/jogl/glsl/GLSLMiscHelper.java b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/GLSLMiscHelper.java
index 297cbbb..c2285ba 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/glsl/GLSLMiscHelper.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/GLSLMiscHelper.java
@@ -132,7 +132,7 @@ public class GLSLMiscHelper {
Assert.assertTrue(vertices0.sealed());
Assert.assertEquals(4, vertices0.getElementCount());
Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
- Assert.assertEquals(vertices0.getVBOName(), gl.glGetBoundBuffer(GL.GL_ARRAY_BUFFER));
+ Assert.assertEquals(0, gl.glGetBoundBuffer(GL.GL_ARRAY_BUFFER)); // should be cleared ASAP
validateGLArrayDataServerState(gl, vertices0);
return vertices0;
}
@@ -152,7 +152,7 @@ public class GLSLMiscHelper {
Assert.assertTrue(vertices1.sealed());
Assert.assertEquals(4, vertices1.getElementCount());
Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
- Assert.assertEquals(vertices1.getVBOName(), gl.glGetBoundBuffer(GL.GL_ARRAY_BUFFER));
+ Assert.assertEquals(0, gl.glGetBoundBuffer(GL.GL_ARRAY_BUFFER)); // should be cleared ASAP
validateGLArrayDataServerState(gl, vertices1);
return vertices1;
}
@@ -173,7 +173,7 @@ public class GLSLMiscHelper {
Assert.assertTrue(colors0.isVBOWritten());
Assert.assertTrue(colors0.sealed());
Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
- Assert.assertEquals(colors0.getVBOName(), gl.glGetBoundBuffer(GL.GL_ARRAY_BUFFER));
+ Assert.assertEquals(0, gl.glGetBoundBuffer(GL.GL_ARRAY_BUFFER)); // should be cleared ASAP
validateGLArrayDataServerState(gl, colors0);
return colors0;
}
@@ -191,7 +191,7 @@ public class GLSLMiscHelper {
Assert.assertTrue(colors1.isVBOWritten());
Assert.assertTrue(colors1.sealed());
Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
- Assert.assertEquals(colors1.getVBOName(), gl.glGetBoundBuffer(GL.GL_ARRAY_BUFFER));
+ Assert.assertEquals(0, gl.glGetBoundBuffer(GL.GL_ARRAY_BUFFER)); // should be cleared ASAP
validateGLArrayDataServerState(gl, colors1);
return colors1;
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLShaderState01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLShaderState01NEWT.java
index 987dedc..ab4b2d8 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLShaderState01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLShaderState01NEWT.java
@@ -74,17 +74,19 @@ public class TestGLSLShaderState01NEWT extends UITestCase {
final ShaderState st = new ShaderState();
final ShaderCode rsVp = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, RedSquareES2.class, "shader",
- "shader/bin", "RedSquareShader", false);
+ "shader/bin", "RedSquareShader", true);
final ShaderCode rsFp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, RedSquareES2.class, "shader",
- "shader/bin", "RedSquareShader", false);
+ "shader/bin", "RedSquareShader", true);
+ rsVp.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_vp);
+ rsFp.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_fp);
final ShaderProgram sp = new ShaderProgram();
- Assert.assertTrue(0>sp.program());
+ Assert.assertTrue(0 == sp.program());
sp.add(gl, rsVp, System.err);
sp.add(gl, rsFp, System.err);
- Assert.assertTrue(0<=sp.program());
+ Assert.assertTrue(0 != sp.program());
Assert.assertTrue(!sp.inUse());
Assert.assertTrue(!sp.linked());
Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLShaderState02NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLShaderState02NEWT.java
index 91dcfc3..7022b74 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLShaderState02NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLShaderState02NEWT.java
@@ -81,19 +81,22 @@ public class TestGLSLShaderState02NEWT extends UITestCase {
final ShaderState st = new ShaderState();
final ShaderCode rsVp0 = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, RedSquareES2.class, "shader",
- "shader/bin", "RedSquareShader", false);
+ "shader/bin", "RedSquareShader", true);
final ShaderCode rsFp0 = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, RedSquareES2.class, "shader",
- "shader/bin", "RedSquareShader", false);
+ "shader/bin", "RedSquareShader", true);
final ShaderCode rsFp1 = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, RedSquareES2.class, "shader",
- "shader/bin", "RedSquareShader2", false);
+ "shader/bin", "RedSquareShader2", true);
+ rsVp0.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_vp);
+ rsFp0.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_fp);
+ rsFp1.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_fp);
final ShaderProgram sp1 = new ShaderProgram();
sp1.add(rsVp0);
sp1.add(rsFp1);
Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
- Assert.assertTrue(0>sp1.program());
- sp1.init(gl);
- Assert.assertTrue(0<=sp1.program());
+ Assert.assertTrue(0 == sp1.program());
+ Assert.assertTrue(sp1.init(gl));
+ Assert.assertTrue(0 != sp1.program());
Assert.assertTrue(!sp1.inUse());
Assert.assertTrue(!sp1.linked());
Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
@@ -108,9 +111,9 @@ public class TestGLSLShaderState02NEWT extends UITestCase {
sp0.add(rsFp0);
Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
- Assert.assertTrue(0>sp0.program());
- sp0.init(gl);
- Assert.assertTrue(0<=sp0.program());
+ Assert.assertTrue(0 == sp0.program());
+ Assert.assertTrue(sp0.init(gl));
+ Assert.assertTrue(0 != sp0.program());
Assert.assertTrue(!sp0.inUse());
Assert.assertTrue(!sp0.linked());
Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
@@ -262,15 +265,16 @@ public class TestGLSLShaderState02NEWT extends UITestCase {
sp1.add(rsVp0);
sp1.add(rsFp1);
Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
- Assert.assertTrue(0>sp1.program());
- sp1.init(gl);
+ Assert.assertTrue(0 == sp1.program());
+ Assert.assertTrue(sp1.init(gl));
+ Assert.assertTrue(0 != sp1.program());
Assert.assertTrue(sp1.link(gl, System.err));
final ShaderProgram sp0 = new ShaderProgram();
sp0.add(rsVp0);
sp0.add(rsFp0);
- sp0.init(gl);
+ Assert.assertTrue(sp0.init(gl));
Assert.assertTrue(sp0.link(gl, System.err));
st.attachShaderProgram(gl, sp0, true);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestRulerNEWT01.java b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestRulerNEWT01.java
index 87d3170..98620e0 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestRulerNEWT01.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestRulerNEWT01.java
@@ -74,14 +74,16 @@ public class TestRulerNEWT01 extends UITestCase {
final ShaderState st = new ShaderState();
final ShaderCode vp0 = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, RedSquareES2.class, "shader",
- "shader/bin", "default", false);
+ "shader/bin", "default", true);
final ShaderCode fp0 = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, RedSquareES2.class, "shader",
- "shader/bin", "ruler", false);
+ "shader/bin", "ruler", true);
+ vp0.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_vp);
+ fp0.defaultShaderCustomization(gl, true, ShaderCode.es2_default_precision_fp);
final ShaderProgram sp0 = new ShaderProgram();
sp0.add(gl, vp0, System.err);
sp0.add(gl, fp0, System.err);
- Assert.assertTrue(0<=sp0.program());
+ Assert.assertTrue(0 != sp0.program());
Assert.assertTrue(!sp0.inUse());
Assert.assertTrue(!sp0.linked());
Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/ReadBufferBase.java b/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/ReadBufferBase.java
index 4ef7b27..f8e064a 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/ReadBufferBase.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/ReadBufferBase.java
@@ -70,7 +70,7 @@ public class ReadBufferBase implements GLEventListener {
_gl.getContext().setGLReadDrawable(externalRead);
if(_gl.isGL2GL3()) {
- _gl.getGL2GL3().glReadBuffer(GL2GL3.GL_FRONT);
+ _gl.getGL2GL3().glReadBuffer(GL.GL_FRONT);
}
System.out.println("---------------------------");
System.out.println(_gl.getContext());
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestNewtCanvasSWTGLn.java b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestNewtCanvasSWTGLn.java
index 6a27e6f..fe40cec 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestNewtCanvasSWTGLn.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestNewtCanvasSWTGLn.java
@@ -139,7 +139,7 @@ public class TestNewtCanvasSWTGLn extends UITestCase {
public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height) { }
public void display(final GLAutoDrawable drawable) {
if(displayCount < 3) {
- snapshot(getSimpleTestName("."), displayCount++, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
+ snapshot(displayCount++, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
}
}
public void dispose(final GLAutoDrawable drawable) { }
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTAccessor03AWTGLn.java b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTAccessor03AWTGLn.java
index ad8da8a..91902a8 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTAccessor03AWTGLn.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTAccessor03AWTGLn.java
@@ -49,13 +49,13 @@ import org.eclipse.swt.widgets.Shell;
import org.junit.Assert;
import org.junit.Assume;
-import org.junit.Before;
import org.junit.BeforeClass;
-import org.junit.After;
import org.junit.Test;
+import com.jogamp.common.os.Platform;
import com.jogamp.nativewindow.swt.SWTAccessor;
import com.jogamp.opengl.test.junit.jogl.demos.es1.OneTriangle;
+import com.jogamp.opengl.test.junit.util.MiscUtils;
import com.jogamp.opengl.test.junit.util.UITestCase;
/**
@@ -65,7 +65,7 @@ import com.jogamp.opengl.test.junit.util.UITestCase;
*/
public class TestSWTAccessor03AWTGLn extends UITestCase {
- static final int duration = 250;
+ static int duration = 250;
Display display = null;
Shell shell = null;
@@ -75,6 +75,13 @@ public class TestSWTAccessor03AWTGLn extends UITestCase {
@BeforeClass
public static void startup() {
+ if( Platform.getOSType() == Platform.OSType.MACOS ) {
+ // NSLocking issues on OSX and AWT, able to freeze whole test suite!
+ // Since this test is merely a technical nature to validate the accessor w/ SWT
+ // we can drop it w/o bothering.
+ UITestCase.setTestSupported(false);
+ return;
+ }
System.out.println( "GLProfile " + GLProfile.glAvailabilityToString() );
Frame f0 = new Frame("Test - AWT 1st");
f0.add(new java.awt.Label("AWT was here 1st"));
@@ -85,8 +92,7 @@ public class TestSWTAccessor03AWTGLn extends UITestCase {
}
}
- @Before
- public void init() throws InterruptedException, InvocationTargetException {
+ protected void init() throws InterruptedException, InvocationTargetException {
SWTAccessor.invoke(true, new Runnable() {
public void run() {
display = new Display();
@@ -102,8 +108,7 @@ public class TestSWTAccessor03AWTGLn extends UITestCase {
}});
}
- @After
- public void release() throws InterruptedException, InvocationTargetException {
+ protected void release() throws InterruptedException, InvocationTargetException {
Assert.assertNotNull( display );
Assert.assertNotNull( shell );
Assert.assertNotNull( composite );
@@ -129,71 +134,81 @@ public class TestSWTAccessor03AWTGLn extends UITestCase {
}});
}
- protected void runTestGL( GLProfile glprofile ) throws InterruptedException {
- GLCapabilities glcapabilities = new GLCapabilities( glprofile );
- glcanvas = new GLCanvas( glcapabilities );
- Assert.assertNotNull( glcanvas );
- frame.add( glcanvas );
-
- glcanvas.addGLEventListener( new GLEventListener() {
- /* @Override */
- public void init( GLAutoDrawable glautodrawable ) {
- }
-
- /* @Override */
- public void dispose( GLAutoDrawable glautodrawable ) {
- }
-
- /* @Override */
- public void display( GLAutoDrawable glautodrawable ) {
- Rectangle rectangle = new Rectangle( 0, 0, glautodrawable.getWidth(), glautodrawable.getHeight() );
- GL2ES1 gl = glautodrawable.getGL().getGL2ES1();
- OneTriangle.render( gl, rectangle.width, rectangle.height );
- }
-
- /* @Override */
- public void reshape( GLAutoDrawable glautodrawable, int x, int y, int width, int height ) {
- Rectangle rectangle = new Rectangle( 0, 0, glautodrawable.getWidth(), glautodrawable.getHeight() );
- GL2ES1 gl = glautodrawable.getGL().getGL2ES1();
- OneTriangle.setup( gl, rectangle.width, rectangle.height );
- }
- });
-
- SWTAccessor.invoke(true, new Runnable() {
- public void run() {
- shell.setText( getClass().getName() );
- shell.setSize( 640, 480 );
- shell.open();
- }});
-
- long lStartTime = System.currentTimeMillis();
- long lEndTime = lStartTime + duration;
+ protected void runTestGL( GLProfile glprofile ) throws InterruptedException, InvocationTargetException {
+ init();
try {
- while( (System.currentTimeMillis() < lEndTime) && !composite.isDisposed() ) {
- SWTAccessor.invoke(true, new Runnable() {
- public void run() {
- if( !display.readAndDispatch() ) {
- // blocks on linux .. display.sleep();
- try {
- Thread.sleep(10);
- } catch (InterruptedException e) { }
- }
- }});
+ GLCapabilities glcapabilities = new GLCapabilities( glprofile );
+ glcanvas = new GLCanvas( glcapabilities );
+ Assert.assertNotNull( glcanvas );
+ frame.add( glcanvas );
+
+ glcanvas.addGLEventListener( new GLEventListener() {
+ /* @Override */
+ public void init( GLAutoDrawable glautodrawable ) {
+ }
+
+ /* @Override */
+ public void dispose( GLAutoDrawable glautodrawable ) {
+ }
+
+ /* @Override */
+ public void display( GLAutoDrawable glautodrawable ) {
+ Rectangle rectangle = new Rectangle( 0, 0, glautodrawable.getWidth(), glautodrawable.getHeight() );
+ GL2ES1 gl = glautodrawable.getGL().getGL2ES1();
+ OneTriangle.render( gl, rectangle.width, rectangle.height );
+ }
+
+ /* @Override */
+ public void reshape( GLAutoDrawable glautodrawable, int x, int y, int width, int height ) {
+ Rectangle rectangle = new Rectangle( 0, 0, glautodrawable.getWidth(), glautodrawable.getHeight() );
+ GL2ES1 gl = glautodrawable.getGL().getGL2ES1();
+ OneTriangle.setup( gl, rectangle.width, rectangle.height );
+ }
+ });
+
+ SWTAccessor.invoke(true, new Runnable() {
+ public void run() {
+ shell.setText( getClass().getName() );
+ shell.setSize( 640, 480 );
+ shell.open();
+ }});
+
+ long lStartTime = System.currentTimeMillis();
+ long lEndTime = lStartTime + duration;
+ try {
+ while( (System.currentTimeMillis() < lEndTime) && !composite.isDisposed() ) {
+ SWTAccessor.invoke(true, new Runnable() {
+ public void run() {
+ if( !display.readAndDispatch() ) {
+ // blocks on linux .. display.sleep();
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException e) { }
+ }
+ }});
+ }
}
- }
- catch( Throwable throwable ) {
- throwable.printStackTrace();
- Assume.assumeNoException( throwable );
+ catch( Throwable throwable ) {
+ throwable.printStackTrace();
+ Assume.assumeNoException( throwable );
+ }
+ } finally {
+ release();
}
}
@Test
- public void test() throws InterruptedException {
+ public void test() throws InterruptedException, InvocationTargetException {
GLProfile glprofile = GLProfile.getGL2ES1();
runTestGL( glprofile );
}
public static void main(String args[]) {
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-time")) {
+ duration = MiscUtils.atoi(args[++i], duration);
+ }
+ }
org.junit.runner.JUnitCore.main( TestSWTAccessor03AWTGLn.class.getName() );
}
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTJOGLGLCanvas01GLn.java b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTJOGLGLCanvas01GLn.java
index 4ca1dae..6d9e221 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTJOGLGLCanvas01GLn.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTJOGLGLCanvas01GLn.java
@@ -134,7 +134,7 @@ public class TestSWTJOGLGLCanvas01GLn extends UITestCase {
public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height) { }
public void display(final GLAutoDrawable drawable) {
if(displayCount < 3) {
- snapshot(getSimpleTestName("."), displayCount++, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
+ snapshot(displayCount++, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
}
}
public void dispose(final GLAutoDrawable drawable) { }
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/DemoGL2ES1ImmModeSink.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/DemoGL2ES1ImmModeSink.java
new file mode 100644
index 0000000..276fb17
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/DemoGL2ES1ImmModeSink.java
@@ -0,0 +1,97 @@
+package com.jogamp.opengl.test.junit.jogl.util;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2ES1;
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLPipelineFactory;
+import javax.media.opengl.glu.GLU;
+import javax.media.opengl.glu.gl2es1.GLUgl2es1;
+
+import com.jogamp.opengl.util.ImmModeSink;
+import com.jogamp.opengl.util.glsl.fixedfunc.FixedFuncUtil;
+import com.jogamp.opengl.util.glsl.fixedfunc.ShaderSelectionMode;
+
+class DemoGL2ES1ImmModeSink implements GLEventListener {
+ private boolean debugFFPEmu = false;
+ private boolean verboseFFPEmu = false;
+ private boolean traceFFPEmu = false;
+ private boolean forceFFPEmu = false;
+ final ImmModeSink ims;
+ final GLU glu;
+
+ DemoGL2ES1ImmModeSink(boolean useVBO) {
+ ims = ImmModeSink.createFixed(3*3,
+ 3, GL.GL_FLOAT, // vertex
+ 3, GL.GL_FLOAT, // color
+ 0, GL.GL_FLOAT, // normal
+ 0, GL.GL_FLOAT, // texCoords
+ useVBO ? GL.GL_STATIC_DRAW : 0);
+ glu = new GLUgl2es1();
+ }
+
+ public void setForceFFPEmu(boolean forceFFPEmu, boolean verboseFFPEmu, boolean debugFFPEmu, boolean traceFFPEmu) {
+ this.forceFFPEmu = forceFFPEmu;
+ this.verboseFFPEmu = verboseFFPEmu;
+ this.debugFFPEmu = debugFFPEmu;
+ this.traceFFPEmu = traceFFPEmu;
+ }
+
+ @Override
+ public void init(GLAutoDrawable drawable) {
+ GL _gl = drawable.getGL();
+ if(debugFFPEmu) {
+ // Debug ..
+ _gl = _gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Debug", GL2ES2.class, _gl, null) );
+ }
+ if(traceFFPEmu) {
+ // Trace ..
+ _gl = _gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Trace", GL2ES2.class, _gl, new Object[] { System.err } ) );
+ }
+ GL2ES1 gl = FixedFuncUtil.wrapFixedFuncEmul(_gl, ShaderSelectionMode.AUTO, null, forceFFPEmu, verboseFFPEmu);
+
+ System.err.println("GL_VENDOR "+gl.glGetString(GL.GL_VENDOR));
+ System.err.println("GL_RENDERER "+gl.glGetString(GL.GL_RENDERER));
+ System.err.println("GL_VERSION "+gl.glGetString(GL.GL_VERSION));
+ }
+
+ @Override
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
+ GL2ES1 gl = drawable.getGL().getGL2ES1();
+
+ gl.glMatrixMode( GL2ES1.GL_PROJECTION );
+ gl.glLoadIdentity();
+
+ // coordinate system origin at lower left with width and height same as the window
+ glu.gluOrtho2D( 0.0f, width, 0.0f, height );
+
+ gl.glMatrixMode( GL2ES1.GL_MODELVIEW );
+ gl.glLoadIdentity();
+
+ gl.glViewport( 0, 0, width, height );
+ }
+
+ @Override
+ public void display(GLAutoDrawable drawable) {
+ GL2ES1 gl = drawable.getGL().getGL2ES1();
+
+ gl.glClear( GL.GL_COLOR_BUFFER_BIT );
+
+ // draw a triangle filling the window
+ gl.glLoadIdentity();
+
+ ims.glBegin(GL.GL_TRIANGLES);
+ ims.glColor3f( 1, 0, 0 );
+ ims.glVertex2f( 0, 0 );
+ ims.glColor3f( 0, 1, 0 );
+ ims.glVertex2f( TestImmModeSinkES1NEWT.iWidth, 0 );
+ ims.glColor3f( 0, 0, 1 );
+ ims.glVertex2f( TestImmModeSinkES1NEWT.iWidth / 2, TestImmModeSinkES1NEWT.iHeight );
+ ims.glEnd(gl, true);
+ }
+
+ @Override
+ public void dispose(GLAutoDrawable drawable) {
+ }
+}
\ No newline at end of file
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/DemoGL2ES1Plain.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/DemoGL2ES1Plain.java
new file mode 100644
index 0000000..b66a095
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/DemoGL2ES1Plain.java
@@ -0,0 +1,161 @@
+package com.jogamp.opengl.test.junit.jogl.util;
+
+import java.nio.ByteBuffer;
+import java.nio.FloatBuffer;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2ES1;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLException;
+import javax.media.opengl.fixedfunc.GLPointerFunc;
+import javax.media.opengl.glu.GLU;
+import javax.media.opengl.glu.gl2es1.GLUgl2es1;
+
+import com.jogamp.common.nio.Buffers;
+import com.jogamp.opengl.util.GLArrayDataWrapper;
+import com.jogamp.opengl.util.GLBuffers;
+
+class DemoGL2ES1Plain implements GLEventListener {
+ final boolean useArrayData;
+ final boolean useVBO;
+ final GLU glu;
+
+ final float[] vertices = new float[] { 0, 0, 0,
+ TestImmModeSinkES1NEWT.iWidth, 0, 0,
+ TestImmModeSinkES1NEWT.iWidth / 2, TestImmModeSinkES1NEWT.iHeight, 0 };
+
+ final float[] colors = new float[] { 1, 0, 0,
+ 0, 1, 0,
+ 0, 0, 1 };
+
+ final ByteBuffer bufferAll;
+ final int bufferVOffset, bufferCOffset;
+ final int bufferVSize, bufferCSize;
+ final FloatBuffer bufferC, bufferV;
+ final int[] vboName = new int[] { 0 };
+ final GLArrayDataWrapper arrayC, arrayV;
+
+ DemoGL2ES1Plain(boolean useArrayData, boolean useVBO) {
+ this.useArrayData = useArrayData;
+ this.useVBO = useVBO;
+ this.glu = new GLUgl2es1();
+
+ bufferAll = Buffers.newDirectByteBuffer( ( colors.length + vertices.length ) * Buffers.SIZEOF_FLOAT );
+
+ bufferVOffset = 0;
+ bufferVSize = 3*3*GLBuffers.sizeOfGLType(GL.GL_FLOAT);
+ bufferCOffset = bufferVSize;
+ bufferCSize = 3*3*GLBuffers.sizeOfGLType(GL.GL_FLOAT);
+
+ bufferV = (FloatBuffer) GLBuffers.sliceGLBuffer(bufferAll, bufferVOffset, bufferVSize, GL.GL_FLOAT);
+ bufferV.put(vertices, 0, vertices.length).rewind();
+ bufferC = (FloatBuffer) GLBuffers.sliceGLBuffer(bufferAll, bufferCOffset, bufferCSize, GL.GL_FLOAT);
+ bufferC.put(colors, 0, colors.length).rewind();
+
+ System.err.println("bufferAll: "+bufferAll+", byteOffset "+Buffers.getDirectBufferByteOffset(bufferAll));
+ System.err.println("bufferV: off "+bufferVOffset+", size "+bufferVSize+": "+bufferV+", byteOffset "+Buffers.getDirectBufferByteOffset(bufferV));
+ System.err.println("bufferC: off "+bufferCOffset+", size "+bufferCSize+": "+bufferC+", byteOffset "+Buffers.getDirectBufferByteOffset(bufferC));
+
+ if(useArrayData) {
+ arrayV = GLArrayDataWrapper.createFixed(GLPointerFunc.GL_VERTEX_ARRAY, 3, GL.GL_FLOAT, false, 0,
+ bufferV, 0, bufferVOffset, GL.GL_STATIC_DRAW, GL.GL_ARRAY_BUFFER);
+
+ arrayC = GLArrayDataWrapper.createFixed(GLPointerFunc.GL_COLOR_ARRAY, 3, GL.GL_FLOAT, false, 0,
+ bufferC, 0, bufferCOffset, GL.GL_STATIC_DRAW, GL.GL_ARRAY_BUFFER);
+ } else {
+ arrayV = null;
+ arrayC = null;
+ }
+ }
+
+ @Override
+ public void init(GLAutoDrawable drawable) {
+ GL gl = drawable.getGL();
+ System.err.println("GL_VENDOR "+gl.glGetString(GL.GL_VENDOR));
+ System.err.println("GL_RENDERER "+gl.glGetString(GL.GL_RENDERER));
+ System.err.println("GL_VERSION "+gl.glGetString(GL.GL_VERSION));
+ if(useVBO) {
+ gl.glGenBuffers(1, vboName, 0);
+ if(0 == vboName[0]) {
+ throw new GLException("glGenBuffers didn't return valid VBO name");
+ }
+ }
+ }
+
+ @Override
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
+ GL2ES1 gl = drawable.getGL().getGL2ES1();
+
+ gl.glMatrixMode( GL2ES1.GL_PROJECTION );
+ gl.glLoadIdentity();
+
+ // coordinate system origin at lower left with width and height same as the window
+ glu.gluOrtho2D( 0.0f, width, 0.0f, height );
+
+ gl.glMatrixMode( GL2ES1.GL_MODELVIEW );
+ gl.glLoadIdentity();
+
+ gl.glViewport( 0, 0, width, height );
+ }
+
+ @Override
+ public void display(GLAutoDrawable drawable) {
+ GL2ES1 gl = drawable.getGL().getGL2ES1();
+
+ gl.glClear( GL.GL_COLOR_BUFFER_BIT );
+
+ // draw a triangle filling the window
+ gl.glLoadIdentity();
+
+ if(useVBO) {
+ gl.glBindBuffer(GL.GL_ARRAY_BUFFER, vboName[0]);
+ gl.glBufferData(GL.GL_ARRAY_BUFFER, bufferAll.limit(), bufferAll, GL.GL_STATIC_DRAW);
+ if(useArrayData) {
+ arrayV.setVBOName(vboName[0]);
+ arrayC.setVBOName(vboName[0]);
+ }
+ }
+
+ gl.glEnableClientState(GLPointerFunc.GL_VERTEX_ARRAY);
+ if(useArrayData) {
+ gl.glVertexPointer(arrayV);
+ } else {
+ if(useVBO) {
+ gl.glVertexPointer(3, GL.GL_FLOAT, 0, bufferVOffset);
+ } else {
+ gl.glVertexPointer(3, GL.GL_FLOAT, 0, bufferV);
+ }
+ }
+
+ gl.glEnableClientState(GLPointerFunc.GL_COLOR_ARRAY);
+ if(useArrayData) {
+ gl.glColorPointer(arrayC);
+ } else {
+ if(useVBO) {
+ gl.glColorPointer(3, GL.GL_FLOAT, 0, bufferCOffset);
+ } else {
+ gl.glColorPointer(3, GL.GL_FLOAT, 0, bufferC);
+ }
+ }
+
+ if(useVBO) {
+ gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
+ }
+
+ gl.glDrawArrays(GL.GL_TRIANGLES, 0, 3);
+ gl.glFlush();
+
+ gl.glDisableClientState(GLPointerFunc.GL_COLOR_ARRAY);
+ gl.glDisableClientState(GLPointerFunc.GL_VERTEX_ARRAY);
+ }
+
+ @Override
+ public void dispose(GLAutoDrawable drawable) {
+ GL gl = drawable.getGL();
+ if(0 != vboName[0]) {
+ gl.glDeleteBuffers(1, vboName, 0);
+ vboName[0] = 0;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/DemoGL2ES1TextureImmModeSink.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/DemoGL2ES1TextureImmModeSink.java
new file mode 100644
index 0000000..75a98ed
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/DemoGL2ES1TextureImmModeSink.java
@@ -0,0 +1,142 @@
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community OR
+ * CONTRIBUTORS 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.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.opengl.test.junit.jogl.util;
+
+import java.io.InputStream;
+import java.net.URLConnection;
+
+import com.jogamp.common.util.IOUtil;
+import com.jogamp.opengl.test.junit.jogl.demos.TextureDraw01Accessor;
+import com.jogamp.opengl.util.ImmModeSink;
+import com.jogamp.opengl.util.glsl.fixedfunc.FixedFuncUtil;
+import com.jogamp.opengl.util.glsl.fixedfunc.ShaderSelectionMode;
+import com.jogamp.opengl.util.texture.Texture;
+import com.jogamp.opengl.util.texture.TextureCoords;
+import com.jogamp.opengl.util.texture.TextureData;
+import com.jogamp.opengl.util.texture.TextureIO;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2ES1;
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLPipelineFactory;
+import javax.media.opengl.glu.GLU;
+
+public class DemoGL2ES1TextureImmModeSink implements GLEventListener, TextureDraw01Accessor {
+ private boolean debugFFPEmu = false;
+ private boolean verboseFFPEmu = false;
+ private boolean traceFFPEmu = false;
+ private boolean forceFFPEmu = false;
+ private ImmModeSink ims;
+ private GLU glu = new GLU();
+ private TextureData textureData;
+ private Texture texture;
+
+ public DemoGL2ES1TextureImmModeSink() {
+ this.ims = ImmModeSink.createFixed(32, 3, GL.GL_FLOAT, 4, GL.GL_FLOAT, 0, GL.GL_FLOAT, 2, GL.GL_FLOAT, GL.GL_STATIC_DRAW);
+ }
+
+ public void setForceFFPEmu(boolean forceFFPEmu, boolean verboseFFPEmu, boolean debugFFPEmu, boolean traceFFPEmu) {
+ this.forceFFPEmu = forceFFPEmu;
+ this.verboseFFPEmu = verboseFFPEmu;
+ this.debugFFPEmu = debugFFPEmu;
+ this.traceFFPEmu = traceFFPEmu;
+ }
+
+ public void init(GLAutoDrawable drawable) {
+ GL _gl = drawable.getGL();
+ if(debugFFPEmu) {
+ // Debug ..
+ _gl = _gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Debug", GL2ES2.class, _gl, null) );
+ }
+ if(traceFFPEmu) {
+ // Trace ..
+ _gl = _gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Trace", GL2ES2.class, _gl, new Object[] { System.err } ) );
+ }
+ GL2ES1 gl = FixedFuncUtil.wrapFixedFuncEmul(_gl, ShaderSelectionMode.AUTO, null, forceFFPEmu, verboseFFPEmu);
+
+ URLConnection testTextureUrlConn = IOUtil.getResource("jogl/util/data/av/test-ntsc01-160x90.png", this.getClass().getClassLoader());
+ try {
+ InputStream testTextureStream = testTextureUrlConn.getInputStream();
+ textureData = TextureIO.newTextureData(gl.getGLProfile(), testTextureStream , false /* mipmap */, TextureIO.PNG);
+ texture = TextureIO.newTexture(gl, textureData);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public Texture getTexture( ) {
+ return this.texture;
+ }
+
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
+ GL2ES1 gl = drawable.getGL().getGL2ES1();
+ gl.glMatrixMode(GL2ES1.GL_PROJECTION);
+ gl.glLoadIdentity();
+ glu.gluOrtho2D(0, 1, 0, 1);
+ gl.glMatrixMode(GL2ES1.GL_MODELVIEW);
+ gl.glLoadIdentity();
+ }
+
+ public void dispose(GLAutoDrawable drawable) {
+ GL2ES1 gl = drawable.getGL().getGL2ES1();
+ if(null!=texture) {
+ texture.disable(gl);
+ texture.destroy(gl);
+ }
+ if(null!=textureData) {
+ textureData.destroy();
+ }
+ }
+
+ public void display(GLAutoDrawable drawable) {
+ GL2ES1 gl = drawable.getGL().getGL2ES1();
+
+ // draw one quad with the texture
+ if(null!=texture) {
+ texture.enable(gl);
+ texture.bind(gl);
+ // gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL2.GL_REPLACE);
+ TextureCoords coords = texture.getImageTexCoords();
+ ims.glBegin(ImmModeSink.GL_QUADS);
+ ims.glTexCoord2f(coords.left(), coords.bottom());
+ ims.glVertex3f(0, 0, 0);
+ ims.glTexCoord2f(coords.right(), coords.bottom());
+ ims.glVertex3f(1, 0, 0);
+ ims.glTexCoord2f(coords.right(), coords.top());
+ ims.glVertex3f(1, 1, 0);
+ ims.glTexCoord2f(coords.left(), coords.top());
+ ims.glVertex3f(0, 1, 0);
+ ims.glEnd(gl);
+ texture.disable(gl);
+ }
+ }
+}
+
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/newt/TestRedSquareES1NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/TestES1FixedFunctionPipelineNEWT.java
similarity index 53%
copy from src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/newt/TestRedSquareES1NEWT.java
copy to src/test/com/jogamp/opengl/test/junit/jogl/util/TestES1FixedFunctionPipelineNEWT.java
index c327a30..9d84bc5 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/newt/TestRedSquareES1NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/TestES1FixedFunctionPipelineNEWT.java
@@ -26,19 +26,19 @@
* or implied, of JogAmp Community.
*/
-package com.jogamp.opengl.test.junit.jogl.demos.es1.newt;
+package com.jogamp.opengl.test.junit.jogl.util;
-import com.jogamp.newt.event.KeyAdapter;
-import com.jogamp.newt.event.KeyEvent;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.test.junit.util.UITestCase;
import com.jogamp.opengl.test.junit.util.QuitAdapter;
import com.jogamp.opengl.util.Animator;
+import com.jogamp.opengl.test.junit.jogl.demos.es1.GearsES1;
import com.jogamp.opengl.test.junit.jogl.demos.es1.RedSquareES1;
import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
import org.junit.Assert;
@@ -46,7 +46,7 @@ import org.junit.BeforeClass;
import org.junit.AfterClass;
import org.junit.Test;
-public class TestRedSquareES1NEWT extends UITestCase {
+public class TestES1FixedFunctionPipelineNEWT extends UITestCase {
static int width, height;
@BeforeClass
@@ -59,58 +59,83 @@ public class TestRedSquareES1NEWT extends UITestCase {
public static void releaseClass() {
}
- protected void runTestGL(GLCapabilities caps) throws InterruptedException {
+ protected void runTestGL0(GLCapabilities caps, GLEventListener demo) throws InterruptedException {
GLWindow glWindow = GLWindow.create(caps);
Assert.assertNotNull(glWindow);
- glWindow.setTitle("Gears NEWT Test");
+ glWindow.setTitle(getSimpleTestName("."));
- glWindow.addGLEventListener(new RedSquareES1());
+ glWindow.addGLEventListener(demo);
+ final SnapshotGLEventListener snap = new SnapshotGLEventListener();
+ snap.setPostSNDetail(demo.getClass().getSimpleName());
+ glWindow.addGLEventListener(snap);
Animator animator = new Animator(glWindow);
QuitAdapter quitAdapter = new QuitAdapter();
-
- //glWindow.addKeyListener(new TraceKeyAdapter(quitAdapter));
- //glWindow.addWindowListener(new TraceWindowAdapter(quitAdapter));
glWindow.addKeyListener(quitAdapter);
glWindow.addWindowListener(quitAdapter);
- final GLWindow f_glWindow = glWindow;
- glWindow.addKeyListener(new KeyAdapter() {
- public void keyTyped(KeyEvent e) {
- if(e.getKeyChar()=='f') {
- new Thread() {
- public void run() {
- f_glWindow.setFullscreen(!f_glWindow.isFullscreen());
- } }.start();
- } else if(e.getKeyChar()=='d') {
- new Thread() {
- public void run() {
- f_glWindow.setUndecorated(!f_glWindow.isUndecorated());
- } }.start();
- }
- }
- });
-
glWindow.setSize(width, height);
glWindow.setVisible(true);
animator.setUpdateFPSFrames(1, null);
animator.start();
-
+
+ snap.setMakeSnapshot();
while(!quitAdapter.shouldQuit() && animator.isAnimating() && animator.getTotalFPSDuration()<duration) {
Thread.sleep(100);
}
-
+ glWindow.removeGLEventListener(demo);
+
animator.stop();
glWindow.destroy();
}
+
+ protected void runTestGL(GLCapabilities caps, boolean forceFFPEmu) throws InterruptedException {
+ final RedSquareES1 demo01 = new RedSquareES1();
+ demo01.setForceFFPEmu(forceFFPEmu, false, false, false);
+ runTestGL0(caps, demo01);
+
+ final GearsES1 demo02 = new GearsES1();
+ demo02.setForceFFPEmu(forceFFPEmu, false, false, false);
+ runTestGL0(caps, demo02);
+
+ final DemoGL2ES1ImmModeSink demo03 = new DemoGL2ES1ImmModeSink(true);
+ demo03.setForceFFPEmu(forceFFPEmu, false, false, false);
+ runTestGL0(caps, demo03);
+
+ final DemoGL2ES1TextureImmModeSink demo04 = new DemoGL2ES1TextureImmModeSink();
+ demo04.setForceFFPEmu(forceFFPEmu, false, false, false);
+ runTestGL0(caps, demo04);
+ }
@Test
- public void test01() throws InterruptedException {
- GLCapabilities caps = new GLCapabilities(GLProfile.getGL2ES1());
- runTestGL(caps);
+ public void test01GL2Normal() throws InterruptedException {
+ if(!GLProfile.isAvailable(GLProfile.GL2)) { System.err.println("GL2 n/a"); return; }
+ GLCapabilities caps = new GLCapabilities(GLProfile.get(GLProfile.GL2));
+ runTestGL(caps, false);
}
-
- static long duration = 500; // ms
+
+ @Test
+ public void test03GL2FFPEmu() throws InterruptedException {
+ if(!GLProfile.isAvailable(GLProfile.GL2)) { System.err.println("GL2 n/a"); return; }
+ GLCapabilities caps = new GLCapabilities(GLProfile.get(GLProfile.GL2));
+ runTestGL(caps, true);
+ }
+
+ @Test
+ public void test04GL2ES1Normal() throws InterruptedException {
+ if(!GLProfile.isAvailable(GLProfile.GL2ES1)) { System.err.println("GL2ES1 n/a"); return; }
+ GLCapabilities caps = new GLCapabilities(GLProfile.get(GLProfile.GL2ES1));
+ runTestGL(caps, false);
+ }
+
+ @Test
+ public void test05ES2FFPEmu() throws InterruptedException {
+ if(!GLProfile.isAvailable(GLProfile.GLES2)) { System.err.println("GLES2 n/a"); return; }
+ GLCapabilities caps = new GLCapabilities(GLProfile.get(GLProfile.GLES2));
+ runTestGL(caps, false); // should be FFPEmu implicit
+ }
+
+ static long duration = 1000; // ms
public static void main(String args[]) {
for(int i=0; i<args.length; i++) {
@@ -121,6 +146,6 @@ public class TestRedSquareES1NEWT extends UITestCase {
} catch (Exception ex) { ex.printStackTrace(); }
}
}
- org.junit.runner.JUnitCore.main(TestRedSquareES1NEWT.class.getName());
+ org.junit.runner.JUnitCore.main(TestES1FixedFunctionPipelineNEWT.class.getName());
}
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/TestImmModeSinkES1NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/TestImmModeSinkES1NEWT.java
new file mode 100644
index 0000000..d8bdf8a
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/TestImmModeSinkES1NEWT.java
@@ -0,0 +1,140 @@
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community OR
+ * CONTRIBUTORS 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.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.opengl.test.junit.jogl.util;
+
+import java.io.IOException;
+
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLProfile;
+
+import org.junit.Test;
+
+import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.test.junit.util.MiscUtils;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+
+/**
+ * Testing the ImmModeSink w/ GL2ES1 context
+ */
+public class TestImmModeSinkES1NEWT extends UITestCase {
+ static int duration = 100;
+ static final int iWidth = 400;
+ static final int iHeight = 400;
+
+ static GLCapabilities getCaps(String profile) {
+ if( !GLProfile.isAvailable(profile) ) {
+ System.err.println("Profile "+profile+" n/a");
+ return null;
+ }
+ return new GLCapabilities(GLProfile.get(profile));
+ }
+
+ void doTest(GLCapabilitiesImmutable reqGLCaps, GLEventListener demo) throws InterruptedException {
+ System.out.println("Requested GL Caps: "+reqGLCaps);
+
+ //
+ // Create native windowing resources .. X11/Win/OSX
+ //
+ final GLWindow glad = GLWindow.create(reqGLCaps);
+ glad.addGLEventListener(demo);
+
+ final SnapshotGLEventListener snapshotGLEventListener = new SnapshotGLEventListener();
+ glad.addGLEventListener(snapshotGLEventListener);
+ glad.setSize(iWidth, iHeight);
+ glad.setVisible(true);
+
+ snapshotGLEventListener.setMakeSnapshot();
+ glad.display(); // initial resize/display
+
+ Thread.sleep(duration);
+
+ glad.destroy();
+ }
+
+ @Test
+ public void test01Plain__GL2ES1_VBOOffUsePlain() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2ES1);
+ if(null == reqGLCaps) return;
+ doTest(reqGLCaps, new DemoGL2ES1Plain(false, false));
+ }
+
+ @Test
+ public void test02Plain__GL2ES1_VBOOffUseArrayData() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2ES1);
+ if(null == reqGLCaps) return;
+ doTest(reqGLCaps, new DemoGL2ES1Plain(true, false));
+ }
+
+ @Test
+ public void test03Plain__GL2ES1_VBOOnUsePlain() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2ES1);
+ if(null == reqGLCaps) return;
+ doTest(reqGLCaps, new DemoGL2ES1Plain(false, true));
+ }
+
+ @Test
+ public void test04Plain__GL2ES1_VBOOnUseArrayData() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2ES1);
+ if(null == reqGLCaps) return;
+ doTest(reqGLCaps, new DemoGL2ES1Plain(true, true));
+ }
+
+ @Test
+ public void test05ImmSinkGL2ES1_VBOOff() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2ES1);
+ if(null == reqGLCaps) return;
+ doTest(reqGLCaps, new DemoGL2ES1ImmModeSink(false));
+ }
+
+ @Test
+ public void test06ImmSinkGL2ES1_VBOOn() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2ES1);
+ if(null == reqGLCaps) return;
+ doTest(reqGLCaps, new DemoGL2ES1ImmModeSink(true));
+ }
+
+ @Test
+ public void test07ImmSinkGL2ES1_VBOOnTexture() throws InterruptedException {
+ final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2ES1);
+ if(null == reqGLCaps) return;
+ doTest(reqGLCaps, new DemoGL2ES1TextureImmModeSink());
+ }
+
+ public static void main(String args[]) throws IOException {
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-time")) {
+ duration = MiscUtils.atoi(args[++i], duration);
+ }
+ }
+ org.junit.runner.JUnitCore.main(TestImmModeSinkES1NEWT.class.getName());
+ }
+
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite01AWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite01AWT.java
index 6cee319..e2252d6 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite01AWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite01AWT.java
@@ -96,8 +96,8 @@ public class TestGLReadBufferUtilTextureIOWrite01AWT extends UITestCase {
public void init(GLAutoDrawable drawable) {}
public void dispose(GLAutoDrawable drawable) {}
public void display(GLAutoDrawable drawable) {
- snapshot(getSimpleTestName("."), f, null, drawable.getGL(), screenshotRGBA, TextureIO.PNG, null);
- snapshot(getSimpleTestName("."), f, null, drawable.getGL(), screenshotRGB, TextureIO.PNG, null);
+ snapshot(f, null, drawable.getGL(), screenshotRGBA, TextureIO.PNG, null);
+ snapshot(f, null, drawable.getGL(), screenshotRGB, TextureIO.PNG, null);
f++;
}
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { }
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite01NEWT.java
index 5681df0..16bd94c 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite01NEWT.java
@@ -75,12 +75,12 @@ public class TestGLReadBufferUtilTextureIOWrite01NEWT extends UITestCase {
public void init(GLAutoDrawable drawable) {}
public void dispose(GLAutoDrawable drawable) {}
public void display(GLAutoDrawable drawable) {
- snapshot(getSimpleTestName("."), f++, null, drawable.getGL(), screenshotRGBA, TextureIO.PNG, null);
- snapshot(getSimpleTestName("."), f++, null, drawable.getGL(), screenshotRGB, TextureIO.PNG, null);
- snapshot(getSimpleTestName("."), f++, null, drawable.getGL(), screenshotRGBA, TextureIO.TGA, null);
- snapshot(getSimpleTestName("."), f++, null, drawable.getGL(), screenshotRGB, TextureIO.TGA, null);
- snapshot(getSimpleTestName("."), f++, null, drawable.getGL(), screenshotRGBA, TextureIO.PAM, null);
- snapshot(getSimpleTestName("."), f++, null, drawable.getGL(), screenshotRGB, TextureIO.PAM, null);
+ snapshot(f++, null, drawable.getGL(), screenshotRGBA, TextureIO.PNG, null);
+ snapshot(f++, null, drawable.getGL(), screenshotRGB, TextureIO.PNG, null);
+ snapshot(f++, null, drawable.getGL(), screenshotRGBA, TextureIO.TGA, null);
+ snapshot(f++, null, drawable.getGL(), screenshotRGB, TextureIO.TGA, null);
+ snapshot(f++, null, drawable.getGL(), screenshotRGBA, TextureIO.PAM, null);
+ snapshot(f++, null, drawable.getGL(), screenshotRGB, TextureIO.PAM, null);
}
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { }
});
@@ -103,8 +103,8 @@ public class TestGLReadBufferUtilTextureIOWrite01NEWT extends UITestCase {
public void init(GLAutoDrawable drawable) {}
public void dispose(GLAutoDrawable drawable) {}
public void display(GLAutoDrawable drawable) {
- snapshot(getSimpleTestName("."), f, null, drawable.getGL(), screenshotRGBA, TextureIO.PNG, null);
- snapshot(getSimpleTestName("."), f, null, drawable.getGL(), screenshotRGB, TextureIO.PNG, null);
+ snapshot(f, null, drawable.getGL(), screenshotRGBA, TextureIO.PNG, null);
+ snapshot(f, null, drawable.getGL(), screenshotRGB, TextureIO.PNG, null);
f++;
}
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { }
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite02AWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite02AWT.java
index 43641fe..bec55d8 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite02AWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite02AWT.java
@@ -111,7 +111,7 @@ public class TestGLReadBufferUtilTextureIOWrite02AWT extends UITestCase {
if(snap) {
System.err.println("XXX: ["+fw_old+", "+dw_old+"], "+fw+"x"+fh+", "+dw+"x"+dh+", sz_changed "+sz_changed+", snap "+snap);
c=0;
- snapshot(getSimpleTestName("."), i++, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
+ snapshot(i++, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
dw_old = dw;
fw_old = fw;
Threading.invoke(true, new Runnable() {
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite02NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite02NEWT.java
index d1ffa84..36d905a 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite02NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite02NEWT.java
@@ -94,7 +94,7 @@ public class TestGLReadBufferUtilTextureIOWrite02NEWT extends UITestCase {
if(snap) {
System.err.println("XXX: ["+dw_old+"], "+dw+"x"+dh+", sz_changed "+sz_changed+", snap "+snap);
c=0;
- snapshot(getSimpleTestName("."), i++, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
+ snapshot(i++, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
dw_old = dw;
new Thread() {
@Override
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileAWT.java
index 0d4f2b0..7dbccd5 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileAWT.java
@@ -140,7 +140,7 @@ public class TestPNGTextureFromFileAWT extends UITestCase {
// 1 snapshot
if(null!=((TextureDraw01Accessor)gle).getTexture() && !shot) {
shot = true;
- snapshot(getSimpleTestName("."), 0, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
+ snapshot(0, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
}
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileNEWT.java
index b4faafb..e9ef9b9 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileNEWT.java
@@ -112,7 +112,7 @@ public class TestPNGTextureFromFileNEWT extends UITestCase {
// 1 snapshot
if(null!=((TextureDraw01Accessor)gle).getTexture() && !shot) {
shot = true;
- snapshot(getSimpleTestName("."), 0, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
+ snapshot(0, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
}
}
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestFocus01SwingAWTRobot.java b/src/test/com/jogamp/opengl/test/junit/newt/TestFocus01SwingAWTRobot.java
index bb67e77..5d6218d 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestFocus01SwingAWTRobot.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestFocus01SwingAWTRobot.java
@@ -35,6 +35,7 @@ import org.junit.Assume;
import java.awt.AWTException;
import java.awt.BorderLayout;
import java.awt.Button;
+import java.awt.Container;
import java.awt.Robot;
import java.lang.reflect.InvocationTargetException;
@@ -55,6 +56,15 @@ import com.jogamp.opengl.test.junit.jogl.demos.es2.RedSquareES2;
import com.jogamp.opengl.test.junit.util.*;
+/**
+ * Testing focus traversal of an AWT component tree with {@link NewtCanvasAWT} attached.
+ * <p>
+ * {@link JFrame} . {@link Container}+ . {@link NewtCanvasAWT} . {@link GLWindow}
+ * </p>
+ * <p>
+ * <i>+ Container is the JFrame's implicit root content pane</i><br/>
+ * </p>
+ */
public class TestFocus01SwingAWTRobot extends UITestCase {
static int width, height;
static long durationPerTest = 10;
@@ -125,6 +135,10 @@ public class TestFocus01SwingAWTRobot extends UITestCase {
AWTKeyAdapter buttonKA = new AWTKeyAdapter("Button");
button.addKeyListener(buttonKA);
eventCountAdapters.add(buttonKA);
+ AWTMouseAdapter buttonMA = new AWTMouseAdapter("Button");
+ button.addMouseListener(buttonMA);
+ eventCountAdapters.add(buttonMA);
+
frame1.getContentPane().add(button, BorderLayout.NORTH);
frame1.setSize(width, height);
javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
@@ -149,22 +163,27 @@ public class TestFocus01SwingAWTRobot extends UITestCase {
animator.start();
// Button Focus
- Thread.sleep(100); // allow event sync
+ Thread.sleep(200); // allow event sync
System.err.println("FOCUS AWT Button request");
EventCountAdapterUtil.reset(eventCountAdapters);
- AWTRobotUtil.assertRequestFocusAndWait(robot, button, button, buttonFA, frame1FA);
+ AWTRobotUtil.assertRequestFocusAndWait(robot, button, button, buttonFA, frame1FA); // OSX sporadically button did not gain - major UI failure
Assert.assertEquals(false, glWindow1FA.focusGained());
Assert.assertEquals(false, newtCanvasAWTFA.focusGained());
System.err.println("FOCUS AWT Button sync");
AWTRobotUtil.assertKeyType(robot, java.awt.event.KeyEvent.VK_A, 2, button, buttonKA);
+ AWTRobotUtil.assertMouseClick(robot, java.awt.event.InputEvent.BUTTON1_MASK, 1,
+ button, buttonMA);
+ AWTRobotUtil.assertMouseClick(robot, java.awt.event.InputEvent.BUTTON1_MASK, 2,
+ button, buttonMA);
// Request the AWT focus, which should automatically provide the NEWT window with focus.
Thread.sleep(100); // allow event sync
System.err.println("FOCUS NEWT Canvas/GLWindow request");
EventCountAdapterUtil.reset(eventCountAdapters);
- AWTRobotUtil.assertRequestFocusAndWait(robot, newtCanvasAWT, newtCanvasAWT.getNEWTChild(), glWindow1FA, buttonFA);
- Assert.assertEquals(false, newtCanvasAWTFA.focusGained());
+ AWTRobotUtil.assertRequestFocusAndWait(robot, newtCanvasAWT, newtCanvasAWT.getNEWTChild(), glWindow1FA, buttonFA); // OSX sporadically button did not loose - minor UI failure
+ Assert.assertTrue("Focus prev. gained, but NewtCanvasAWT didn't loose it. Gainer: "+glWindow1FA+"; Looser "+newtCanvasAWTFA,
+ AWTRobotUtil.waitForFocus(glWindow1FA, newtCanvasAWTFA));
System.err.println("FOCUS NEWT Canvas/GLWindow sync");
AWTRobotUtil.assertKeyType(robot, java.awt.event.KeyEvent.VK_A, 2, glWindow1, glWindow1KA);
Assert.assertEquals("AWT parent canvas received keyboard events", 0, newtCanvasAWTKA.getCount());
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestFocus02SwingAWTRobot.java b/src/test/com/jogamp/opengl/test/junit/newt/TestFocus02SwingAWTRobot.java
index a0efa53..0e87144 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestFocus02SwingAWTRobot.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestFocus02SwingAWTRobot.java
@@ -56,6 +56,15 @@ import java.io.IOException;
import com.jogamp.opengl.test.junit.util.*;
import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+/**
+ * Testing focus traversal of an AWT component tree with {@link NewtCanvasAWT} attached.
+ * <p>
+ * {@link JFrame} . {@link JPanel}+ . {@link Container} . {@link NewtCanvasAWT} . {@link GLWindow}
+ * </p>
+ * <p>
+ * <i>+ JPanel is set as JFrame's root content pane</i><br/>
+ * </p>
+ */
public class TestFocus02SwingAWTRobot extends UITestCase {
static int width, height;
static long durationPerTest = 10;
@@ -85,9 +94,6 @@ public class TestFocus02SwingAWTRobot extends UITestCase {
ArrayList<EventCountAdapter> eventCountAdapters = new ArrayList<EventCountAdapter>();
- /**
- * JFrame . JPanel . Container . NewtCanvasAWT . GLWindow
- */
GLWindow glWindow1 = GLWindow.create(glCaps);
glWindow1.setTitle("testWindowParenting01CreateVisibleDestroy");
GLEventListener demo1 = new GearsES2();
@@ -177,12 +183,12 @@ public class TestFocus02SwingAWTRobot extends UITestCase {
Thread.sleep(100); // allow event sync
System.err.println("FOCUS AWT Button Outer request");
EventCountAdapterUtil.reset(eventCountAdapters);
- AWTRobotUtil.assertRequestFocusAndWait(robot, buttonNorthOuter, buttonNorthOuter, buttonNorthOuterFA, jFrame1FA);
+ AWTRobotUtil.assertRequestFocusAndWait(robot, buttonNorthOuter, buttonNorthOuter, buttonNorthOuterFA, jFrame1FA); // OSX sporadically buttonNorthOuter did not gain - major UI failure
Assert.assertEquals(false, glWindow1FA.focusGained());
Assert.assertEquals(false, newtCanvasAWTFA.focusGained());
Assert.assertEquals(false, buttonNorthInnerFA.focusGained());
System.err.println("FOCUS AWT Button Outer sync");
- AWTRobotUtil.assertKeyType(robot, java.awt.event.KeyEvent.VK_A, 2, buttonNorthOuter, buttonNorthOuterKA);
+ AWTRobotUtil.assertKeyType(robot, java.awt.event.KeyEvent.VK_A, 2, buttonNorthOuter, buttonNorthOuterKA); // OSX sporadically won't receive the keyboard input - major UI failure
AWTRobotUtil.assertMouseClick(robot, java.awt.event.InputEvent.BUTTON1_MASK, 1,
buttonNorthOuter, buttonNorthOuterMA);
AWTRobotUtil.assertMouseClick(robot, java.awt.event.InputEvent.BUTTON1_MASK, 2,
@@ -225,7 +231,9 @@ public class TestFocus02SwingAWTRobot extends UITestCase {
System.err.println("FOCUS NEWT Canvas/GLWindow request");
EventCountAdapterUtil.reset(eventCountAdapters);
AWTRobotUtil.assertRequestFocusAndWait(robot, newtCanvasAWT, newtCanvasAWT.getNEWTChild(), glWindow1FA, buttonNorthInnerFA);
- Assert.assertTrue(AWTRobotUtil.waitForFocusCount(false, newtCanvasAWTFA));
+ Assert.assertTrue("Focus prev. gained, but NewtCanvasAWT didn't loose it. Gainer: "+glWindow1FA+"; Looser "+newtCanvasAWTFA,
+ AWTRobotUtil.waitForFocus(glWindow1FA, newtCanvasAWTFA));
+
Assert.assertEquals(false, newtCanvasAWTFA.focusGained());
Assert.assertEquals(false, buttonNorthOuterFA.focusGained());
Assert.assertEquals(false, jFrame1FA.focusGained());
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyCodeModifiersAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyCodeModifiersAWT.java
new file mode 100644
index 0000000..b067883
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyCodeModifiersAWT.java
@@ -0,0 +1,275 @@
+/**
+ * Copyright 2012 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community OR
+ * CONTRIBUTORS 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.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.opengl.test.junit.newt;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.AfterClass;
+import org.junit.Assume;
+import org.junit.Before;
+
+import java.awt.AWTException;
+import java.awt.BorderLayout;
+import java.awt.Robot;
+import java.lang.reflect.InvocationTargetException;
+import java.util.EventObject;
+import java.util.List;
+
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLEventListener;
+import javax.swing.JFrame;
+
+import java.io.IOException;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.jogamp.newt.awt.NewtCanvasAWT;
+import com.jogamp.newt.event.InputEvent;
+import com.jogamp.newt.event.KeyEvent;
+import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.util.Animator;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.RedSquareES2;
+
+import com.jogamp.opengl.test.junit.util.*;
+
+/**
+ * Testing combinations of key code modifiers of key event.
+ */
+public class TestNewtKeyCodeModifiersAWT extends UITestCase {
+ static int width, height;
+ static long durationPerTest = 100;
+ static long awtWaitTimeout = 1000;
+
+ static GLCapabilities glCaps;
+
+ @BeforeClass
+ public static void initClass() {
+ width = 640;
+ height = 480;
+ glCaps = new GLCapabilities(null);
+ }
+
+ @AfterClass
+ public static void release() {
+ }
+
+ @Before
+ public void initTest() {
+ }
+
+ @After
+ public void releaseTest() {
+ }
+
+ @Test
+ public void test01NEWT() throws AWTException, InterruptedException, InvocationTargetException {
+ GLWindow glWindow = GLWindow.create(glCaps);
+ glWindow.setSize(width, height);
+ glWindow.setVisible(true);
+
+ testImpl(glWindow);
+
+ glWindow.destroy();
+ }
+
+ @Test
+ public void test02NewtCanvasAWT() throws AWTException, InterruptedException, InvocationTargetException {
+ GLWindow glWindow = GLWindow.create(glCaps);
+
+ // Wrap the window in a canvas.
+ final NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow);
+
+ // Add the canvas to a frame, and make it all visible.
+ final JFrame frame1 = new JFrame("Swing AWT Parent Frame: "+ glWindow.getTitle());
+ frame1.getContentPane().add(newtCanvasAWT, BorderLayout.CENTER);
+ frame1.setSize(width, height);
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ frame1.setVisible(true);
+ } } );
+
+ Assert.assertEquals(true, AWTRobotUtil.waitForVisible(frame1, true));
+
+ testImpl(glWindow);
+
+ try {
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ frame1.setVisible(false);
+ frame1.dispose();
+ }});
+ } catch( Throwable throwable ) {
+ throwable.printStackTrace();
+ Assume.assumeNoException( throwable );
+ }
+ glWindow.destroy();
+ }
+
+ static void testKeyCodeModifier(Robot robot, NEWTKeyAdapter keyAdapter, int modifierKey, int modifierMask) {
+ keyAdapter.reset();
+ AWTRobotUtil.keyPress(0, robot, true, KeyEvent.VK_P, 10); // press P
+ AWTRobotUtil.keyPress(0, robot, false, KeyEvent.VK_P, 100); // release+typed P
+ robot.waitForIdle();
+ for(int j=0; j < 10 && keyAdapter.getQueueSize() < 3; j++) { // wait until events are collected
+ robot.delay(100);
+ }
+
+ AWTRobotUtil.keyPress(0, robot, true, modifierKey, 10); // press MOD
+ AWTRobotUtil.keyPress(0, robot, true, KeyEvent.VK_P, 10); // press P
+ AWTRobotUtil.keyPress(0, robot, false, KeyEvent.VK_P, 10); // release+typed P
+ AWTRobotUtil.keyPress(0, robot, false, modifierKey, 100); // release+typed MOD
+ robot.waitForIdle();
+ for(int j=0; j < 10 && keyAdapter.getQueueSize() < 3+6; j++) { // wait until events are collected
+ robot.delay(100);
+ }
+ NEWTKeyUtil.validateKeyAdapterStats(keyAdapter, 3+6, 0);
+
+ final List<EventObject> queue = keyAdapter.getQueued();
+ int i=0;
+ NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_PRESSED, 0, KeyEvent.VK_P);
+ NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_RELEASED, 0, KeyEvent.VK_P);
+ NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_TYPED, 0, KeyEvent.VK_P);
+
+ NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_PRESSED, modifierMask, modifierKey);
+ NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_PRESSED, modifierMask, KeyEvent.VK_P);
+ NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_RELEASED, modifierMask, KeyEvent.VK_P);
+ NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_TYPED, modifierMask, KeyEvent.VK_P);
+ NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_RELEASED, modifierMask, modifierKey);
+ NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_TYPED, modifierMask, modifierKey);
+ }
+
+ static void testKeyCodeAllModifierV1(Robot robot, NEWTKeyAdapter keyAdapter) {
+ final int m1k = KeyEvent.VK_ALT;
+ final int m1m = InputEvent.ALT_MASK;
+ final int m2k = KeyEvent.VK_CONTROL;
+ final int m2m = InputEvent.CTRL_MASK;
+ final int m3k = KeyEvent.VK_SHIFT;
+ final int m3m = InputEvent.SHIFT_MASK;
+
+ keyAdapter.reset();
+ AWTRobotUtil.keyPress(0, robot, true, m1k, 10); // press MOD1
+ AWTRobotUtil.keyPress(0, robot, true, m2k, 10); // press MOD2
+ AWTRobotUtil.keyPress(0, robot, true, m3k, 10); // press MOD3
+ AWTRobotUtil.keyPress(0, robot, true, KeyEvent.VK_P, 10); // press P
+
+ AWTRobotUtil.keyPress(0, robot, false, KeyEvent.VK_P, 100); // release+typed P
+ AWTRobotUtil.keyPress(0, robot, false, m3k, 10); // release+typed MOD
+ AWTRobotUtil.keyPress(0, robot, false, m2k, 10); // release+typed MOD
+ AWTRobotUtil.keyPress(0, robot, false, m1k, 10); // release+typed MOD
+
+ robot.waitForIdle();
+ for(int j=0; j < 10 && keyAdapter.getQueueSize() < 3*4; j++) { // wait until events are collected
+ robot.delay(100);
+ }
+ NEWTKeyUtil.validateKeyAdapterStats(keyAdapter, 3*4, 0);
+
+ final List<EventObject> queue = keyAdapter.getQueued();
+ int i=0;
+ NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_PRESSED, m1m, m1k);
+ NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_PRESSED, m1m|m2m, m2k);
+ NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_PRESSED, m1m|m2m|m3m, m3k);
+
+ NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_PRESSED, m1m|m2m|m3m, KeyEvent.VK_P);
+ NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_RELEASED, m1m|m2m|m3m, KeyEvent.VK_P);
+ NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_TYPED, m1m|m2m|m3m, KeyEvent.VK_P);
+
+ NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_RELEASED, m1m|m2m|m3m, m3k);
+ NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_TYPED, m1m|m2m|m3m, m3k);
+ NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_RELEASED, m1m|m2m, m2k);
+ NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_TYPED, m1m|m2m, m2k);
+ NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_RELEASED, m1m, m1k);
+ NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_TYPED, m1m, m1k);
+ }
+
+ void testImpl(GLWindow glWindow) throws AWTException, InterruptedException, InvocationTargetException {
+ final Robot robot = new Robot();
+ robot.setAutoWaitForIdle(true);
+
+ GLEventListener demo1 = new RedSquareES2();
+ TestListenerCom01AWT.setDemoFields(demo1, glWindow, false);
+ glWindow.addGLEventListener(demo1);
+
+ // NEWTFocusAdapter glWindow1FA = new NEWTFocusAdapter("GLWindow1");
+ // glWindow.addWindowListener(glWindow1FA);
+ NEWTKeyAdapter glWindow1KA = new NEWTKeyAdapter("GLWindow1");
+ glWindow1KA.setVerbose(false);
+ glWindow.addKeyListener(glWindow1KA);
+
+ Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glWindow, true));
+
+ // Continuous animation ..
+ Animator animator = new Animator(glWindow);
+ animator.start();
+
+ Thread.sleep(durationPerTest); // manual testing
+
+ AWTRobotUtil.assertRequestFocusAndWait(null, glWindow, glWindow, null, null); // programmatic
+ AWTRobotUtil.requestFocus(robot, glWindow, false); // within unit framework, prev. tests (TestFocus02SwingAWTRobot) 'confuses' Windows keyboard input
+ glWindow1KA.reset();
+
+ testKeyCodeModifier(robot, glWindow1KA, KeyEvent.VK_SHIFT, InputEvent.SHIFT_MASK);
+ testKeyCodeModifier(robot, glWindow1KA, KeyEvent.VK_CONTROL, InputEvent.CTRL_MASK);
+ testKeyCodeModifier(robot, glWindow1KA, KeyEvent.VK_ALT, InputEvent.ALT_MASK);
+
+ testKeyCodeAllModifierV1(robot, glWindow1KA);
+
+ // Remove listeners to avoid logging during dispose/destroy.
+ glWindow.removeKeyListener(glWindow1KA);
+
+ // Shutdown the test.
+ animator.stop();
+ }
+
+ static int atoi(String a) {
+ int i=0;
+ try {
+ i = 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]);
+ }
+ }
+ /**
+ BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
+ System.err.println("Press enter to continue");
+ System.err.println(stdin.readLine());
+ */
+ System.out.println("durationPerTest: "+durationPerTest);
+ String tstname = TestNewtKeyCodeModifiersAWT.class.getName();
+ org.junit.runner.JUnitCore.main(tstname);
+ }
+
+
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestFocus01SwingAWTRobot.java b/src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyCodesAWT.java
similarity index 50%
copy from src/test/com/jogamp/opengl/test/junit/newt/TestFocus01SwingAWTRobot.java
copy to src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyCodesAWT.java
index bb67e77..e786eaf 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestFocus01SwingAWTRobot.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyCodesAWT.java
@@ -1,5 +1,5 @@
/**
- * Copyright 2010 JogAmp Community. All rights reserved.
+ * Copyright 2012 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
@@ -28,21 +28,24 @@
package com.jogamp.opengl.test.junit.newt;
+import org.junit.After;
import org.junit.Assert;
import org.junit.AfterClass;
import org.junit.Assume;
+import org.junit.Before;
import java.awt.AWTException;
import java.awt.BorderLayout;
-import java.awt.Button;
import java.awt.Robot;
import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.EventObject;
+import java.util.List;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.swing.JFrame;
-import java.util.ArrayList;
import java.io.IOException;
import org.junit.BeforeClass;
@@ -54,10 +57,14 @@ import com.jogamp.opengl.util.Animator;
import com.jogamp.opengl.test.junit.jogl.demos.es2.RedSquareES2;
import com.jogamp.opengl.test.junit.util.*;
+import com.jogamp.opengl.test.junit.util.NEWTKeyUtil.CodeSeg;
-public class TestFocus01SwingAWTRobot extends UITestCase {
+/**
+ * Testing key code of key events.
+ */
+public class TestNewtKeyCodesAWT extends UITestCase {
static int width, height;
- static long durationPerTest = 10;
+ static long durationPerTest = 100;
static long awtWaitTimeout = 1000;
static GLCapabilities glCaps;
@@ -72,111 +79,46 @@ public class TestFocus01SwingAWTRobot extends UITestCase {
@AfterClass
public static void release() {
}
-
- @Test
- public void testFocus01ProgrFocus() throws AWTException, InterruptedException, InvocationTargetException {
- testFocus01ProgrFocusImpl(null);
+
+ @Before
+ public void initTest() {
}
+ @After
+ public void releaseTest() {
+ }
+
@Test
- public void testFocus02RobotFocus() throws AWTException, InterruptedException, InvocationTargetException {
- Robot robot = new Robot();
- robot.setAutoWaitForIdle(true);
- testFocus01ProgrFocusImpl(robot);
+ public void test01NEWT() throws AWTException, InterruptedException, InvocationTargetException {
+ GLWindow glWindow = GLWindow.create(glCaps);
+ glWindow.setSize(width, height);
+ glWindow.setVisible(true);
+
+ testImpl(glWindow);
+
+ glWindow.destroy();
}
-
- private void testFocus01ProgrFocusImpl(Robot robot) throws AWTException,
- InvocationTargetException, InterruptedException {
- ArrayList<EventCountAdapter> eventCountAdapters = new ArrayList<EventCountAdapter>();
-
- // Create a window.
- GLWindow glWindow1 = GLWindow.create(glCaps);
- glWindow1.setTitle("testNewtChildFocus");
- GLEventListener demo1 = new RedSquareES2();
- TestListenerCom01AWT.setDemoFields(demo1, glWindow1, false);
- glWindow1.addGLEventListener(demo1);
- NEWTFocusAdapter glWindow1FA = new NEWTFocusAdapter("GLWindow1");
- glWindow1.addWindowListener(glWindow1FA);
-
- // Monitor NEWT focus and keyboard events.
- NEWTKeyAdapter glWindow1KA = new NEWTKeyAdapter("GLWindow1");
- eventCountAdapters.add(glWindow1KA);
- glWindow1.addKeyListener(glWindow1KA);
-
+
+ @Test
+ public void test02NewtCanvasAWT() throws AWTException, InterruptedException, InvocationTargetException {
+ GLWindow glWindow = GLWindow.create(glCaps);
+
// Wrap the window in a canvas.
- final NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow1);
-
- // Monitor AWT focus and keyboard events.
- AWTKeyAdapter newtCanvasAWTKA = new AWTKeyAdapter("NewtCanvasAWT");
- newtCanvasAWT.addKeyListener(newtCanvasAWTKA);
- eventCountAdapters.add(newtCanvasAWTKA);
- AWTFocusAdapter newtCanvasAWTFA = new AWTFocusAdapter("NewtCanvasAWT");
- newtCanvasAWT.addFocusListener(newtCanvasAWTFA);
-
+ final NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow);
+
// Add the canvas to a frame, and make it all visible.
- final JFrame frame1 = new JFrame("Swing AWT Parent Frame: "
- + glWindow1.getTitle());
- AWTFocusAdapter frame1FA = new AWTFocusAdapter("frame1");
- frame1.addFocusListener(frame1FA);
+ final JFrame frame1 = new JFrame("Swing AWT Parent Frame: "+ glWindow.getTitle());
frame1.getContentPane().add(newtCanvasAWT, BorderLayout.CENTER);
- final Button button = new Button("Click me ..");
- AWTFocusAdapter buttonFA = new AWTFocusAdapter("Button");
- button.addFocusListener(buttonFA);
- AWTKeyAdapter buttonKA = new AWTKeyAdapter("Button");
- button.addKeyListener(buttonKA);
- eventCountAdapters.add(buttonKA);
- frame1.getContentPane().add(button, BorderLayout.NORTH);
frame1.setSize(width, height);
javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
frame1.setVisible(true);
} } );
+
Assert.assertEquals(true, AWTRobotUtil.waitForVisible(frame1, true));
- Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glWindow1, true));
- AWTRobotUtil.clearAWTFocus(robot);
- Assert.assertTrue(AWTRobotUtil.toFrontAndRequestFocus(robot, frame1));
-
- Thread.sleep(durationPerTest); // manual testing
- int wait=0;
- while(wait<awtWaitTimeout/100 && glWindow1.getTotalFPSFrames()<1) { Thread.sleep(awtWaitTimeout/10); wait++; }
- System.err.println("Frames for initial setVisible(true): "+glWindow1.getTotalFPSFrames());
- Assert.assertTrue(glWindow1.isVisible());
- Assert.assertTrue(0 < glWindow1.getTotalFPSFrames());
-
- // Continuous animation ..
- Animator animator = new Animator(glWindow1);
- animator.start();
-
- // Button Focus
- Thread.sleep(100); // allow event sync
+ testImpl(glWindow);
- System.err.println("FOCUS AWT Button request");
- EventCountAdapterUtil.reset(eventCountAdapters);
- AWTRobotUtil.assertRequestFocusAndWait(robot, button, button, buttonFA, frame1FA);
- Assert.assertEquals(false, glWindow1FA.focusGained());
- Assert.assertEquals(false, newtCanvasAWTFA.focusGained());
- System.err.println("FOCUS AWT Button sync");
- AWTRobotUtil.assertKeyType(robot, java.awt.event.KeyEvent.VK_A, 2, button, buttonKA);
-
- // Request the AWT focus, which should automatically provide the NEWT window with focus.
- Thread.sleep(100); // allow event sync
- System.err.println("FOCUS NEWT Canvas/GLWindow request");
- EventCountAdapterUtil.reset(eventCountAdapters);
- AWTRobotUtil.assertRequestFocusAndWait(robot, newtCanvasAWT, newtCanvasAWT.getNEWTChild(), glWindow1FA, buttonFA);
- Assert.assertEquals(false, newtCanvasAWTFA.focusGained());
- System.err.println("FOCUS NEWT Canvas/GLWindow sync");
- AWTRobotUtil.assertKeyType(robot, java.awt.event.KeyEvent.VK_A, 2, glWindow1, glWindow1KA);
- Assert.assertEquals("AWT parent canvas received keyboard events", 0, newtCanvasAWTKA.getCount());
-
- // Remove listeners to avoid logging during dispose/destroy.
- glWindow1.removeKeyListener(glWindow1KA);
- glWindow1.removeWindowListener(glWindow1FA);
- newtCanvasAWT.removeKeyListener(newtCanvasAWTKA);
- newtCanvasAWT.removeFocusListener(newtCanvasAWTFA);
-
- // Shutdown the test.
- animator.stop();
try {
javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
@@ -187,7 +129,93 @@ public class TestFocus01SwingAWTRobot extends UITestCase {
throwable.printStackTrace();
Assume.assumeNoException( throwable );
}
- glWindow1.destroy();
+ glWindow.destroy();
+ }
+
+ static CodeSeg[] codeSegments = new CodeSeg[] {
+ new CodeSeg(0x008, 0x008, "bs"),
+ // new CodeSeg(0x009, 0x009, "tab"), // TAB functions as focus traversal key
+ new CodeSeg(0x00a, 0x00a, "cr"),
+ new CodeSeg(0x010, 0x012, "shift, ctrl, alt"),
+ new CodeSeg(0x01B, 0x01B, "esc"),
+ new CodeSeg(0x020, 0x024, "space, up, down, end, home"),
+ new CodeSeg(0x025, 0x028, "cursor"),
+ new CodeSeg(0x02C, 0x02F, ", - . /"),
+ new CodeSeg(0x030, 0x039, "0 - 9"),
+ new CodeSeg(0x03B, 0x03B, ";"),
+ new CodeSeg(0x03D, 0x03D, "="),
+ new CodeSeg(0x041, 0x05A, "a - z"),
+ new CodeSeg(0x05B, 0x05D, "[ \\ ]"),
+ // new CodeSeg(0x060, 0x06B, "numpad1"), // can be mapped to normal keycodes
+ // new CodeSeg(0x06D, 0x06F, "numpad2"), // can be mapped to normal keycodes
+ new CodeSeg(0x07F, 0x07F, "del"),
+ // new CodeSeg(0x090, 0x091, "num lock, scroll lock"),
+ // new CodeSeg(0x070, 0x07B, "F1 - F12"),
+ // new CodeSeg(0x09A, 0x09D, "prt ins hlp meta"),
+ new CodeSeg(0x0C0, 0x0C0, "back quote"),
+ new CodeSeg(0x0DE, 0x0DE, "quote"),
+ // new CodeSeg(0x0E0, 0x0E3, "cursor kp"),
+ // new CodeSeg(0x080, 0x08F, "dead-1"),
+ // new CodeSeg(0x096, 0x0A2, "& ^ \" < > { }"),
+ // new CodeSeg(0x200, 0x20D, "extra-2"), // @ ; ..
+ };
+
+ static void testKeyCodes(Robot robot, NEWTKeyAdapter keyAdapter) {
+ final List<List<EventObject>> cse = new ArrayList<List<EventObject>>();
+
+ for(int i=0; i<codeSegments.length; i++) {
+ keyAdapter.reset();
+ final CodeSeg codeSeg = codeSegments[i];
+ // System.err.println("*** Segment "+codeSeg.description);
+ for(int c=codeSeg.min; c<=codeSeg.max; c++) {
+ // System.err.println("*** KeyCode 0x"+Integer.toHexString(c));
+ AWTRobotUtil.keyPress(0, robot, true, c, 10);
+ AWTRobotUtil.keyPress(0, robot, false, c, 100);
+ robot.waitForIdle();
+ }
+ final int codeCount = codeSeg.max - codeSeg.min + 1;
+ for(int j=0; j < 10 && keyAdapter.getQueueSize() < 3 * codeCount; j++) { // wait until events are collected
+ robot.delay(100);
+ }
+ final ArrayList<EventObject> events = new ArrayList<EventObject>(keyAdapter.getQueued());
+ cse.add(events);
+ }
+ Assert.assertEquals("KeyCode impl. incomplete", true, NEWTKeyUtil.validateKeyCodes(codeSegments, cse, true));
+ }
+
+ void testImpl(GLWindow glWindow) throws AWTException, InterruptedException, InvocationTargetException {
+ final Robot robot = new Robot();
+ robot.setAutoWaitForIdle(true);
+
+ GLEventListener demo1 = new RedSquareES2();
+ TestListenerCom01AWT.setDemoFields(demo1, glWindow, false);
+ glWindow.addGLEventListener(demo1);
+
+ // NEWTFocusAdapter glWindow1FA = new NEWTFocusAdapter("GLWindow1");
+ // glWindow.addWindowListener(glWindow1FA);
+ NEWTKeyAdapter glWindow1KA = new NEWTKeyAdapter("GLWindow1");
+ glWindow1KA.setVerbose(false);
+ glWindow.addKeyListener(glWindow1KA);
+
+ Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glWindow, true));
+
+ // Continuous animation ..
+ Animator animator = new Animator(glWindow);
+ animator.start();
+
+ Thread.sleep(durationPerTest); // manual testing
+
+ AWTRobotUtil.assertRequestFocusAndWait(null, glWindow, glWindow, null, null); // programmatic
+ AWTRobotUtil.requestFocus(robot, glWindow, false); // within unit framework, prev. tests (TestFocus02SwingAWTRobot) 'confuses' Windows keyboard input
+ glWindow1KA.reset();
+
+ testKeyCodes(robot, glWindow1KA);
+
+ // Remove listeners to avoid logging during dispose/destroy.
+ glWindow.removeKeyListener(glWindow1KA);
+
+ // Shutdown the test.
+ animator.stop();
}
static int atoi(String a) {
@@ -210,7 +238,7 @@ public class TestFocus01SwingAWTRobot extends UITestCase {
System.err.println(stdin.readLine());
*/
System.out.println("durationPerTest: "+durationPerTest);
- String tstname = TestFocus01SwingAWTRobot.class.getName();
+ String tstname = TestNewtKeyCodesAWT.class.getName();
org.junit.runner.JUnitCore.main(tstname);
}
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyEventAutoRepeatAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyEventAutoRepeatAWT.java
new file mode 100644
index 0000000..7b6fe05
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyEventAutoRepeatAWT.java
@@ -0,0 +1,320 @@
+/**
+ * Copyright 2012 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community OR
+ * CONTRIBUTORS 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.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.opengl.test.junit.newt;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.AfterClass;
+import org.junit.Assume;
+import org.junit.Before;
+
+import java.awt.AWTException;
+import java.awt.BorderLayout;
+import java.awt.Robot;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Arrays;
+import java.util.EventObject;
+import java.util.List;
+
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLEventListener;
+import javax.swing.JFrame;
+
+import java.io.IOException;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.jogamp.newt.awt.NewtCanvasAWT;
+import com.jogamp.newt.event.InputEvent;
+import com.jogamp.newt.event.KeyEvent;
+import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.util.Animator;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.RedSquareES2;
+
+import com.jogamp.opengl.test.junit.util.*;
+
+/**
+ * Testing key event order incl. auto-repeat (Bug 601)
+ *
+ * <p>
+ * Note Event order:
+ * <ol>
+ * <li>{@link #EVENT_KEY_PRESSED}</li>
+ * <li>{@link #EVENT_KEY_RELEASED}</li>
+ * <li>{@link #EVENT_KEY_TYPED}</li>
+ * </ol>
+ * </p>
+ * <p>
+ * Auto-Repeat shall behave as follow:
+ * <pre>
+ D = pressed, U = released, T = typed
+ 0 = normal, 1 = auto-repeat
+
+ D(0), [ U(1), T(1), D(1), U(1) T(1) ..], U(0) T(0)
+ * </pre>
+ *
+ * The idea is if you mask out auto-repeat in your event listener
+ * you just get one long pressed key D/U/T triple.
+ */
+public class TestNewtKeyEventAutoRepeatAWT extends UITestCase {
+ static int width, height;
+ static long durationPerTest = 100;
+ static long awtWaitTimeout = 1000;
+
+ static GLCapabilities glCaps;
+
+ @BeforeClass
+ public static void initClass() {
+ width = 640;
+ height = 480;
+ glCaps = new GLCapabilities(null);
+ }
+
+ @AfterClass
+ public static void release() {
+ }
+
+ @Before
+ public void initTest() {
+ }
+
+ @After
+ public void releaseTest() {
+ }
+
+ @Test
+ public void test01NEWT() throws AWTException, InterruptedException, InvocationTargetException {
+ GLWindow glWindow = GLWindow.create(glCaps);
+ glWindow.setSize(width, height);
+ glWindow.setVisible(true);
+
+ testImpl(glWindow);
+
+ glWindow.destroy();
+ }
+
+ @Test
+ public void test02NewtCanvasAWT() throws AWTException, InterruptedException, InvocationTargetException {
+ GLWindow glWindow = GLWindow.create(glCaps);
+
+ // Wrap the window in a canvas.
+ final NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow);
+
+ // Add the canvas to a frame, and make it all visible.
+ final JFrame frame1 = new JFrame("Swing AWT Parent Frame: "+ glWindow.getTitle());
+ frame1.getContentPane().add(newtCanvasAWT, BorderLayout.CENTER);
+ frame1.setSize(width, height);
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ frame1.setVisible(true);
+ } } );
+
+ Assert.assertEquals(true, AWTRobotUtil.waitForVisible(frame1, true));
+
+ testImpl(glWindow);
+
+ try {
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ frame1.setVisible(false);
+ frame1.dispose();
+ }});
+ } catch( Throwable throwable ) {
+ throwable.printStackTrace();
+ Assume.assumeNoException( throwable );
+ }
+ glWindow.destroy();
+ }
+
+ static void testKeyEventAutoRepeat(Robot robot, NEWTKeyAdapter keyAdapter, int loops, int pressDurationMS) {
+ System.err.println("KEY Event Auto-Repeat Test: "+loops);
+ EventObject[][] first = new EventObject[loops][3];
+ EventObject[][] last = new EventObject[loops][3];
+
+ keyAdapter.reset();
+ int firstIdx = 0;
+ for(int i=0; i<loops; i++) {
+ System.err.println("+++ KEY Event Auto-Repeat START Input Loop: "+i);
+ AWTRobotUtil.keyPress(0, robot, true, java.awt.event.KeyEvent.VK_A, pressDurationMS);
+ robot.waitForIdle();
+ AWTRobotUtil.keyPress(0, robot, false, java.awt.event.KeyEvent.VK_A, 500); // 1s .. no AR anymore
+ robot.waitForIdle();
+ final int minCodeCount = firstIdx + 3;
+ final int desiredCodeCount = firstIdx + 6;
+ for(int j=0; j < 10 && keyAdapter.getQueueSize() < desiredCodeCount; j++) { // wait until events are collected
+ robot.delay(100);
+ }
+ Assert.assertTrue("AR Test didn't collect enough key events: required min "+minCodeCount+", received "+(keyAdapter.getQueueSize()-firstIdx)+", "+keyAdapter.getQueued(),
+ keyAdapter.getQueueSize() >= minCodeCount );
+ final List<EventObject> keyEvents = keyAdapter.getQueued();
+ first[i][0] = (KeyEvent) keyEvents.get(firstIdx+0);
+ first[i][1] = (KeyEvent) keyEvents.get(firstIdx+1);
+ first[i][2] = (KeyEvent) keyEvents.get(firstIdx+2);
+ firstIdx = keyEvents.size() - 3;
+ last[i][0] = (KeyEvent) keyEvents.get(firstIdx+0);
+ last[i][1] = (KeyEvent) keyEvents.get(firstIdx+1);
+ last[i][2] = (KeyEvent) keyEvents.get(firstIdx+2);
+ System.err.println("+++ KEY Event Auto-Repeat END Input Loop: "+i);
+
+ // add a pair of normal press/release in between auto-repeat!
+ firstIdx = keyEvents.size();
+ AWTRobotUtil.keyPress(0, robot, true, java.awt.event.KeyEvent.VK_B, 10);
+ robot.waitForIdle();
+ AWTRobotUtil.keyPress(0, robot, false, java.awt.event.KeyEvent.VK_B, 250);
+ robot.waitForIdle();
+ for(int j=0; j < 10 && keyAdapter.getQueueSize() < firstIdx+3; j++) { // wait until events are collected
+ robot.delay(100);
+ }
+ firstIdx = keyEvents.size();
+ }
+ // dumpKeyEvents(keyEvents);
+ final List<EventObject> keyEvents = keyAdapter.getQueued();
+ NEWTKeyUtil.validateKeyEventOrder(keyEvents);
+
+ final boolean hasAR = 0 < keyAdapter.getKeyPressedCount(true) ;
+
+ {
+ final int expTotal = keyEvents.size();
+ final int expAR = hasAR ? expTotal - 3 * 2 * loops : 0; // per loop: 3 for non AR events and 3 for non AR 'B'
+ NEWTKeyUtil.validateKeyAdapterStats(keyAdapter, expTotal, expAR);
+ }
+
+ if( !hasAR ) {
+ System.err.println("No AUTO-REPEAT triggered by AWT Robot .. aborting test analysis");
+ return;
+ }
+
+ for(int i=0; i<loops; i++) {
+ System.err.println("Auto-Repeat Loop "+i+" - Head:");
+ NEWTKeyUtil.dumpKeyEvents(Arrays.asList(first[i]));
+ System.err.println("Auto-Repeat Loop "+i+" - Tail:");
+ NEWTKeyUtil.dumpKeyEvents(Arrays.asList(last[i]));
+ }
+ for(int i=0; i<loops; i++) {
+ KeyEvent e = (KeyEvent) first[i][0];
+ Assert.assertTrue("1st Shall be A, but is "+e, KeyEvent.VK_A == e.getKeyCode() );
+ Assert.assertTrue("1st Shall be PRESSED, but is "+e, KeyEvent.EVENT_KEY_PRESSED == e.getEventType() );
+ Assert.assertTrue("1st Shall not be AR, but is "+e, 0 == ( InputEvent.AUTOREPEAT_MASK & e.getModifiers() ) );
+
+ e = (KeyEvent) first[i][1];
+ Assert.assertTrue("2nd Shall be A, but is "+e, KeyEvent.VK_A == e.getKeyCode() );
+ Assert.assertTrue("2nd Shall be RELEASED, but is "+e, KeyEvent.EVENT_KEY_RELEASED == e.getEventType() );
+ Assert.assertTrue("2nd Shall be AR, but is "+e, 0 != ( InputEvent.AUTOREPEAT_MASK & e.getModifiers() ) );
+
+ e = (KeyEvent) first[i][2];
+ Assert.assertTrue("3rd Shall be A, but is "+e, KeyEvent.VK_A == e.getKeyCode() );
+ Assert.assertTrue("3rd Shall be TYPED, but is "+e, KeyEvent.EVENT_KEY_TYPED == e.getEventType() );
+ Assert.assertTrue("3rd Shall be AR, but is "+e, 0 != ( InputEvent.AUTOREPEAT_MASK & e.getModifiers() ) );
+
+ e = (KeyEvent) last[i][0];
+ Assert.assertTrue("last-2 Shall be A, but is "+e, KeyEvent.VK_A == e.getKeyCode() );
+ Assert.assertTrue("last-2 Shall be PRESSED, but is "+e, KeyEvent.EVENT_KEY_PRESSED == e.getEventType() );
+ Assert.assertTrue("last-2 Shall be AR, but is "+e, 0 != ( InputEvent.AUTOREPEAT_MASK & e.getModifiers() ) );
+
+ e = (KeyEvent) last[i][1];
+ Assert.assertTrue("last-1 Shall be A, but is "+e, KeyEvent.VK_A == e.getKeyCode() );
+ Assert.assertTrue("last-1 Shall be RELEASED, but is "+e, KeyEvent.EVENT_KEY_RELEASED == e.getEventType() );
+ Assert.assertTrue("last-1 Shall not be AR, but is "+e, 0 == ( InputEvent.AUTOREPEAT_MASK & e.getModifiers() ) );
+
+ e = (KeyEvent) last[i][2];
+ Assert.assertTrue("last-0 Shall be A, but is "+e, KeyEvent.VK_A == e.getKeyCode() );
+ Assert.assertTrue("last-0 Shall be TYPED, but is "+e, KeyEvent.EVENT_KEY_TYPED == e.getEventType() );
+ Assert.assertTrue("last-0 Shall not be AR, but is "+e, 0 == ( InputEvent.AUTOREPEAT_MASK & e.getModifiers() ) );
+ }
+ }
+
+ void testImpl(GLWindow glWindow) throws AWTException, InterruptedException, InvocationTargetException {
+ final Robot robot = new Robot();
+ robot.setAutoWaitForIdle(true);
+
+ GLEventListener demo1 = new RedSquareES2();
+ TestListenerCom01AWT.setDemoFields(demo1, glWindow, false);
+ glWindow.addGLEventListener(demo1);
+
+ NEWTKeyAdapter glWindow1KA = new NEWTKeyAdapter("GLWindow1");
+ glWindow1KA.setVerbose(false);
+ glWindow.addKeyListener(glWindow1KA);
+
+ Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glWindow, true));
+
+ // Continuous animation ..
+ Animator animator = new Animator(glWindow);
+ animator.start();
+
+ Thread.sleep(durationPerTest); // manual testing
+
+ AWTRobotUtil.assertRequestFocusAndWait(null, glWindow, glWindow, null, null); // programmatic
+ AWTRobotUtil.requestFocus(robot, glWindow, false); // within unit framework, prev. tests (TestFocus02SwingAWTRobot) 'confuses' Windows keyboard input
+ glWindow1KA.reset();
+
+ //
+ // Test the key event order w/ auto-repeat
+ //
+ final int origAutoDelay = robot.getAutoDelay();
+ robot.setAutoDelay(10);
+ try {
+ testKeyEventAutoRepeat(robot, glWindow1KA, 3, 1000);
+ } finally {
+ robot.setAutoDelay(origAutoDelay);
+ }
+
+ // Remove listeners to avoid logging during dispose/destroy.
+ glWindow.removeKeyListener(glWindow1KA);
+
+ // Shutdown the test.
+ animator.stop();
+ }
+
+ static int atoi(String a) {
+ int i=0;
+ try {
+ i = 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]);
+ }
+ }
+ /**
+ BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
+ System.err.println("Press enter to continue");
+ System.err.println(stdin.readLine());
+ */
+ System.out.println("durationPerTest: "+durationPerTest);
+ String tstname = TestNewtKeyEventAutoRepeatAWT.class.getName();
+ org.junit.runner.JUnitCore.main(tstname);
+ }
+
+
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestFocus01SwingAWTRobot.java b/src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyEventOrderAWT.java
similarity index 52%
copy from src/test/com/jogamp/opengl/test/junit/newt/TestFocus01SwingAWTRobot.java
copy to src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyEventOrderAWT.java
index bb67e77..cf50161 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestFocus01SwingAWTRobot.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyEventOrderAWT.java
@@ -1,5 +1,5 @@
/**
- * Copyright 2010 JogAmp Community. All rights reserved.
+ * Copyright 2012 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
@@ -28,13 +28,14 @@
package com.jogamp.opengl.test.junit.newt;
+import org.junit.After;
import org.junit.Assert;
import org.junit.AfterClass;
import org.junit.Assume;
+import org.junit.Before;
import java.awt.AWTException;
import java.awt.BorderLayout;
-import java.awt.Button;
import java.awt.Robot;
import java.lang.reflect.InvocationTargetException;
@@ -42,7 +43,6 @@ import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.swing.JFrame;
-import java.util.ArrayList;
import java.io.IOException;
import org.junit.BeforeClass;
@@ -55,9 +55,21 @@ import com.jogamp.opengl.test.junit.jogl.demos.es2.RedSquareES2;
import com.jogamp.opengl.test.junit.util.*;
-public class TestFocus01SwingAWTRobot extends UITestCase {
+/**
+ * Testing key event order excl. auto-repeat (Bug 601)
+ *
+ * <p>
+ * Note Event order:
+ * <ol>
+ * <li>{@link #EVENT_KEY_PRESSED}</li>
+ * <li>{@link #EVENT_KEY_RELEASED}</li>
+ * <li>{@link #EVENT_KEY_TYPED}</li>
+ * </ol>
+ * </p>
+ */
+public class TestNewtKeyEventOrderAWT extends UITestCase {
static int width, height;
- static long durationPerTest = 10;
+ static long durationPerTest = 100;
static long awtWaitTimeout = 1000;
static GLCapabilities glCaps;
@@ -72,111 +84,46 @@ public class TestFocus01SwingAWTRobot extends UITestCase {
@AfterClass
public static void release() {
}
-
- @Test
- public void testFocus01ProgrFocus() throws AWTException, InterruptedException, InvocationTargetException {
- testFocus01ProgrFocusImpl(null);
+
+ @Before
+ public void initTest() {
}
+ @After
+ public void releaseTest() {
+ }
+
@Test
- public void testFocus02RobotFocus() throws AWTException, InterruptedException, InvocationTargetException {
- Robot robot = new Robot();
- robot.setAutoWaitForIdle(true);
- testFocus01ProgrFocusImpl(robot);
+ public void test01NEWT() throws AWTException, InterruptedException, InvocationTargetException {
+ GLWindow glWindow = GLWindow.create(glCaps);
+ glWindow.setSize(width, height);
+ glWindow.setVisible(true);
+
+ testImpl(glWindow);
+
+ glWindow.destroy();
}
-
- private void testFocus01ProgrFocusImpl(Robot robot) throws AWTException,
- InvocationTargetException, InterruptedException {
- ArrayList<EventCountAdapter> eventCountAdapters = new ArrayList<EventCountAdapter>();
-
- // Create a window.
- GLWindow glWindow1 = GLWindow.create(glCaps);
- glWindow1.setTitle("testNewtChildFocus");
- GLEventListener demo1 = new RedSquareES2();
- TestListenerCom01AWT.setDemoFields(demo1, glWindow1, false);
- glWindow1.addGLEventListener(demo1);
- NEWTFocusAdapter glWindow1FA = new NEWTFocusAdapter("GLWindow1");
- glWindow1.addWindowListener(glWindow1FA);
-
- // Monitor NEWT focus and keyboard events.
- NEWTKeyAdapter glWindow1KA = new NEWTKeyAdapter("GLWindow1");
- eventCountAdapters.add(glWindow1KA);
- glWindow1.addKeyListener(glWindow1KA);
-
+
+ @Test
+ public void test02NewtCanvasAWT() throws AWTException, InterruptedException, InvocationTargetException {
+ GLWindow glWindow = GLWindow.create(glCaps);
+
// Wrap the window in a canvas.
- final NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow1);
-
- // Monitor AWT focus and keyboard events.
- AWTKeyAdapter newtCanvasAWTKA = new AWTKeyAdapter("NewtCanvasAWT");
- newtCanvasAWT.addKeyListener(newtCanvasAWTKA);
- eventCountAdapters.add(newtCanvasAWTKA);
- AWTFocusAdapter newtCanvasAWTFA = new AWTFocusAdapter("NewtCanvasAWT");
- newtCanvasAWT.addFocusListener(newtCanvasAWTFA);
-
+ final NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow);
+
// Add the canvas to a frame, and make it all visible.
- final JFrame frame1 = new JFrame("Swing AWT Parent Frame: "
- + glWindow1.getTitle());
- AWTFocusAdapter frame1FA = new AWTFocusAdapter("frame1");
- frame1.addFocusListener(frame1FA);
+ final JFrame frame1 = new JFrame("Swing AWT Parent Frame: "+ glWindow.getTitle());
frame1.getContentPane().add(newtCanvasAWT, BorderLayout.CENTER);
- final Button button = new Button("Click me ..");
- AWTFocusAdapter buttonFA = new AWTFocusAdapter("Button");
- button.addFocusListener(buttonFA);
- AWTKeyAdapter buttonKA = new AWTKeyAdapter("Button");
- button.addKeyListener(buttonKA);
- eventCountAdapters.add(buttonKA);
- frame1.getContentPane().add(button, BorderLayout.NORTH);
frame1.setSize(width, height);
javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
frame1.setVisible(true);
} } );
+
Assert.assertEquals(true, AWTRobotUtil.waitForVisible(frame1, true));
- Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glWindow1, true));
- AWTRobotUtil.clearAWTFocus(robot);
- Assert.assertTrue(AWTRobotUtil.toFrontAndRequestFocus(robot, frame1));
-
- Thread.sleep(durationPerTest); // manual testing
- int wait=0;
- while(wait<awtWaitTimeout/100 && glWindow1.getTotalFPSFrames()<1) { Thread.sleep(awtWaitTimeout/10); wait++; }
- System.err.println("Frames for initial setVisible(true): "+glWindow1.getTotalFPSFrames());
- Assert.assertTrue(glWindow1.isVisible());
- Assert.assertTrue(0 < glWindow1.getTotalFPSFrames());
-
- // Continuous animation ..
- Animator animator = new Animator(glWindow1);
- animator.start();
-
- // Button Focus
- Thread.sleep(100); // allow event sync
+ testImpl(glWindow);
- System.err.println("FOCUS AWT Button request");
- EventCountAdapterUtil.reset(eventCountAdapters);
- AWTRobotUtil.assertRequestFocusAndWait(robot, button, button, buttonFA, frame1FA);
- Assert.assertEquals(false, glWindow1FA.focusGained());
- Assert.assertEquals(false, newtCanvasAWTFA.focusGained());
- System.err.println("FOCUS AWT Button sync");
- AWTRobotUtil.assertKeyType(robot, java.awt.event.KeyEvent.VK_A, 2, button, buttonKA);
-
- // Request the AWT focus, which should automatically provide the NEWT window with focus.
- Thread.sleep(100); // allow event sync
- System.err.println("FOCUS NEWT Canvas/GLWindow request");
- EventCountAdapterUtil.reset(eventCountAdapters);
- AWTRobotUtil.assertRequestFocusAndWait(robot, newtCanvasAWT, newtCanvasAWT.getNEWTChild(), glWindow1FA, buttonFA);
- Assert.assertEquals(false, newtCanvasAWTFA.focusGained());
- System.err.println("FOCUS NEWT Canvas/GLWindow sync");
- AWTRobotUtil.assertKeyType(robot, java.awt.event.KeyEvent.VK_A, 2, glWindow1, glWindow1KA);
- Assert.assertEquals("AWT parent canvas received keyboard events", 0, newtCanvasAWTKA.getCount());
-
- // Remove listeners to avoid logging during dispose/destroy.
- glWindow1.removeKeyListener(glWindow1KA);
- glWindow1.removeWindowListener(glWindow1FA);
- newtCanvasAWT.removeKeyListener(newtCanvasAWTKA);
- newtCanvasAWT.removeFocusListener(newtCanvasAWTFA);
-
- // Shutdown the test.
- animator.stop();
try {
javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
@@ -187,7 +134,76 @@ public class TestFocus01SwingAWTRobot extends UITestCase {
throwable.printStackTrace();
Assume.assumeNoException( throwable );
}
- glWindow1.destroy();
+ glWindow.destroy();
+ }
+
+ static void testKeyEventOrder(Robot robot, NEWTKeyAdapter keyAdapter, int loops) {
+ System.err.println("KEY Event Order Test: "+loops);
+ keyAdapter.reset();
+ for(int i=0; i<loops; i++) {
+ // 1
+ AWTRobotUtil.keyPress(0, robot, true, java.awt.event.KeyEvent.VK_A, 10);
+ AWTRobotUtil.keyPress(0, robot, false, java.awt.event.KeyEvent.VK_A, 100);
+ robot.waitForIdle();
+ // 2
+ AWTRobotUtil.keyPress(0, robot, true, java.awt.event.KeyEvent.VK_B, 10);
+ AWTRobotUtil.keyPress(0, robot, false, java.awt.event.KeyEvent.VK_B, 100);
+ robot.waitForIdle();
+ // 3 + 4
+ AWTRobotUtil.keyPress(0, robot, true, java.awt.event.KeyEvent.VK_A, 10);
+ AWTRobotUtil.keyPress(0, robot, true, java.awt.event.KeyEvent.VK_B, 10);
+ AWTRobotUtil.keyPress(0, robot, false, java.awt.event.KeyEvent.VK_A, 10);
+ AWTRobotUtil.keyPress(0, robot, false, java.awt.event.KeyEvent.VK_B, 10);
+ robot.waitForIdle();
+ // 5 + 6
+ AWTRobotUtil.keyPress(0, robot, true, java.awt.event.KeyEvent.VK_A, 10);
+ AWTRobotUtil.keyPress(0, robot, true, java.awt.event.KeyEvent.VK_B, 10);
+ AWTRobotUtil.keyPress(0, robot, false, java.awt.event.KeyEvent.VK_B, 10);
+ AWTRobotUtil.keyPress(0, robot, false, java.awt.event.KeyEvent.VK_A, 10);
+ robot.waitForIdle();
+ }
+ robot.delay(250);
+ // dumpKeyEvents(keyAdapter.getQueued());
+
+ NEWTKeyUtil.validateKeyEventOrder(keyAdapter.getQueued());
+
+ NEWTKeyUtil.validateKeyAdapterStats(keyAdapter, 6*3*loops, 0);
+ }
+
+ void testImpl(GLWindow glWindow) throws AWTException, InterruptedException, InvocationTargetException {
+ final Robot robot = new Robot();
+ robot.setAutoWaitForIdle(true);
+
+ GLEventListener demo1 = new RedSquareES2();
+ TestListenerCom01AWT.setDemoFields(demo1, glWindow, false);
+ glWindow.addGLEventListener(demo1);
+
+ NEWTKeyAdapter glWindow1KA = new NEWTKeyAdapter("GLWindow1");
+ glWindow1KA.setVerbose(false);
+ glWindow.addKeyListener(glWindow1KA);
+
+ Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glWindow, true));
+
+ // Continuous animation ..
+ Animator animator = new Animator(glWindow);
+ animator.start();
+
+ Thread.sleep(durationPerTest); // manual testing
+
+ AWTRobotUtil.assertRequestFocusAndWait(null, glWindow, glWindow, null, null); // programmatic
+ AWTRobotUtil.requestFocus(robot, glWindow, false); // within unit framework, prev. tests (TestFocus02SwingAWTRobot) 'confuses' Windows keyboard input
+ glWindow1KA.reset();
+
+ //
+ // Test the key event order w/o auto-repeat
+ //
+ testKeyEventOrder(robot, glWindow1KA, 6);
+
+ // Remove listeners to avoid logging during dispose/destroy.
+ glWindow.removeKeyListener(glWindow1KA);
+
+ // Shutdown the test.
+ animator.stop();
}
static int atoi(String a) {
@@ -210,7 +226,7 @@ public class TestFocus01SwingAWTRobot extends UITestCase {
System.err.println(stdin.readLine());
*/
System.out.println("durationPerTest: "+durationPerTest);
- String tstname = TestFocus01SwingAWTRobot.class.getName();
+ String tstname = TestNewtKeyEventOrderAWT.class.getName();
org.junit.runner.JUnitCore.main(tstname);
}
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestFocus01SwingAWTRobot.java b/src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyPressReleaseUnmaskRepeatAWT.java
similarity index 51%
copy from src/test/com/jogamp/opengl/test/junit/newt/TestFocus01SwingAWTRobot.java
copy to src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyPressReleaseUnmaskRepeatAWT.java
index bb67e77..c275139 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestFocus01SwingAWTRobot.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyPressReleaseUnmaskRepeatAWT.java
@@ -1,5 +1,5 @@
/**
- * Copyright 2010 JogAmp Community. All rights reserved.
+ * Copyright 2012 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
@@ -28,13 +28,14 @@
package com.jogamp.opengl.test.junit.newt;
+import org.junit.After;
import org.junit.Assert;
import org.junit.AfterClass;
import org.junit.Assume;
+import org.junit.Before;
import java.awt.AWTException;
import java.awt.BorderLayout;
-import java.awt.Button;
import java.awt.Robot;
import java.lang.reflect.InvocationTargetException;
@@ -42,22 +43,27 @@ import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.swing.JFrame;
-import java.util.ArrayList;
import java.io.IOException;
import org.junit.BeforeClass;
import org.junit.Test;
import com.jogamp.newt.awt.NewtCanvasAWT;
+import com.jogamp.newt.event.InputEvent;
+import com.jogamp.newt.event.KeyEvent;
+import com.jogamp.newt.event.KeyListener;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.util.Animator;
import com.jogamp.opengl.test.junit.jogl.demos.es2.RedSquareES2;
import com.jogamp.opengl.test.junit.util.*;
-public class TestFocus01SwingAWTRobot extends UITestCase {
+/**
+ * Testing key press and release events w/o AUTO-REPEAT
+ */
+public class TestNewtKeyPressReleaseUnmaskRepeatAWT extends UITestCase {
static int width, height;
- static long durationPerTest = 10;
+ static long durationPerTest = 100;
static long awtWaitTimeout = 1000;
static GLCapabilities glCaps;
@@ -72,111 +78,46 @@ public class TestFocus01SwingAWTRobot extends UITestCase {
@AfterClass
public static void release() {
}
-
- @Test
- public void testFocus01ProgrFocus() throws AWTException, InterruptedException, InvocationTargetException {
- testFocus01ProgrFocusImpl(null);
+
+ @Before
+ public void initTest() {
}
+ @After
+ public void releaseTest() {
+ }
+
@Test
- public void testFocus02RobotFocus() throws AWTException, InterruptedException, InvocationTargetException {
- Robot robot = new Robot();
- robot.setAutoWaitForIdle(true);
- testFocus01ProgrFocusImpl(robot);
+ public void test01NEWT() throws AWTException, InterruptedException, InvocationTargetException {
+ GLWindow glWindow = GLWindow.create(glCaps);
+ glWindow.setSize(width, height);
+ glWindow.setVisible(true);
+
+ testImpl(glWindow);
+
+ glWindow.destroy();
}
-
- private void testFocus01ProgrFocusImpl(Robot robot) throws AWTException,
- InvocationTargetException, InterruptedException {
- ArrayList<EventCountAdapter> eventCountAdapters = new ArrayList<EventCountAdapter>();
-
- // Create a window.
- GLWindow glWindow1 = GLWindow.create(glCaps);
- glWindow1.setTitle("testNewtChildFocus");
- GLEventListener demo1 = new RedSquareES2();
- TestListenerCom01AWT.setDemoFields(demo1, glWindow1, false);
- glWindow1.addGLEventListener(demo1);
- NEWTFocusAdapter glWindow1FA = new NEWTFocusAdapter("GLWindow1");
- glWindow1.addWindowListener(glWindow1FA);
-
- // Monitor NEWT focus and keyboard events.
- NEWTKeyAdapter glWindow1KA = new NEWTKeyAdapter("GLWindow1");
- eventCountAdapters.add(glWindow1KA);
- glWindow1.addKeyListener(glWindow1KA);
-
+
+ @Test
+ public void test02NewtCanvasAWT() throws AWTException, InterruptedException, InvocationTargetException {
+ GLWindow glWindow = GLWindow.create(glCaps);
+
// Wrap the window in a canvas.
- final NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow1);
-
- // Monitor AWT focus and keyboard events.
- AWTKeyAdapter newtCanvasAWTKA = new AWTKeyAdapter("NewtCanvasAWT");
- newtCanvasAWT.addKeyListener(newtCanvasAWTKA);
- eventCountAdapters.add(newtCanvasAWTKA);
- AWTFocusAdapter newtCanvasAWTFA = new AWTFocusAdapter("NewtCanvasAWT");
- newtCanvasAWT.addFocusListener(newtCanvasAWTFA);
-
+ final NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow);
+
// Add the canvas to a frame, and make it all visible.
- final JFrame frame1 = new JFrame("Swing AWT Parent Frame: "
- + glWindow1.getTitle());
- AWTFocusAdapter frame1FA = new AWTFocusAdapter("frame1");
- frame1.addFocusListener(frame1FA);
+ final JFrame frame1 = new JFrame("Swing AWT Parent Frame: "+ glWindow.getTitle());
frame1.getContentPane().add(newtCanvasAWT, BorderLayout.CENTER);
- final Button button = new Button("Click me ..");
- AWTFocusAdapter buttonFA = new AWTFocusAdapter("Button");
- button.addFocusListener(buttonFA);
- AWTKeyAdapter buttonKA = new AWTKeyAdapter("Button");
- button.addKeyListener(buttonKA);
- eventCountAdapters.add(buttonKA);
- frame1.getContentPane().add(button, BorderLayout.NORTH);
frame1.setSize(width, height);
javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
frame1.setVisible(true);
} } );
+
Assert.assertEquals(true, AWTRobotUtil.waitForVisible(frame1, true));
- Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glWindow1, true));
- AWTRobotUtil.clearAWTFocus(robot);
- Assert.assertTrue(AWTRobotUtil.toFrontAndRequestFocus(robot, frame1));
-
- Thread.sleep(durationPerTest); // manual testing
- int wait=0;
- while(wait<awtWaitTimeout/100 && glWindow1.getTotalFPSFrames()<1) { Thread.sleep(awtWaitTimeout/10); wait++; }
- System.err.println("Frames for initial setVisible(true): "+glWindow1.getTotalFPSFrames());
- Assert.assertTrue(glWindow1.isVisible());
- Assert.assertTrue(0 < glWindow1.getTotalFPSFrames());
-
- // Continuous animation ..
- Animator animator = new Animator(glWindow1);
- animator.start();
-
- // Button Focus
- Thread.sleep(100); // allow event sync
+ testImpl(glWindow);
- System.err.println("FOCUS AWT Button request");
- EventCountAdapterUtil.reset(eventCountAdapters);
- AWTRobotUtil.assertRequestFocusAndWait(robot, button, button, buttonFA, frame1FA);
- Assert.assertEquals(false, glWindow1FA.focusGained());
- Assert.assertEquals(false, newtCanvasAWTFA.focusGained());
- System.err.println("FOCUS AWT Button sync");
- AWTRobotUtil.assertKeyType(robot, java.awt.event.KeyEvent.VK_A, 2, button, buttonKA);
-
- // Request the AWT focus, which should automatically provide the NEWT window with focus.
- Thread.sleep(100); // allow event sync
- System.err.println("FOCUS NEWT Canvas/GLWindow request");
- EventCountAdapterUtil.reset(eventCountAdapters);
- AWTRobotUtil.assertRequestFocusAndWait(robot, newtCanvasAWT, newtCanvasAWT.getNEWTChild(), glWindow1FA, buttonFA);
- Assert.assertEquals(false, newtCanvasAWTFA.focusGained());
- System.err.println("FOCUS NEWT Canvas/GLWindow sync");
- AWTRobotUtil.assertKeyType(robot, java.awt.event.KeyEvent.VK_A, 2, glWindow1, glWindow1KA);
- Assert.assertEquals("AWT parent canvas received keyboard events", 0, newtCanvasAWTKA.getCount());
-
- // Remove listeners to avoid logging during dispose/destroy.
- glWindow1.removeKeyListener(glWindow1KA);
- glWindow1.removeWindowListener(glWindow1FA);
- newtCanvasAWT.removeKeyListener(newtCanvasAWTKA);
- newtCanvasAWT.removeFocusListener(newtCanvasAWTFA);
-
- // Shutdown the test.
- animator.stop();
try {
javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
@@ -187,7 +128,36 @@ public class TestFocus01SwingAWTRobot extends UITestCase {
throwable.printStackTrace();
Assume.assumeNoException( throwable );
}
- glWindow1.destroy();
+ glWindow.destroy();
+ }
+
+ void testImpl(GLWindow glWindow) throws AWTException, InterruptedException, InvocationTargetException {
+ final Robot robot = new Robot();
+ robot.setAutoWaitForIdle(true);
+
+ GLEventListener demo1 = new RedSquareES2();
+ TestListenerCom01AWT.setDemoFields(demo1, glWindow, false);
+ glWindow.addGLEventListener(demo1);
+
+ SimpleKeyPressRelease simpleKeyPressRelease = new SimpleKeyPressRelease();
+ glWindow.addKeyListener(simpleKeyPressRelease);
+
+ Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glWindow, true));
+
+ // Continuous animation ..
+ Animator animator = new Animator(glWindow);
+ animator.start();
+
+ Thread.sleep(durationPerTest); // manual testing
+
+ AWTRobotUtil.assertRequestFocusAndWait(null, glWindow, glWindow, null, null); // programmatic
+ AWTRobotUtil.requestFocus(robot, glWindow, false); // within unit framework, prev. tests (TestFocus02SwingAWTRobot) 'confuses' Windows keyboard input
+
+ // Remove listeners to avoid logging during dispose/destroy.
+ glWindow.removeKeyListener(simpleKeyPressRelease);
+
+ // Shutdown the test.
+ animator.stop();
}
static int atoi(String a) {
@@ -197,6 +167,39 @@ public class TestFocus01SwingAWTRobot extends UITestCase {
} catch (Exception ex) { ex.printStackTrace(); }
return i;
}
+
+ static class SimpleKeyPressRelease implements KeyListener {
+ int seq;
+
+ SimpleKeyPressRelease() {
+ reset();
+ }
+
+ public void reset() {
+ seq=0;
+ }
+
+ @Override
+ public void keyPressed(KeyEvent e) {
+ if( 0 == ( InputEvent.AUTOREPEAT_MASK & e.getModifiers() ) ) {
+ seq++;
+ System.err.println(seq+": "+e);
+ }
+ }
+
+ @Override
+ public void keyReleased(KeyEvent e) {
+ if( 0 == ( InputEvent.AUTOREPEAT_MASK & e.getModifiers() ) ) {
+ seq++;
+ System.err.println(seq+": "+e);
+ }
+ }
+
+ @Override
+ public void keyTyped(KeyEvent e) {
+ }
+
+ }
public static void main(String args[]) throws IOException {
for(int i=0; i<args.length; i++) {
@@ -210,7 +213,7 @@ public class TestFocus01SwingAWTRobot extends UITestCase {
System.err.println(stdin.readLine());
*/
System.out.println("durationPerTest: "+durationPerTest);
- String tstname = TestFocus01SwingAWTRobot.class.getName();
+ String tstname = TestNewtKeyPressReleaseUnmaskRepeatAWT.class.getName();
org.junit.runner.JUnitCore.main(tstname);
}
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestRemoteGLWindows01NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestRemoteGLWindows01NEWT.java
index 35e2440..ef830b6 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestRemoteGLWindows01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestRemoteGLWindows01NEWT.java
@@ -30,7 +30,6 @@ package com.jogamp.opengl.test.junit.newt;
import org.junit.Assert;
import org.junit.Assume;
-import org.junit.BeforeClass;
import org.junit.Test;
import javax.media.opengl.*;
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestRemoteWindow01NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestRemoteWindow01NEWT.java
index eb65258..53995e8 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestRemoteWindow01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestRemoteWindow01NEWT.java
@@ -47,7 +47,7 @@ public class TestRemoteWindow01NEWT extends UITestCase {
@BeforeClass
public static void initClass() {
- NativeWindowFactory.initSingleton(true);
+ NativeWindowFactory.initSingleton();
width = 640;
height = 480;
}
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode00NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode00NEWT.java
index a5b7a76..577119b 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode00NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode00NEWT.java
@@ -59,7 +59,7 @@ public class TestScreenMode00NEWT extends UITestCase {
@BeforeClass
public static void initClass() {
- NativeWindowFactory.initSingleton(true);
+ NativeWindowFactory.initSingleton();
width = 640;
height = 480;
}
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode00bNEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode00bNEWT.java
index e9e66da..75a3126 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode00bNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode00bNEWT.java
@@ -57,7 +57,7 @@ public class TestScreenMode00bNEWT extends UITestCase {
@BeforeClass
public static void initClass() {
- NativeWindowFactory.initSingleton(true);
+ NativeWindowFactory.initSingleton();
width = 640;
height = 480;
}
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode01NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode01NEWT.java
index c3c68e4..f253f3b 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode01NEWT.java
@@ -34,7 +34,6 @@ import javax.media.opengl.GLProfile;
import com.jogamp.opengl.util.Animator;
-import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
@@ -48,6 +47,7 @@ import com.jogamp.newt.ScreenMode;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.newt.util.ScreenModeUtil;
import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
import com.jogamp.opengl.test.junit.util.UITestCase;
import java.util.List;
@@ -109,10 +109,12 @@ public class TestScreenMode01NEWT extends UITestCase {
* Remedy B) is shown in {@link TestScreenMode01bNEWT}
* </pre>
*/
- @After
- public void cleanupGL() throws InterruptedException {
- GLProfile.shutdown(GLProfile.ShutdownType.COMPLETE);
+ private void cleanupGL() throws InterruptedException {
+ System.err.println("*** cleanupGL.shutdown");
+ GLProfile.shutdown();
+ System.err.println("*** cleanupGL.initSingleton");
GLProfile.initSingleton();
+ System.err.println("*** cleanupGL.DONE");
}
static GLWindow createWindow(Screen screen, GLCapabilities caps, int width, int height, boolean onscreen, boolean undecorated) {
@@ -166,7 +168,15 @@ public class TestScreenMode01NEWT extends UITestCase {
Thread.sleep(waitTimeShort);
animator.stop();
- destroyWindow(window);
+ Assert.assertEquals(false, animator.isAnimating());
+ Assert.assertEquals(false, animator.isStarted());
+
+ destroyWindow(window);
+ Assert.assertTrue(AWTRobotUtil.waitForRealized(window, false));
+ Assert.assertEquals(false, window.isRealized());
+ Assert.assertEquals(false, window.isNativeValid());
+
+ cleanupGL();
}
@Test
@@ -230,11 +240,15 @@ public class TestScreenMode01NEWT extends UITestCase {
Assert.assertEquals(true,window.isNativeValid());
Assert.assertEquals(true,window.isVisible());
- animator.stop();
+ animator.stop();
+ Assert.assertEquals(false, animator.isAnimating());
+ Assert.assertEquals(false, animator.isStarted());
+
destroyWindow(window);
- Thread.sleep(waitTimeShort);
+ Assert.assertTrue(AWTRobotUtil.waitForRealized(window, false));
Assert.assertEquals(false,window.isVisible());
+ Assert.assertEquals(false,window.isRealized());
Assert.assertEquals(false,window.isNativeValid());
Assert.assertEquals(false,screen.isNativeValid());
Assert.assertEquals(false,display.isNativeValid());
@@ -246,14 +260,15 @@ public class TestScreenMode01NEWT extends UITestCase {
smCurrent = screen.getCurrentScreenMode();
System.err.println("[1] current/orig: "+smCurrent);
+ screen.destroy();
+ Assert.assertEquals(false,screen.isNativeValid());
+ Assert.assertEquals(false,display.isNativeValid());
Assert.assertNotNull(smCurrent);
Assert.assertEquals(smCurrent, smOrig);
- screen.destroy();
-
- Assert.assertEquals(false,screen.isNativeValid());
- Assert.assertEquals(false,display.isNativeValid());
+
+ cleanupGL();
}
@Test
@@ -326,10 +341,14 @@ public class TestScreenMode01NEWT extends UITestCase {
Assert.assertEquals(true,window.isVisible());
animator.stop();
+ Assert.assertEquals(false, animator.isAnimating());
+ Assert.assertEquals(false, animator.isStarted());
+
destroyWindow(window);
- Thread.sleep(waitTimeShort);
+ Assert.assertTrue(AWTRobotUtil.waitForRealized(window, false));
Assert.assertEquals(false,window.isVisible());
+ Assert.assertEquals(false,window.isRealized());
Assert.assertEquals(false,window.isNativeValid());
Assert.assertEquals(false,screen.isNativeValid());
Assert.assertEquals(false,display.isNativeValid());
@@ -341,11 +360,14 @@ public class TestScreenMode01NEWT extends UITestCase {
smCurrent = screen.getCurrentScreenMode();
System.err.println("[1] current/orig: "+smCurrent);
+ screen.destroy();
+ Assert.assertEquals(false,screen.isNativeValid());
+ Assert.assertEquals(false,display.isNativeValid());
Assert.assertNotNull(smCurrent);
Assert.assertEquals(smCurrent, smOrig);
-
- screen.destroy();
+
+ cleanupGL();
}
public static void main(String args[]) throws IOException {
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestWindows01NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestWindows01NEWT.java
index a99edfa..e03b5e7 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestWindows01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestWindows01NEWT.java
@@ -33,7 +33,6 @@ import org.junit.BeforeClass;
import org.junit.Test;
import javax.media.nativewindow.*;
-import javax.media.nativewindow.util.Point;
import com.jogamp.newt.*;
import java.io.IOException;
@@ -45,7 +44,7 @@ public class TestWindows01NEWT extends UITestCase {
@BeforeClass
public static void initClass() {
- NativeWindowFactory.initSingleton(true);
+ NativeWindowFactory.initSingleton();
width = 256;
height = 256;
}
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtAWTReparentingKeyAdapter.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtAWTReparentingKeyAdapter.java
index 473f2f5..15393e8 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtAWTReparentingKeyAdapter.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtAWTReparentingKeyAdapter.java
@@ -36,7 +36,7 @@ import com.jogamp.newt.event.KeyAdapter;
import com.jogamp.newt.event.KeyEvent;
import com.jogamp.newt.opengl.GLWindow;
-class NewtAWTReparentingKeyAdapter extends KeyAdapter {
+public class NewtAWTReparentingKeyAdapter extends KeyAdapter {
Frame frame;
NewtCanvasAWT newtCanvasAWT;
GLWindow glWindow;
@@ -48,7 +48,9 @@ class NewtAWTReparentingKeyAdapter extends KeyAdapter {
}
public void keyTyped(KeyEvent e) {
- if(e.getKeyChar()=='d') {
+ if(e.getKeyChar()=='i') {
+ System.err.println(glWindow);
+ } else if(e.getKeyChar()=='d') {
glWindow.setUndecorated(!glWindow.isUndecorated());
} else if(e.getKeyChar()=='f') {
glWindow.setFullscreen(!glWindow.isFullscreen());
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingFocusTraversal01AWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingFocusTraversal01AWT.java
index f39b5df..d6f1f81 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingFocusTraversal01AWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingFocusTraversal01AWT.java
@@ -68,12 +68,13 @@ public class TestParentingFocusTraversal01AWT extends UITestCase {
static long durationPerTest = numFocus * 200;
static GLCapabilities glCaps;
static boolean manual = false;
+ static boolean forceGL3 = false;
@BeforeClass
public static void initClass() {
glSize = new Dimension(200,200);
fSize = new Dimension(300,300);
- glCaps = new GLCapabilities(null);
+ glCaps = new GLCapabilities( forceGL3 ? GLProfile.get(GLProfile.GL3) : null );
}
@Test
@@ -314,6 +315,8 @@ public class TestParentingFocusTraversal01AWT extends UITestCase {
durationPerTest = atoi(args[++i]);
} else if(args[i].equals("-manual")) {
manual = true;
+ } else if(args[i].equals("-gl3")) {
+ forceGL3 = true;
}
}
String tstname = TestParentingFocusTraversal01AWT.class.getName();
diff --git a/src/test/com/jogamp/opengl/test/junit/util/AWTFocusAdapter.java b/src/test/com/jogamp/opengl/test/junit/util/AWTFocusAdapter.java
index fe0f2ac..32ff602 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/AWTFocusAdapter.java
+++ b/src/test/com/jogamp/opengl/test/junit/util/AWTFocusAdapter.java
@@ -36,12 +36,15 @@ public class AWTFocusAdapter implements FocusEventCountAdapter, FocusListener {
String prefix;
int focusCount;
boolean wasTemporary;
+ boolean verbose = true;
public AWTFocusAdapter(String prefix) {
this.prefix = prefix;
reset();
}
+ public void setVerbose(boolean v) { verbose = false; }
+
public boolean focusLost() {
return focusCount<0;
}
@@ -65,7 +68,9 @@ public class AWTFocusAdapter implements FocusEventCountAdapter, FocusListener {
if(focusCount<0) { focusCount=0; }
focusCount++;
wasTemporary = e.isTemporary();
- System.err.println("FOCUS AWT GAINED "+(wasTemporary?"TEMP":"PERM")+" [fc "+focusCount+"]: "+prefix+", "+e);
+ if( verbose ) {
+ System.err.println("FOCUS AWT GAINED "+(wasTemporary?"TEMP":"PERM")+" [fc "+focusCount+"]: "+prefix+", "+e);
+ }
}
/* @Override */
@@ -73,7 +78,9 @@ public class AWTFocusAdapter implements FocusEventCountAdapter, FocusListener {
if(focusCount>0) { focusCount=0; }
focusCount--;
wasTemporary = e.isTemporary();
- System.err.println("FOCUS AWT LOST "+(wasTemporary?"TEMP":"PERM")+" [fc "+focusCount+"]: "+prefix+", "+e);
+ if( verbose ) {
+ System.err.println("FOCUS AWT LOST "+(wasTemporary?"TEMP":"PERM")+" [fc "+focusCount+"]: "+prefix+", "+e);
+ }
}
public String toString() { return prefix+"[focusCount "+focusCount +", temp "+wasTemporary+"]"; }
diff --git a/src/test/com/jogamp/opengl/test/junit/util/AWTKeyAdapter.java b/src/test/com/jogamp/opengl/test/junit/util/AWTKeyAdapter.java
index 6c01561..837ba5d 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/AWTKeyAdapter.java
+++ b/src/test/com/jogamp/opengl/test/junit/util/AWTKeyAdapter.java
@@ -29,44 +29,85 @@
package com.jogamp.opengl.test.junit.util;
import java.awt.event.KeyEvent;
+import java.util.ArrayList;
+import java.util.EventObject;
+import java.util.List;
-public class AWTKeyAdapter extends java.awt.event.KeyAdapter implements InputEventCountAdapter {
+public class AWTKeyAdapter extends java.awt.event.KeyAdapter implements KeyEventCountAdapter {
String prefix;
- int keyTyped;
+ int keyPressed, keyReleased, keyTyped;
boolean pressed;
+ List<EventObject> queue = new ArrayList<EventObject>();
+ boolean verbose = true;
public AWTKeyAdapter(String prefix) {
this.prefix = prefix;
reset();
}
- public boolean isPressed() {
+ public synchronized void setVerbose(boolean v) { verbose = false; }
+
+ public synchronized boolean isPressed() {
return pressed;
}
- public int getCount() {
+ public synchronized int getCount() {
return keyTyped;
}
- public void reset() {
+ public synchronized int getKeyPressedCount(boolean autoRepeatOnly) {
+ return keyPressed;
+ }
+
+ public synchronized int getKeyReleasedCount(boolean autoRepeatOnly) {
+ return keyReleased;
+ }
+
+ public synchronized int getKeyTypedCount(boolean autoRepeatOnly) {
+ return keyTyped;
+ }
+
+ public synchronized List<EventObject> getQueued() {
+ return queue;
+ }
+
+ public synchronized int getQueueSize() {
+ return queue.size();
+ }
+
+ public synchronized void reset() {
keyTyped = 0;
+ keyPressed = 0;
+ keyReleased = 0;
pressed = false;
+ queue.clear();
}
- public void keyPressed(KeyEvent e) {
+ public synchronized void keyPressed(KeyEvent e) {
pressed = true;
- System.err.println("KEY AWT PRESSED ["+pressed+"]: "+prefix+", "+e);
+ keyPressed++;
+ queue.add(e);
+ if( verbose ) {
+ System.err.println("KEY AWT PRESSED ["+pressed+"]: "+prefix+", "+e);
+ }
}
- public void keyReleased(KeyEvent e) {
+ public synchronized void keyReleased(KeyEvent e) {
pressed = false;
- System.err.println("KEY AWT RELEASED ["+pressed+"]: "+prefix+", "+e);
+ keyReleased++;
+ queue.add(e);
+ if( verbose ) {
+ System.err.println("KEY AWT RELEASED ["+pressed+"]: "+prefix+", "+e);
+ }
}
- public void keyTyped(java.awt.event.KeyEvent e) {
- ++keyTyped;
- System.err.println("KEY AWT TYPED ["+keyTyped+"]: "+prefix+", "+e);
+ public synchronized void keyTyped(java.awt.event.KeyEvent e) {
+ keyTyped++;
+ queue.add(e);
+ if( verbose ) {
+ System.err.println("KEY AWT TYPED ["+keyTyped+"]: "+prefix+", "+e);
+ }
}
public String toString() { return prefix+"[pressed "+pressed+", typed "+keyTyped+"]"; }
diff --git a/src/test/com/jogamp/opengl/test/junit/util/AWTMouseAdapter.java b/src/test/com/jogamp/opengl/test/junit/util/AWTMouseAdapter.java
index b948023..31362bf 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/AWTMouseAdapter.java
+++ b/src/test/com/jogamp/opengl/test/junit/util/AWTMouseAdapter.java
@@ -29,43 +29,68 @@
package com.jogamp.opengl.test.junit.util;
import java.awt.event.MouseEvent;
+import java.util.ArrayList;
+import java.util.EventObject;
+import java.util.List;
public class AWTMouseAdapter extends java.awt.event.MouseAdapter implements InputEventCountAdapter {
String prefix;
int mouseClicked;
boolean pressed;
+ List<EventObject> queue = new ArrayList<EventObject>();
+ boolean verbose = true;
public AWTMouseAdapter(String prefix) {
this.prefix = prefix;
reset();
}
- public boolean isPressed() {
+ public synchronized void setVerbose(boolean v) { verbose = false; }
+
+ public synchronized boolean isPressed() {
return pressed;
}
- public int getCount() {
+ public synchronized int getCount() {
return mouseClicked;
}
- public void reset() {
+ public synchronized List<EventObject> getQueued() {
+ return queue;
+ }
+
+ public synchronized int getQueueSize() {
+ return queue.size();
+ }
+
+ public synchronized void reset() {
mouseClicked = 0;
pressed = false;
+ queue.clear();
}
- public void mousePressed(MouseEvent e) {
+ public synchronized void mousePressed(MouseEvent e) {
pressed = true;
- System.err.println("MOUSE AWT PRESSED ["+pressed+"]: "+prefix+", "+e);
+ queue.add(e);
+ if( verbose ) {
+ System.err.println("MOUSE AWT PRESSED ["+pressed+"]: "+prefix+", "+e);
+ }
}
- public void mouseReleased(MouseEvent e) {
+ public synchronized void mouseReleased(MouseEvent e) {
pressed = false;
- System.err.println("MOUSE AWT RELEASED ["+pressed+"]: "+prefix+", "+e);
+ queue.add(e);
+ if( verbose ) {
+ System.err.println("MOUSE AWT RELEASED ["+pressed+"]: "+prefix+", "+e);
+ }
}
- public void mouseClicked(java.awt.event.MouseEvent e) {
+ public synchronized void mouseClicked(java.awt.event.MouseEvent e) {
mouseClicked+=e.getClickCount();
- System.err.println("MOUSE AWT CLICKED ["+mouseClicked+"]: "+prefix+", "+e);
+ queue.add(e);
+ if( verbose ) {
+ System.err.println("MOUSE AWT CLICKED ["+mouseClicked+"]: "+prefix+", "+e);
+ }
}
public String toString() { return prefix+"[pressed "+pressed+", clicked "+mouseClicked+"]"; }
diff --git a/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java b/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java
index 35a2d96..e64b320 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java
+++ b/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java
@@ -29,6 +29,7 @@
package com.jogamp.opengl.test.junit.util;
import jogamp.newt.WindowImplAccess;
+
import java.lang.reflect.InvocationTargetException;
import java.awt.AWTException;
import java.awt.Component;
@@ -38,6 +39,7 @@ import java.awt.Robot;
import java.awt.Toolkit;
import javax.media.nativewindow.NativeWindow;
+import javax.media.opengl.GLDrawable;
import javax.media.opengl.awt.GLCanvas;
import org.junit.Assert;
@@ -194,10 +196,20 @@ public class AWTRobotUtil {
/**
* requestFocus, if robot is valid, use mouse operation,
- * otherwise programatic, ie call requestFocus
+ * otherwise programmatic, ie call requestFocus
*/
public static void requestFocus(Robot robot, Object obj)
throws AWTException, InterruptedException, InvocationTargetException {
+ requestFocus(robot, obj, true);
+ }
+
+ /**
+ * requestFocus, if robot is valid, use mouse operation,
+ * otherwise programmatic, ie call requestFocus
+ */
+ public static void requestFocus(Robot robot, Object obj, boolean onTitleBarIfWindow)
+ throws AWTException, InterruptedException, InvocationTargetException {
+
final Component comp;
final com.jogamp.newt.Window win;
@@ -211,7 +223,7 @@ public class AWTRobotUtil {
throw new RuntimeException("Neither AWT nor NEWT: "+obj);
}
- if(null == robot) {
+ if(null == robot) {
if(null!=comp) {
javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
@@ -224,7 +236,7 @@ public class AWTRobotUtil {
}
} else {
final int mouseButton = java.awt.event.InputEvent.BUTTON1_MASK;
- centerMouse(robot, obj, true);
+ centerMouse(robot, obj, onTitleBarIfWindow);
robot.waitForIdle();
robot.mousePress(mouseButton);
@@ -274,24 +286,29 @@ public class AWTRobotUtil {
*
* @return True if the Window became the global focused Window within TIME_OUT
*/
- public static boolean waitForFocus(Object obj, FocusEventCountAdapter gain,
- FocusEventCountAdapter lost) throws InterruptedException {
- if(!waitForFocus(obj)) {
- return false;
- }
- if(null == gain) {
- return true;
- }
-
+ public static boolean waitForFocus(FocusEventCountAdapter gain,
+ FocusEventCountAdapter lost) throws InterruptedException {
int wait;
for (wait=0; wait<POLL_DIVIDER; wait++) {
- if( ( null == lost || lost.focusLost() ) && gain.focusGained() ) {
+ if( ( null == lost || lost.focusLost() ) && ( null == gain || gain.focusGained() ) ) {
return true;
}
Thread.sleep(TIME_SLICE);
}
return false;
}
+
+ /**
+ *
+ * @return True if the Window became the global focused Window within TIME_OUT
+ */
+ public static boolean waitForFocus(Object obj, FocusEventCountAdapter gain,
+ FocusEventCountAdapter lost) throws InterruptedException {
+ if(!waitForFocus(obj)) {
+ return false;
+ }
+ return waitForFocus(gain, lost);
+ }
public static void assertRequestFocusAndWait(Robot robot, Object requestFocus, Object waitForFocus,
FocusEventCountAdapter gain, FocusEventCountAdapter lost)
@@ -306,7 +323,7 @@ public class AWTRobotUtil {
}
if(!hasFocus) {
System.err.print("*** AWTRobotUtil.assertRequestFocusAndWait() ");
- if(gain.focusGained() && !lost.focusLost()) {
+ if( ( null == gain || gain.focusGained() ) && ( null == lost || !lost.focusLost() ) ) {
// be error tolerant here, some impl. may lack focus-lost events (OS X)
System.err.println("minor UI failure");
hasFocus = true;
@@ -331,11 +348,12 @@ public class AWTRobotUtil {
}
public static int keyType(int i, Robot robot, int keyCode,
- Object obj, InputEventCountAdapter counter) throws InterruptedException, AWTException, InvocationTargetException
+ Object obj, KeyEventCountAdapter counter) throws InterruptedException, AWTException, InvocationTargetException
{
int tc = 0;
int j;
final long t0 = System.currentTimeMillis();
+ final int c0 = null!=counter ? counter.getCount() : 0;
for(j=0; 1 > tc && j<RETRY_NUMBER; j++) {
if(!hasFocus(obj)) {
@@ -343,11 +361,12 @@ public class AWTRobotUtil {
if(DEBUG) { System.err.println(i+":"+j+" KC1.0: "+counter+" - regain focus"); }
requestFocus(null, obj);
}
- final int c0 = null!=counter ? counter.getCount() : 0;
if(DEBUG) { System.err.println(i+":"+j+" KC1.1: "+counter); }
robot.waitForIdle();
robot.keyPress(keyCode);
+ robot.delay(10);
robot.keyRelease(keyCode);
+ robot.delay(100);
if(DEBUG) { System.err.println(i+":"+j+" KC1.2: "+counter); }
tc = ( null!=counter ? counter.getCount() : 1 ) - c0;
for (int wait=0; wait<POLL_DIVIDER && 1 > tc; wait++) {
@@ -359,13 +378,26 @@ public class AWTRobotUtil {
Assert.assertEquals("Key ("+i+":"+j+") not typed one time", 1, tc);
return (int) ( System.currentTimeMillis() - t0 ) ;
}
+
+ /** No validation is performed .. */
+ public static int keyPress(int i, Robot robot, boolean press, int keyCode, int msDelay) {
+ final long t0 = System.currentTimeMillis();
+ if(press) {
+ robot.keyPress(keyCode);
+ } else {
+ robot.keyRelease(keyCode);
+ }
+ robot.delay(msDelay);
+
+ return (int) ( System.currentTimeMillis() - t0 ) ;
+ }
/**
* @param keyCode TODO
* @param counter shall return the number of keys typed (press + release)
*/
public static void assertKeyType(Robot robot, int keyCode, int typeCount,
- Object obj, InputEventCountAdapter counter)
+ Object obj, KeyEventCountAdapter counter)
throws AWTException, InterruptedException, InvocationTargetException {
if(null == robot) {
@@ -392,6 +424,38 @@ public class AWTRobotUtil {
Assert.assertEquals("Wrong key count", typeCount, counter.getCount()-c0);
}
+ /**
+ * @param keyCode TODO
+ * @param counter shall return the number of keys typed (press + release)
+ */
+ public static void assertKeyPress(Robot robot, int keyCode, int typeCount,
+ Object obj, KeyEventCountAdapter counter)
+ throws AWTException, InterruptedException, InvocationTargetException {
+
+ if(null == robot) {
+ robot = new Robot();
+ robot.setAutoWaitForIdle(true);
+ }
+
+ centerMouse(robot, obj, false);
+
+ Assert.assertEquals("Key already pressed", false, counter.isPressed());
+
+ if(DEBUG) {
+ System.err.println("**************************************");
+ System.err.println("KC0: "+counter);
+ }
+
+ final int c0 = counter.getCount();
+
+ for(int i=0; i<typeCount; i++) {
+ keyType(i, robot, keyCode, obj, counter);
+ }
+
+ if(DEBUG) { System.err.println("KC3.0: "+counter); }
+ Assert.assertEquals("Wrong key count", typeCount, counter.getCount()-c0);
+ }
+
static int mouseClick(int i, Robot robot, int mouseButton,
Object obj, InputEventCountAdapter counter) throws InterruptedException, AWTException, InvocationTargetException
{
@@ -460,20 +524,6 @@ public class AWTRobotUtil {
/**
*
- * @return True if the FocusEventCountAdapter became the desired value within TIME_OUT
- */
- public static boolean waitForFocusCount(boolean desired, FocusEventCountAdapter eca) throws InterruptedException {
- for (int wait=0; wait<POLL_DIVIDER; wait++) {
- if( desired && eca.focusGained() || !desired && eca.focusLost() ) {
- return true;
- }
- Thread.sleep(TIME_SLICE);
- }
- return false;
- }
-
- /**
- *
* @return True if the Component becomes <code>visible</code> within TIME_OUT
*/
public static boolean waitForVisible(Object obj, boolean visible) throws InterruptedException {
@@ -496,6 +546,18 @@ public class AWTRobotUtil {
/**
*
+ * @return True if the GLDrawable recives the expected size within TIME_OUT
+ */
+ public static boolean waitForSize(GLDrawable drawable, int width, int height) throws InterruptedException {
+ int wait;
+ for (wait=0; wait<POLL_DIVIDER && ( width != drawable.getWidth() || height != drawable.getHeight() ) ; wait++) {
+ Thread.sleep(TIME_SLICE);
+ }
+ return wait<POLL_DIVIDER;
+ }
+
+ /**
+ *
* @return True if the Component becomes realized (not displayable, native invalid) within TIME_OUT
*/
public static boolean waitForRealized(Object obj, boolean realized) throws InterruptedException {
diff --git a/src/test/com/jogamp/opengl/test/junit/util/AWTWindowFocusAdapter.java b/src/test/com/jogamp/opengl/test/junit/util/AWTWindowFocusAdapter.java
index 16aacd2..2e74dfa 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/AWTWindowFocusAdapter.java
+++ b/src/test/com/jogamp/opengl/test/junit/util/AWTWindowFocusAdapter.java
@@ -35,12 +35,15 @@ public class AWTWindowFocusAdapter implements FocusEventCountAdapter, WindowFocu
String prefix;
int focusCount;
+ boolean verbose = true;
public AWTWindowFocusAdapter(String prefix) {
this.prefix = prefix;
reset();
}
+ public void setVerbose(boolean v) { verbose = false; }
+
public boolean focusLost() {
return focusCount<0;
}
@@ -57,14 +60,18 @@ public class AWTWindowFocusAdapter implements FocusEventCountAdapter, WindowFocu
public void windowGainedFocus(WindowEvent e) {
if(focusCount<0) { focusCount=0; }
focusCount++;
- System.err.println("FOCUS AWT GAINED (Window) [fc "+focusCount+"]: "+prefix+", "+e);
+ if( verbose ) {
+ System.err.println("FOCUS AWT GAINED (Window) [fc "+focusCount+"]: "+prefix+", "+e);
+ }
}
/* @Override */
public void windowLostFocus(WindowEvent e) {
if(focusCount>0) { focusCount=0; }
focusCount--;
- System.err.println("FOCUS AWT LOST (Window) [fc "+focusCount+"]: "+prefix+", "+e);
+ if( verbose ) {
+ System.err.println("FOCUS AWT LOST (Window) [fc "+focusCount+"]: "+prefix+", "+e);
+ }
}
public String toString() { return prefix+"[focusCount "+focusCount +"]"; }
diff --git a/src/test/com/jogamp/opengl/test/junit/util/EventCountAdapter.java b/src/test/com/jogamp/opengl/test/junit/util/EventCountAdapter.java
index 76a1884..906e4a7 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/EventCountAdapter.java
+++ b/src/test/com/jogamp/opengl/test/junit/util/EventCountAdapter.java
@@ -28,7 +28,16 @@
package com.jogamp.opengl.test.junit.util;
+/**
+ * Base event count adapter.
+ * <p>
+ * Instance starts in verbose mode.
+ * </p>
+ */
public interface EventCountAdapter {
void reset();
+
+ /** Instance starts in verbose mode, call w/ false to disable verbosity. */
+ void setVerbose(boolean v);
}
diff --git a/src/test/com/jogamp/opengl/test/junit/util/InputEventCountAdapter.java b/src/test/com/jogamp/opengl/test/junit/util/InputEventCountAdapter.java
index 27f3d7e..c407843 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/InputEventCountAdapter.java
+++ b/src/test/com/jogamp/opengl/test/junit/util/InputEventCountAdapter.java
@@ -28,8 +28,14 @@
package com.jogamp.opengl.test.junit.util;
+import java.util.EventObject;
+import java.util.List;
+
public interface InputEventCountAdapter extends EventCountAdapter {
int getCount();
boolean isPressed();
+
+ public List<EventObject> getQueued();
+ public int getQueueSize();
}
diff --git a/src/test/com/jogamp/opengl/test/junit/util/InputEventCountAdapter.java b/src/test/com/jogamp/opengl/test/junit/util/KeyEventCountAdapter.java
similarity index 83%
copy from src/test/com/jogamp/opengl/test/junit/util/InputEventCountAdapter.java
copy to src/test/com/jogamp/opengl/test/junit/util/KeyEventCountAdapter.java
index 27f3d7e..832f5ae 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/InputEventCountAdapter.java
+++ b/src/test/com/jogamp/opengl/test/junit/util/KeyEventCountAdapter.java
@@ -1,5 +1,5 @@
/**
- * Copyright 2010 JogAmp Community. All rights reserved.
+ * Copyright 2012 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
@@ -28,8 +28,11 @@
package com.jogamp.opengl.test.junit.util;
-public interface InputEventCountAdapter extends EventCountAdapter {
- int getCount();
- boolean isPressed();
+public interface KeyEventCountAdapter extends InputEventCountAdapter {
+ public int getKeyPressedCount(boolean autoRepeatOnly);
+
+ public int getKeyReleasedCount(boolean autoRepeatOnly);
+
+ public int getKeyTypedCount(boolean autoRepeatOnly);
}
diff --git a/src/test/com/jogamp/opengl/test/junit/util/MiscUtils.java b/src/test/com/jogamp/opengl/test/junit/util/MiscUtils.java
index 9cbeabb..c230f0a 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/MiscUtils.java
+++ b/src/test/com/jogamp/opengl/test/junit/util/MiscUtils.java
@@ -30,6 +30,7 @@
package com.jogamp.opengl.test.junit.util;
import java.lang.reflect.*;
+import java.nio.FloatBuffer;
public class MiscUtils {
public static int atoi(String str, int def) {
@@ -50,6 +51,53 @@ public class MiscUtils {
return def;
}
+ public static void assertFloatBufferEquals(String errmsg, FloatBuffer expected, FloatBuffer actual, float delta) {
+ if(null == expected && null == actual) {
+ return;
+ }
+ String msg = null != errmsg ? errmsg + " " : "";
+ if(null == expected) {
+ throw new AssertionError(msg+"; Expected is null, but actual not: "+actual);
+ }
+ if(null == actual) {
+ throw new AssertionError(msg+"; Actual is null, but expected not: "+expected);
+ }
+ if(expected.remaining() != actual.remaining()) {
+ throw new AssertionError(msg+"; Expected has "+expected.remaining()+" remaining, but actual has "+actual.remaining());
+ }
+ final int a0 = expected.position();
+ final int b0 = actual.position();
+ for(int i=0; i<expected.remaining(); i++) {
+ final float ai = expected.get(a0 + i);
+ final float bi = actual.get(b0 + i);
+ final float daibi = Math.abs(ai - bi);
+ if( daibi > delta ) {
+ throw new AssertionError(msg+"; Expected @ ["+a0+"+"+i+"] has "+ai+", but actual @ ["+b0+"+"+i+"] has "+bi+", it's delta "+daibi+" > "+delta);
+ }
+ }
+ }
+
+ public static void assertFloatBufferNotEqual(String errmsg, FloatBuffer expected, FloatBuffer actual, float delta) {
+ if(null == expected || null == actual) {
+ return;
+ }
+ if(expected.remaining() != actual.remaining()) {
+ return;
+ }
+ String msg = null != errmsg ? errmsg + " " : "";
+ final int a0 = expected.position();
+ final int b0 = actual.position();
+ for(int i=0; i<expected.remaining(); i++) {
+ final float ai = expected.get(a0 + i);
+ final float bi = actual.get(b0 + i);
+ final float daibi = Math.abs(ai - bi);
+ if( daibi > delta ) {
+ return;
+ }
+ }
+ throw new AssertionError(msg+"; Expected and actual are equal.");
+ }
+
public static boolean setFieldIfExists(Object instance, String fieldName, Object value) {
try {
Field f = instance.getClass().getField(fieldName);
diff --git a/src/test/com/jogamp/opengl/test/junit/util/NEWTFocusAdapter.java b/src/test/com/jogamp/opengl/test/junit/util/NEWTFocusAdapter.java
index 27d4abd..ccb1bde 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/NEWTFocusAdapter.java
+++ b/src/test/com/jogamp/opengl/test/junit/util/NEWTFocusAdapter.java
@@ -36,12 +36,15 @@ public class NEWTFocusAdapter implements WindowListener, FocusEventCountAdapter
String prefix;
int focusCount;
+ boolean verbose = true;
public NEWTFocusAdapter(String prefix) {
this.prefix = prefix;
reset();
}
+ public void setVerbose(boolean v) { verbose = false; }
+
public boolean focusLost() {
return focusCount<0;
}
@@ -57,13 +60,17 @@ public class NEWTFocusAdapter implements WindowListener, FocusEventCountAdapter
public void windowGainedFocus(WindowEvent e) {
if(focusCount<0) { focusCount=0; }
focusCount++;
- System.err.println("FOCUS NEWT GAINED [fc "+focusCount+"]: "+prefix+", "+e);
+ if( verbose ) {
+ System.err.println("FOCUS NEWT GAINED [fc "+focusCount+"]: "+prefix+", "+e);
+ }
}
public void windowLostFocus(WindowEvent e) {
if(focusCount>0) { focusCount=0; }
focusCount--;
- System.err.println("FOCUS NEWT LOST [fc "+focusCount+"]: "+prefix+", "+e);
+ if( verbose ) {
+ System.err.println("FOCUS NEWT LOST [fc "+focusCount+"]: "+prefix+", "+e);
+ }
}
public void windowResized(WindowEvent e) { }
diff --git a/src/test/com/jogamp/opengl/test/junit/util/NEWTGLContext.java b/src/test/com/jogamp/opengl/test/junit/util/NEWTGLContext.java
index 3f989bf..a76b67d 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/NEWTGLContext.java
+++ b/src/test/com/jogamp/opengl/test/junit/util/NEWTGLContext.java
@@ -70,8 +70,8 @@ public class NEWTGLContext {
Assert.assertNotNull(window);
window.setSize(width, height);
window.setVisible(true);
- AWTRobotUtil.waitForVisible(window, true);
- AWTRobotUtil.waitForRealized(window, true);
+ Assert.assertTrue(AWTRobotUtil.waitForVisible(window, true));
+ Assert.assertTrue(AWTRobotUtil.waitForRealized(window, true));
GLDrawableFactory factory = GLDrawableFactory.getFactory(caps.getGLProfile());
GLDrawable drawable = factory.createGLDrawable(window);
diff --git a/src/test/com/jogamp/opengl/test/junit/util/NEWTKeyAdapter.java b/src/test/com/jogamp/opengl/test/junit/util/NEWTKeyAdapter.java
index 32b392c..f19169b 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/NEWTKeyAdapter.java
+++ b/src/test/com/jogamp/opengl/test/junit/util/NEWTKeyAdapter.java
@@ -28,47 +28,103 @@
package com.jogamp.opengl.test.junit.util;
+import java.util.ArrayList;
+import java.util.EventObject;
+import java.util.List;
+
+import com.jogamp.newt.event.InputEvent;
import com.jogamp.newt.event.KeyAdapter;
import com.jogamp.newt.event.KeyEvent;
-public class NEWTKeyAdapter extends KeyAdapter implements InputEventCountAdapter {
+public class NEWTKeyAdapter extends KeyAdapter implements KeyEventCountAdapter {
String prefix;
- int keyTyped;
+ int keyPressed, keyReleased, keyTyped;
+ int keyPressedAR, keyReleasedAR, keyTypedAR;
boolean pressed;
+ List<EventObject> queue = new ArrayList<EventObject>();
+ boolean verbose = true;
public NEWTKeyAdapter(String prefix) {
this.prefix = prefix;
reset();
}
+
+ public synchronized void setVerbose(boolean v) { verbose = false; }
- public boolean isPressed() {
+ public synchronized boolean isPressed() {
return pressed;
}
- public int getCount() {
+ public synchronized int getCount() {
return keyTyped;
}
- public void reset() {
+ public synchronized int getKeyPressedCount(boolean autoRepeatOnly) {
+ return autoRepeatOnly ? keyPressedAR: keyPressed;
+ }
+
+ public synchronized int getKeyReleasedCount(boolean autoRepeatOnly) {
+ return autoRepeatOnly ? keyReleasedAR: keyReleased;
+ }
+
+ public synchronized int getKeyTypedCount(boolean autoRepeatOnly) {
+ return autoRepeatOnly ? keyTypedAR: keyTyped;
+ }
+
+ public synchronized List<EventObject> getQueued() {
+ return queue;
+ }
+
+ public synchronized int getQueueSize() {
+ return queue.size();
+ }
+
+ public synchronized void reset() {
keyTyped = 0;
+ keyPressed = 0;
+ keyReleased = 0;
+ keyTypedAR = 0;
+ keyPressedAR = 0;
+ keyReleasedAR = 0;
pressed = false;
+ queue.clear();
}
- public void keyPressed(KeyEvent e) {
+ public synchronized void keyPressed(KeyEvent e) {
pressed = true;
- System.err.println("NEWT AWT PRESSED ["+pressed+"]: "+prefix+", "+e);
+ keyPressed++;
+ if( 0 != ( e.getModifiers() & InputEvent.AUTOREPEAT_MASK ) ) {
+ keyPressedAR++;
+ }
+ queue.add(e);
+ if( verbose ) {
+ System.err.println("NEWT AWT PRESSED ["+pressed+"]: "+prefix+", "+e);
+ }
}
- public void keyReleased(KeyEvent e) {
+ public synchronized void keyReleased(KeyEvent e) {
pressed = false;
- System.err.println("NEWT AWT RELEASED ["+pressed+"]: "+prefix+", "+e);
+ keyReleased++;
+ if( 0 != ( e.getModifiers() & InputEvent.AUTOREPEAT_MASK ) ) {
+ keyReleasedAR++;
+ }
+ queue.add(e);
+ if( verbose ) {
+ System.err.println("NEWT AWT RELEASED ["+pressed+"]: "+prefix+", "+e);
+ }
}
@Override
- public void keyTyped(KeyEvent e) {
- ++keyTyped;
- System.err.println("KEY NEWT TYPED ["+keyTyped+"]: "+prefix+", "+e);
+ public synchronized void keyTyped(KeyEvent e) {
+ keyTyped++;
+ if( 0 != ( e.getModifiers() & InputEvent.AUTOREPEAT_MASK ) ) {
+ keyTypedAR++;
+ }
+ queue.add(e);
+ if( verbose ) {
+ System.err.println("KEY NEWT TYPED ["+keyTyped+"]: "+prefix+", "+e);
+ }
}
public String toString() { return prefix+"[pressed "+pressed+", typed "+keyTyped+"]"; }
diff --git a/src/test/com/jogamp/opengl/test/junit/util/NEWTKeyUtil.java b/src/test/com/jogamp/opengl/test/junit/util/NEWTKeyUtil.java
new file mode 100644
index 0000000..e090ed4
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/util/NEWTKeyUtil.java
@@ -0,0 +1,185 @@
+/**
+ * Copyright 2012 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community OR
+ * CONTRIBUTORS 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.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+package com.jogamp.opengl.test.junit.util;
+
+import java.util.ArrayList;
+import java.util.EventObject;
+import java.util.List;
+
+import org.junit.Assert;
+
+import com.jogamp.common.util.IntIntHashMap;
+import com.jogamp.newt.event.KeyEvent;
+
+public class NEWTKeyUtil {
+ public static class CodeSeg {
+ public final int min;
+ public final int max;
+ public final String description;
+
+ public CodeSeg(int min, int max, String description) {
+ this.min = min;
+ this.max = max;
+ this.description = description;
+ }
+ }
+ public static class CodeEvent {
+ public final int code;
+ public final String description;
+ public final KeyEvent event;
+
+ public CodeEvent(int code, String description, KeyEvent event) {
+ this.code = code;
+ this.description = description;
+ this.event = event;
+ }
+ public String toString() {
+ return "Code 0x"+Integer.toHexString(code)+" != "+event+" // "+description;
+ }
+ }
+
+ public static void dumpKeyEvents(List<EventObject> keyEvents) {
+ for(int i=0; i<keyEvents.size(); i++) {
+ System.err.println(i+": "+keyEvents.get(i));
+ }
+ }
+
+ public static boolean validateKeyCodes(CodeSeg[] codeSegments, List<List<EventObject>> keyEventsList, boolean verbose) {
+ final List<CodeEvent> missCodes = new ArrayList<CodeEvent>();
+ int totalCodeCount = 0;
+ boolean res = true;
+ for(int i=0; i<codeSegments.length; i++) {
+ final CodeSeg codeSeg = codeSegments[i];
+ totalCodeCount += codeSeg.max - codeSeg.min + 1;
+ final List<EventObject> keyEvents = keyEventsList.get(i);
+ res &= validateKeyCodes(missCodes, codeSeg, keyEvents, verbose);
+ }
+ if(verbose) {
+ System.err.println("*** Total KeyCode Misses "+missCodes.size()+" / "+totalCodeCount+", valid "+res);
+ for(int i=0; i<missCodes.size(); i++) {
+ System.err.println("Miss["+i+"]: "+missCodes.get(i));
+ }
+ }
+ return res;
+ }
+ public static boolean validateKeyCodes(List<CodeEvent> missCodes, CodeSeg codeSeg, List<EventObject> keyEvents, boolean verbose) {
+ final int codeCount = codeSeg.max - codeSeg.min + 1;
+ int misses = 0;
+ for(int i=0; i<codeCount; i++) {
+ final int c = codeSeg.min + i;
+ final int j = i*3+0; // KEY_PRESSED
+ final KeyEvent e = (KeyEvent) ( j < keyEvents.size() ? keyEvents.get(j) : null );
+ if( null == e || c != e.getKeyCode() ) {
+ missCodes.add(new CodeEvent(c, codeSeg.description, e));
+ misses++;
+ }
+ }
+ final boolean res = 3*codeCount == keyEvents.size() && 0 == missCodes.size();
+ if(verbose) {
+ System.err.println("+++ Code Segment "+codeSeg.description+", Misses: "+misses+" / "+codeCount+", events "+keyEvents.size()+", valid "+res);
+ }
+ return res;
+ }
+
+ public static void validateKeyEvent(KeyEvent e, int eventType, int modifier, int keyCode) {
+ if(0 <= keyCode) {
+ Assert.assertTrue("KeyEvent code mismatch, expected 0x"+Integer.toHexString(keyCode)+", has "+e, keyCode == e.getKeyCode());
+ }
+ if(0 <= eventType) {
+ Assert.assertTrue("KeyEvent type mismatch, expected 0x"+Integer.toHexString(eventType)+", has "+e, eventType == e.getEventType());
+ }
+ if(0 <= modifier) {
+ Assert.assertTrue("KeyEvent modifier mismatch, expected 0x"+Integer.toHexString(modifier)+", has "+e, modifier == e.getModifiers());
+ }
+ }
+
+ public static int getNextKeyEventType(int et) {
+ switch( et ) {
+ case KeyEvent.EVENT_KEY_PRESSED:
+ return KeyEvent.EVENT_KEY_RELEASED;
+ case KeyEvent.EVENT_KEY_RELEASED:
+ return KeyEvent.EVENT_KEY_TYPED;
+ case KeyEvent.EVENT_KEY_TYPED:
+ return KeyEvent.EVENT_KEY_PRESSED;
+ default:
+ Assert.assertTrue("Invalid event type "+et, false);
+ return 0;
+ }
+ }
+
+ public static void validateKeyEventOrder(List<EventObject> keyEvents) {
+ IntIntHashMap keyCode2NextEvent = new IntIntHashMap();
+ for(int i=0; i<keyEvents.size(); i++) {
+ final KeyEvent e = (KeyEvent) keyEvents.get(i);
+ int eet = keyCode2NextEvent.get(e.getKeyCode());
+ if( 0 >= eet ) {
+ eet = KeyEvent.EVENT_KEY_PRESSED;
+ }
+ final int et = e.getEventType();
+ Assert.assertEquals("Key event not in proper order", eet, et);
+ eet = getNextKeyEventType(et);
+ keyCode2NextEvent.put(e.getKeyCode(), eet);
+ }
+ }
+
+ /**
+ *
+ * @param keyAdapter
+ * @param expTotalCount number of key press/release/types events
+ * @param expARCount number of key press/release/types Auto-Release events
+ */
+ public static void validateKeyAdapterStats(NEWTKeyAdapter keyAdapter, int expTotalCount, int expARCount) {
+ final int keyPressed = keyAdapter.getKeyPressedCount(false);
+ final int keyPressedAR = keyAdapter.getKeyPressedCount(true);
+ final int keyReleased = keyAdapter.getKeyReleasedCount(false);
+ final int keyReleasedAR = keyAdapter.getKeyReleasedCount(true);
+ final int keyTyped = keyAdapter.getKeyTypedCount(false);
+ final int keyTypedAR = keyAdapter.getKeyTypedCount(true);
+ final int keyPressedNR = keyPressed-keyPressedAR;
+ final int keyReleasedNR = keyReleased-keyReleasedAR;
+ final int keyTypedNR = keyTyped-keyTypedAR;
+ System.err.println("Total Press "+keyPressed +", Release "+keyReleased +", Typed "+keyTyped);
+ System.err.println("AutoR Press "+keyPressedAR+", Release "+keyReleasedAR+", Typed "+keyTypedAR);
+ System.err.println("No AR Press "+keyPressedNR+", Release "+keyReleasedNR+", Typed "+keyTypedNR);
+
+ final List<EventObject> keyEvents = keyAdapter.getQueued();
+ Assert.assertEquals("Key event count not multiple of 3", 0, keyEvents.size()%3);
+ Assert.assertEquals("Key event count not 3 * press_release_count", expTotalCount, keyEvents.size());
+ Assert.assertEquals("Key press count failure", expTotalCount/3, keyPressed);
+ Assert.assertEquals("Key press count failure (AR)", expARCount/3, keyPressedAR);
+ Assert.assertEquals("Key released count failure", expTotalCount/3, keyReleased);
+ Assert.assertEquals("Key released count failure (AR)", expARCount/3, keyReleasedAR);
+ Assert.assertEquals("Key typed count failure", expTotalCount/3, keyTyped);
+ Assert.assertEquals("Key typed count failure (AR)", expARCount/3, keyTypedAR);
+
+ // should be true - always, reaching this point - duh!
+ Assert.assertEquals( ( expTotalCount - expARCount ) / 3, keyPressedNR);
+ Assert.assertEquals( ( expTotalCount - expARCount ) / 3, keyReleasedNR);
+ Assert.assertEquals( ( expTotalCount - expARCount ) / 3, keyTypedNR);
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/util/NEWTMouseAdapter.java b/src/test/com/jogamp/opengl/test/junit/util/NEWTMouseAdapter.java
index d98b9ca..6445237 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/NEWTMouseAdapter.java
+++ b/src/test/com/jogamp/opengl/test/junit/util/NEWTMouseAdapter.java
@@ -28,6 +28,10 @@
package com.jogamp.opengl.test.junit.util;
+import java.util.ArrayList;
+import java.util.EventObject;
+import java.util.List;
+
import com.jogamp.newt.event.MouseAdapter;
import com.jogamp.newt.event.MouseEvent;
@@ -36,38 +40,60 @@ public class NEWTMouseAdapter extends MouseAdapter implements InputEventCountAda
String prefix;
int mouseClicked;
boolean pressed;
+ List<EventObject> queue = new ArrayList<EventObject>();
+ boolean verbose = true;
public NEWTMouseAdapter(String prefix) {
this.prefix = prefix;
reset();
}
- public boolean isPressed() {
+ public synchronized void setVerbose(boolean v) { verbose = false; }
+
+ public synchronized boolean isPressed() {
return pressed;
}
- public int getCount() {
+ public synchronized int getCount() {
return mouseClicked;
}
- public void reset() {
+ public synchronized List<EventObject> getQueued() {
+ return queue;
+ }
+
+ public synchronized int getQueueSize() {
+ return queue.size();
+ }
+
+ public synchronized void reset() {
mouseClicked = 0;
pressed = false;
+ queue.clear();
}
- public void mousePressed(MouseEvent e) {
+ public synchronized void mousePressed(MouseEvent e) {
pressed = true;
- System.err.println("MOUSE NEWT PRESSED ["+pressed+"]: "+prefix+", "+e);
+ queue.add(e);
+ if( verbose ) {
+ System.err.println("MOUSE NEWT PRESSED ["+pressed+"]: "+prefix+", "+e);
+ }
}
- public void mouseReleased(MouseEvent e) {
+ public synchronized void mouseReleased(MouseEvent e) {
pressed = false;
- System.err.println("MOUSE NEWT RELEASED ["+pressed+"]: "+prefix+", "+e);
+ queue.add(e);
+ if( verbose ) {
+ System.err.println("MOUSE NEWT RELEASED ["+pressed+"]: "+prefix+", "+e);
+ }
}
- public void mouseClicked(MouseEvent e) {
+ public synchronized void mouseClicked(MouseEvent e) {
mouseClicked+=e.getClickCount();
- System.err.println("MOUSE NEWT CLICKED ["+mouseClicked+"]: "+prefix+", "+e);
+ queue.add(e);
+ if( verbose ) {
+ System.err.println("MOUSE NEWT CLICKED ["+mouseClicked+"]: "+prefix+", "+e);
+ }
}
public String toString() { return prefix+"[pressed "+pressed+", clicked "+mouseClicked+"]"; }
diff --git a/src/test/com/jogamp/opengl/test/junit/util/UITestCase.java b/src/test/com/jogamp/opengl/test/junit/util/UITestCase.java
index c07d5b7..b028df3 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/UITestCase.java
+++ b/src/test/com/jogamp/opengl/test/junit/util/UITestCase.java
@@ -29,12 +29,14 @@
package com.jogamp.opengl.test.junit.util;
import java.io.File;
-import java.io.PrintWriter;
-import java.io.StringWriter;
+import java.util.Iterator;
+import java.util.List;
import javax.media.opengl.GL;
+import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLEventListener;
import com.jogamp.common.util.locks.SingletonInstance;
import com.jogamp.opengl.util.GLReadBufferUtil;
@@ -47,6 +49,8 @@ import org.junit.After;
import org.junit.AfterClass;
import org.junit.Rule;
import org.junit.rules.TestName;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.TestClass;
public abstract class UITestCase {
@@ -58,9 +62,11 @@ public abstract class UITestCase {
public static final long SINGLE_INSTANCE_LOCK_TO = 3*60*1000; // wait up to 3 min
public static final long SINGLE_INSTANCE_LOCK_POLL = 1000; // poll every 1s
- static volatile SingletonInstance singletonInstance;
+ private static volatile SingletonInstance singletonInstance;
- static volatile boolean testSupported = true;
+ private static volatile boolean testSupported = true;
+
+ private static volatile int maxMethodNameLen = 0;
private static final synchronized void initSingletonInstance() {
if( null == singletonInstance ) {
@@ -72,11 +78,29 @@ public abstract class UITestCase {
}
}
+ public static boolean isTestSupported() {
+ return testSupported;
+ }
+
public static void setTestSupported(boolean v) {
System.err.println("setTestSupported: "+v);
testSupported = v;
}
+ public int getMaxTestNameLen() {
+ if(0 == maxMethodNameLen) {
+ int ml = 0;
+ final TestClass tc = new TestClass(getClass());
+ final List<FrameworkMethod> testMethods = tc.getAnnotatedMethods(org.junit.Test.class);
+ for(Iterator<FrameworkMethod> iter=testMethods.iterator(); iter.hasNext(); ) {
+ final int l = iter.next().getName().length();
+ if( ml < l ) { ml = l; }
+ }
+ maxMethodNameLen = ml;
+ }
+ return maxMethodNameLen;
+ }
+
public final String getTestMethodName() {
return _unitTestName.getMethodName();
}
@@ -107,7 +131,7 @@ public abstract class UITestCase {
System.err.print("++++ UITestCase.setUp: "+getFullTestName(" - "));
if(!testSupported) {
System.err.println(" - "+unsupportedTestMsg);
- Assume.assumeTrue(testSupported);
+ Assume.assumeTrue(testSupported); // abort
}
System.err.println();
}
@@ -118,15 +142,52 @@ public abstract class UITestCase {
}
static final String unsupportedTestMsg = "Test not supported on this platform.";
+
+ public String getSnapshotFilename(int sn, String postSNDetail, GLCapabilitiesImmutable caps, int width, int height, boolean sinkHasAlpha, String fileSuffix, String destPath) {
+ if(null == fileSuffix) {
+ fileSuffix = TextureIO.PNG;
+ }
+ final int maxSimpleTestNameLen = getMaxTestNameLen()+getClass().getSimpleName().length()+1;
+ final String simpleTestName = this.getSimpleTestName(".");
+ final String filenameBaseName;
+ {
+ final String accel = caps.getHardwareAccelerated() ? "hw" : "sw" ;
+ final String scrnm;
+ if(caps.isOnscreen()) {
+ scrnm = "onscreen";
+ } else if(caps.isFBO()) {
+ scrnm = "fbobject";
+ } else if(caps.isPBuffer()) {
+ scrnm = "pbuffer_";
+ } else if(caps.isBitmap()) {
+ scrnm = "bitmap__";
+ } else {
+ scrnm = "unknown_";
+ }
+ final String dblb = caps.getDoubleBuffered() ? "dbl" : "one";
+ final String F_pfmt = sinkHasAlpha ? "rgba" : "rgb_";
+ final String pfmt = caps.getAlphaBits() > 0 ? "rgba" : "rgb_";
+ final int depthBits = caps.getDepthBits();
+ final int stencilBits = caps.getStencilBits();
+ final int samples = caps.getNumSamples() ;
+ final String aaext = caps.getSampleExtension();
+ postSNDetail = null != postSNDetail ? "-"+postSNDetail : "";
+
+ filenameBaseName = String.format("%-"+maxSimpleTestNameLen+"s-n%04d%s-%-6s-%s-%s-B%s-F%s_I%s-D%02d-St%02d-Sa%02d_%s-%04dx%04d.%s",
+ simpleTestName, sn, postSNDetail, caps.getGLProfile().getName(), accel,
+ scrnm, dblb, F_pfmt, pfmt, depthBits, stencilBits, samples, aaext,
+ width, height, fileSuffix).replace(' ', '_');
+ }
+ return null != destPath ? destPath + File.separator + filenameBaseName : filenameBaseName;
+ }
/**
- * Takes a snapshot of the drawable's current framebuffer. Example filenames:
+ * Takes a snapshot of the drawable's current front framebuffer. Example filenames:
* <pre>
- * TestFBODrawableNEWT.test01-F_rgba-I_rgba-S0_default-GL2-n0004-0800x0600.png
- * TestFBODrawableNEWT.test01-F_rgba-I_rgba-S0_default-GL2-n0005-0800x0600.png
+ * TestGLDrawableAutoDelegateOnOffscrnCapsNEWT.testES2OffScreenFBOSglBuf____-n0001-msaa0-GLES2_-sw-fbobject-Bdbl-Frgb__Irgb_-D24-St00-Sa00_default-0400x0300.png
+ * TestGLDrawableAutoDelegateOnOffscrnCapsNEWT.testES2OffScreenPbufferDblBuf-n0003-msaa0-GLES2_-sw-pbuffer_-Bdbl-Frgb__Irgb_-D24-St00-Sa00_default-0200x0150.png
+ * TestGLDrawableAutoDelegateOnOffscrnCapsNEWT.testGL2OffScreenPbufferSglBuf-n0003-msaa0-GL2___-hw-pbuffer_-Bone-Frgb__Irgb_-D24-St00-Sa00_default-0200x0150.png
* </pre>
- *
- * @param simpleTestName will be used as the filename prefix
* @param sn sequential number
* @param postSNDetail optional detail to be added to the filename after <code>sn</code>
* @param gl the current GL context object. It's read drawable is being used as the pixel source and to gather some details which will end up in the filename.
@@ -137,30 +198,68 @@ public abstract class UITestCase {
* It shall not end with a directory separator, {@link File#separatorChar}.
* If <code>null</code> the current working directory is being used.
*/
- public static void snapshot(String simpleTestName, int sn, String postSNDetail, GL gl, GLReadBufferUtil readBufferUtil, String fileSuffix, String destPath) {
- if(null == fileSuffix) {
- fileSuffix = TextureIO.PNG;
- }
- final StringWriter filenameSW = new StringWriter();
- {
- final GLDrawable drawable = gl.getContext().getGLReadDrawable();
- final GLCapabilitiesImmutable caps = drawable.getChosenGLCapabilities();
- final String F_pfmt = readBufferUtil.hasAlpha() ? "rgba" : "rgb_";
- final String pfmt = caps.getAlphaBits() > 0 ? "rgba" : "rgb_";
- final String aaext = caps.getSampleExtension();
- final int samples = caps.getNumSamples() ;
- postSNDetail = null != postSNDetail ? "-"+postSNDetail : "";
- final PrintWriter pw = new PrintWriter(filenameSW);
- pw.printf("%s-n%04d%s-F_%s-I_%s-S%d_%s-%s-%04dx%04d.%s",
- simpleTestName, sn, postSNDetail, F_pfmt, pfmt, samples, aaext, drawable.getGLProfile().getName(),
- drawable.getWidth(), drawable.getHeight(), fileSuffix);
- }
- final String filename = null != destPath ? destPath + File.separator + filenameSW.toString() : filenameSW.toString();
+ public void snapshot(int sn, String postSNDetail, GL gl, GLReadBufferUtil readBufferUtil, String fileSuffix, String destPath) {
+ final GLDrawable drawable = gl.getContext().getGLReadDrawable();
+ final String filename = getSnapshotFilename(sn, postSNDetail,
+ drawable.getChosenGLCapabilities(), drawable.getWidth(), drawable.getHeight(),
+ readBufferUtil.hasAlpha(), fileSuffix, destPath);
System.err.println(Thread.currentThread().getName()+": ** screenshot: "+filename);
gl.glFinish(); // just make sure rendering finished ..
if(readBufferUtil.readPixels(gl, false)) {
readBufferUtil.write(new File(filename));
}
- }
+ }
+
+ public class SnapshotGLEventListener implements GLEventListener {
+ private final GLReadBufferUtil screenshot;
+ private volatile boolean makeShot = false;
+ private volatile boolean makeShotAlways = false;
+ private volatile boolean verbose = false;
+ private volatile int displayCount=0;
+ private volatile int reshapeCount=0;
+ private volatile String postSNDetail = null;
+ public SnapshotGLEventListener(GLReadBufferUtil screenshot) {
+ this.screenshot = screenshot;
+ }
+ public SnapshotGLEventListener() {
+ this.screenshot = new GLReadBufferUtil(false, false);
+ }
+ public int getDisplayCount() { return displayCount; }
+ public int getReshapeCount() { return reshapeCount; }
+ public GLReadBufferUtil getGLReadBufferUtil() { return screenshot; }
+ public void init(GLAutoDrawable drawable) {}
+ public void dispose(GLAutoDrawable drawable) {}
+ public void display(GLAutoDrawable drawable) {
+ final GL gl = drawable.getGL();
+ final boolean _makeShot = makeShot || makeShotAlways;
+ if(verbose) {
+ System.err.println(Thread.currentThread().getName()+": ** display: "+displayCount+": "+drawable.getWidth()+"x"+drawable.getHeight()+", makeShot "+_makeShot);
+ }
+ if(_makeShot) {
+ makeShot=false;
+ snapshot(displayCount, postSNDetail, gl, screenshot, TextureIO.PNG, null);
+ }
+ displayCount++;
+ }
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
+ if(verbose) {
+ System.err.println(Thread.currentThread().getName()+": ** reshape: "+reshapeCount+": "+width+"x"+height+" - "+drawable.getWidth()+"x"+drawable.getHeight());
+ }
+ reshapeCount++;
+ }
+ public void setMakeSnapshot() {
+ makeShot=true;
+ }
+ public void setMakeSnapshotAlways(boolean v) {
+ makeShotAlways=v;
+ }
+ public void setVerbose(boolean v) {
+ verbose=v;
+ }
+ public void setPostSNDetail(String v) {
+ postSNDetail = v;
+ }
+ };
+
}
diff --git a/src/test/com/jogamp/opengl/test/junit/util/MiscUtils.java b/src/test/com/jogamp/opengl/test/junit/util/ValidateLockListener.java
similarity index 54%
copy from src/test/com/jogamp/opengl/test/junit/util/MiscUtils.java
copy to src/test/com/jogamp/opengl/test/junit/util/ValidateLockListener.java
index 9cbeabb..73c1ad7 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/MiscUtils.java
+++ b/src/test/com/jogamp/opengl/test/junit/util/ValidateLockListener.java
@@ -1,5 +1,5 @@
/**
- * Copyright 2010 JogAmp Community. All rights reserved.
+ * Copyright 2012 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
@@ -26,47 +26,46 @@
* or implied, of JogAmp Community.
*/
-
package com.jogamp.opengl.test.junit.util;
-import java.lang.reflect.*;
-public class MiscUtils {
- public static int atoi(String str, int def) {
- try {
- return Integer.parseInt(str);
- } catch (Exception ex) {
- ex.printStackTrace();
+import javax.media.nativewindow.NativeSurface;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLEventListener;
+
+
+public class ValidateLockListener implements GLEventListener {
+
+ private void validateLock(GLAutoDrawable drawable) {
+ final NativeSurface ns = drawable.getNativeSurface();
+ ns.getGraphicsConfiguration().getScreen().getDevice().validateLocked();
+
+ final Thread current = Thread.currentThread();
+ final Thread owner = ns.getSurfaceLockOwner();
+ if( ns.isSurfaceLockedByOtherThread() ) {
+ throw new RuntimeException(current.getName()+": Locked by another thread(1), owner "+owner+", "+ns);
+ }
+ if( current != owner ) {
+ if( null == owner ) {
+ throw new RuntimeException(current.getName()+": Not locked: "+ns);
+ }
+ throw new RuntimeException(current.getName()+": Locked by another thread(2), owner "+owner+", "+ns);
}
- return def;
}
- public static long atol(String str, long def) {
- try {
- return Long.parseLong(str);
- } catch (Exception ex) {
- ex.printStackTrace();
- }
- return def;
+ public void init(GLAutoDrawable drawable) {
+ validateLock(drawable);
}
- public static boolean setFieldIfExists(Object instance, String fieldName, Object value) {
- try {
- Field f = instance.getClass().getField(fieldName);
- if(value instanceof Boolean || f.getType().isInstance(value)) {
- f.set(instance, value);
- return true;
- } else {
- System.out.println(instance.getClass()+" '"+fieldName+"' field not assignable with "+value.getClass()+", it's a: "+f.getType());
- }
- } catch (IllegalAccessException ex) {
- throw new RuntimeException(ex);
- } catch (NoSuchFieldException nsfe) {
- // OK - throw new RuntimeException(instance.getClass()+" has no '"+fieldName+"' field", nsfe);
- }
- return false;
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
+ validateLock(drawable);
}
-}
-
+ public void display(GLAutoDrawable drawable) {
+ validateLock(drawable);
+ }
+ public void dispose(GLAutoDrawable drawable) {
+ validateLock(drawable);
+ }
+}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/libjogl2-java.git
More information about the pkg-java-commits
mailing list