aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/jogl/classes/com/jogamp/audio/windows/waveout/Mixer.java239
-rw-r--r--src/jogl/classes/com/jogamp/gluegen/opengl/BuildComposablePipeline.java35
-rw-r--r--src/jogl/classes/com/jogamp/gluegen/opengl/GLConfiguration.java8
-rw-r--r--src/jogl/classes/com/jogamp/gluegen/opengl/GLEmitter.java44
-rw-r--r--src/jogl/classes/com/jogamp/gluegen/runtime/opengl/GLNameResolver.java9
-rw-r--r--src/jogl/classes/com/jogamp/graph/font/FontFactory.java2
-rw-r--r--src/jogl/classes/com/jogamp/opengl/GLAnimatorControl.java3
-rw-r--r--src/jogl/classes/com/jogamp/opengl/GLBase.java73
-rw-r--r--src/jogl/classes/com/jogamp/opengl/GLContext.java222
-rw-r--r--src/jogl/classes/com/jogamp/opengl/GLDrawableFactory.java12
-rw-r--r--src/jogl/classes/com/jogamp/opengl/GLExtensions.java2
-rw-r--r--src/jogl/classes/com/jogamp/opengl/GLProfile.java115
-rw-r--r--src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java7
-rw-r--r--src/jogl/classes/com/jogamp/opengl/GLUniformData.java1
-rw-r--r--src/jogl/classes/com/jogamp/opengl/JoglVersion.java3
-rw-r--r--src/jogl/classes/com/jogamp/opengl/awt/GLJPanel.java3
-rw-r--r--src/jogl/classes/com/jogamp/opengl/cg/CgDynamicLibraryBundleInfo.java10
-rw-r--r--src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java6
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/AWTAnimatorImpl.java48
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/Animator.java23
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java5
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/DefaultAnimatorImpl.java13
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/GLPixelBuffer.java4
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/GLReadBufferUtil.java4
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java2
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/PNGPixelRect.java3
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java19
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java3
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderCode.java100
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/glsl/sdk/CompileShader.java4
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/texture/ImageIOUtil.java445
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/texture/ImageSequence.java2
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/texture/ImageType.java1579
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java51
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/texture/TextureData.java14
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java319
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/texture/spi/DDSImage.java35
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/texture/spi/SGIImage.java24
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/texture/spi/TextureProvider.java101
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/texture/spi/awt/IIOTextureProvider.java51
-rw-r--r--src/jogl/classes/jogamp/graph/font/UbuntuFontLoader.java10
-rw-r--r--src/jogl/classes/jogamp/opengl/DesktopGLDynamicLookupHelper.java2
-rw-r--r--src/jogl/classes/jogamp/opengl/ExtensionAvailabilityCache.java11
-rw-r--r--src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java39
-rw-r--r--src/jogl/classes/jogamp/opengl/GLContextImpl.java826
-rw-r--r--src/jogl/classes/jogamp/opengl/GLDebugMessageHandler.java82
-rw-r--r--src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java18
-rw-r--r--src/jogl/classes/jogamp/opengl/GLDrawableHelper.java106
-rw-r--r--src/jogl/classes/jogamp/opengl/GLDrawableImpl.java8
-rw-r--r--src/jogl/classes/jogamp/opengl/GLDynamicLibraryBundleInfo.java10
-rw-r--r--src/jogl/classes/jogamp/opengl/GLRunnableTask.java5
-rw-r--r--src/jogl/classes/jogamp/opengl/GLWorkerThread.java26
-rw-r--r--src/jogl/classes/jogamp/opengl/GLXExtensions.java6
-rw-r--r--src/jogl/classes/jogamp/opengl/SharedResourceRunner.java136
-rw-r--r--src/jogl/classes/jogamp/opengl/android/av/AndroidGLMediaPlayerAPI14.java11
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLContext.java104
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java32
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java6
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java698
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLDummyUpstreamSurfaceHook.java8
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLES2DynamicLibraryBundleInfo.java18
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java2
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLSurface.java12
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java42
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java29
-rw-r--r--src/jogl/classes/jogamp/opengl/openal/av/ALAudioSink.java22
-rw-r--r--src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java193
-rw-r--r--src/jogl/classes/jogamp/opengl/util/av/VideoPixelFormat.java2
-rw-r--r--src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGDynamicLibraryBundleInfo.java22
-rw-r--r--src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGMediaPlayer.java59
-rw-r--r--src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncColor.fp6
-rw-r--r--src/jogl/classes/jogamp/opengl/util/glsl/fixedfunc/shaders/FixedFuncColorTexture.fp12
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java99
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java65
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java19
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java5
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java125
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java63
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java15
-rw-r--r--src/jogl/native/GLDebugMessageHandler.c7
-rw-r--r--src/jogl/native/libav/ffmpeg_impl_template.c11
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/DefaultGraphicsDevice.java17
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/DefaultGraphicsScreen.java2
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowException.java1
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowFactory.java80
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowHolder.java41
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTGraphicsConfiguration.java21
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/awt/AppContextInfo.java15
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java56
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java20
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/javafx/JFXAccessor.java291
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java2
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/util/Point.java12
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsConfiguration.java43
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/BcmVCArtifacts.java76
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java9
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java43
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java103
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/x11/X11GraphicsConfigurationFactory.java12
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java10
-rw-r--r--src/nativewindow/native/macosx/OSXmisc.m46
-rw-r--r--src/nativewindow/native/win32/WindowsDWM.c115
-rw-r--r--src/nativewindow/native/win32/WindowsDWM.h34
-rw-r--r--src/newt/classes/com/jogamp/newt/NewtFactory.java8
-rw-r--r--src/newt/classes/com/jogamp/newt/Window.java170
-rw-r--r--src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java22
-rw-r--r--src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtApplet1Run.java2
-rw-r--r--src/newt/classes/com/jogamp/newt/javafx/NewtCanvasJFX.java670
-rw-r--r--src/newt/classes/com/jogamp/newt/opengl/GLWindow.java10
-rw-r--r--src/newt/classes/com/jogamp/newt/opengl/util/NEWTDemoListener.java (renamed from src/test/com/jogamp/opengl/test/junit/util/NEWTDemoListener.java)334
-rw-r--r--src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java28
-rw-r--r--src/newt/classes/com/jogamp/newt/util/MainThread.java20
-rw-r--r--src/newt/classes/com/jogamp/newt/util/applet/JOGLNewtAppletBase.java98
-rw-r--r--src/newt/classes/com/jogamp/newt/util/applet3/JOGLNewtApplet3Run.java2
-rw-r--r--src/newt/classes/jogamp/newt/DefaultEDTUtil.java45
-rw-r--r--src/newt/classes/jogamp/newt/DisplayImpl.java48
-rw-r--r--src/newt/classes/jogamp/newt/OffscreenWindow.java10
-rw-r--r--src/newt/classes/jogamp/newt/WindowImpl.java796
-rw-r--r--src/newt/classes/jogamp/newt/awt/NewtFactoryAWT.java35
-rw-r--r--src/newt/classes/jogamp/newt/driver/android/WindowDriver.java11
-rw-r--r--src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java63
-rw-r--r--src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java35
-rw-r--r--src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java166
-rw-r--r--src/newt/classes/jogamp/newt/driver/bcm/egl/WindowDriver.java11
-rw-r--r--src/newt/classes/jogamp/newt/driver/bcm/vc/iv/DisplayDriver.java12
-rw-r--r--src/newt/classes/jogamp/newt/driver/bcm/vc/iv/WindowDriver.java20
-rw-r--r--src/newt/classes/jogamp/newt/driver/intel/gdl/WindowDriver.java11
-rw-r--r--src/newt/classes/jogamp/newt/driver/kd/WindowDriver.java11
-rw-r--r--src/newt/classes/jogamp/newt/driver/linux/LinuxEventDeviceTracker.java5
-rw-r--r--src/newt/classes/jogamp/newt/driver/linux/LinuxMouseTracker.java3
-rw-r--r--src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java4
-rw-r--r--src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java285
-rw-r--r--src/newt/classes/jogamp/newt/driver/opengl/JoglUtilPNGIcon.java62
-rw-r--r--src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java14
-rw-r--r--src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java79
-rw-r--r--src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java26
-rw-r--r--src/newt/classes/jogamp/newt/driver/x11/X11UnderlayTracker.java58
-rw-r--r--src/newt/classes/jogamp/newt/event/NEWTEventTask.java8
-rw-r--r--src/newt/classes/jogamp/newt/javafx/JFXEDTUtil.java358
-rw-r--r--src/newt/classes/jogamp/newt/swt/SWTEDTUtil.java33
-rw-r--r--src/newt/native/MacWindow.m149
-rw-r--r--src/newt/native/NewtMacWindow.h9
-rw-r--r--src/newt/native/NewtMacWindow.m135
-rw-r--r--src/newt/native/Window.h4
-rw-r--r--src/newt/native/WindowsEDID.c10
-rw-r--r--src/newt/native/WindowsWindow.c588
-rw-r--r--src/newt/native/X11Common.h64
-rw-r--r--src/newt/native/X11Display.c171
-rw-r--r--src/newt/native/X11RandR13.c8
-rw-r--r--src/newt/native/X11Window.c313
-rw-r--r--src/oculusvr/classes/com/jogamp/oculusvr/OVRDynamicLibraryBundleInfo.java10
-rw-r--r--src/test/com/jogamp/opengl/test/android/NEWTGearsES2Activity.java3
-rw-r--r--src/test/com/jogamp/opengl/test/bugs/Bug735Inv0AppletAWT.java4
-rw-r--r--src/test/com/jogamp/opengl/test/bugs/Bug735Inv1AppletAWT.java4
-rw-r--r--src/test/com/jogamp/opengl/test/bugs/Bug735Inv2AppletAWT.java7
-rw-r--r--src/test/com/jogamp/opengl/test/bugs/Issue344Base.java3
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/FontSet01.java32
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT00.java7
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT10.java2
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/demos/GPURendererListenerBase01.java25
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextGLListener0A.java1
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextRendererListenerBase01.java11
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/demos/GPUUISceneGLListener0A.java19
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/demos/GPUUISceneNewtCanvasAWTDemo.java4
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/demos/GPUUISceneNewtDemo.java4
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/demos/ui/MediaPlayerButton.java8
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIListenerBase01.java18
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/GLProfile0XBase.java3
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/InitConcurrentBaseNEWT.java8
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestBug1146GLContextDialogToolTipAWT.java5
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOAutoDrawableDeadlockAWT.java3
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMix2DemosES2NEWT.java9
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOOffThreadSharedContextMix2DemosES2NEWT.java4
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOOnThreadSharedContext1DemoES2NEWT.java4
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableFactoryGLProfileDeviceNEWT.java247
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextSurfaceLockNEWT.java9
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLDebug00NEWT.java85
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLDebug01NEWT.java65
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestOffscreenLayer02NewtCanvasAWT.java17
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestPBufferDeadlockAWT.java3
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedExternalContextAWT.java3
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestVersionSemanticsNOUI.java38
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/anim/Bug898AnimatorFromEDTAWT.java9
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug1225EventQueueInterruptedAWT.java378
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug1245JTabbedPanelCrashAWT.java228
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/caps/TestTranslucencyNEWT.java8
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/GLClearOnInitReshape.java64
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/PointsDemoES1.java4
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/RedSquareES1.java4
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/newt/TestGearsES1NEWT.java5
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/newt/TestRedSquareES1NEWT.java5
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/FBOMix2DemosES2.java4
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java4
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/LandscapeES2.java4
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/LineSquareXDemoES2.java189
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/Mix2TexturesES2.java4
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/PointsDemoES2.java4
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareES2.java36
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareMappedES2.java4
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureDraw02ES2ListenerFBO.java4
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/CrossFadePlayer.java7
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieCube.java32
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSBSStereo.java5
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java36
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2AWT.java10
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2GLJPanelAWT.java231
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestElektronenMultipliziererNEWT.java5
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java145
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NewtCanvasAWT.java39
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NewtCanvasSWT.java7
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2SimpleNEWT.java22
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestLandscapeES2NEWT.java8
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestLandscapeES2NewtCanvasAWT.java25
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestRedSquareES2NEWT.java8
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/Gears.java4
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/Teapot.java2
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/newt/TestGearsNEWT.java35
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/gl3/GeomShader01TextureGL3.java2
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/javafx/PureJFXApp01.java54
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/javafx/TestNewtCanvasJFXGLn.java516
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/math/TestPMVMatrix01NEWT.java4
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/swt/TestBug672NewtCanvasSWTSashForm.java4
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/swt/TestBug672NewtCanvasSWTSashFormComposite.java4
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/swt/TestNewtCanvasSWTBug628ResizeDeadlockAWT.java17
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTBug643AsyncExec.java8
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/util/DemoGL2ES1TextureImmModeSink.java2
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/util/texture/ImageTstFiles.java128
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestBug362DDSImageCreateFromData.java2
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite02NEWT.java3
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestImageTypeNEWT.java92
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestJPEGImage01NEWT.java2
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestJPEGJoglAWTBenchmarkNewtAWT.java6
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestJPEGJoglAWTCompareNewtAWT.java4
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestJPEGTextureFromFileNEWT.java20
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGPixelRect00NEWT.java4
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGPixelRect01NEWT.java6
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileAWT.java2
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileNEWT.java18
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPixelFormatUtil01NEWT.java2
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestTGATextureFromFileNEWT.java6
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestTextureIONEWT.java165
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/TestBug1211IRQ00NEWT.java324
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/TestGLWindows00NEWT.java100
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/TestGLWindows01NEWT.java99
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/TestWindowAndPointerIconNEWT.java2
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/TestWindows02NEWT.java158
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/event/BaseNewtEventModifiers.java10
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/event/TestParentingFocus03KeyTraversalAWT.java10
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtAWTReparentingKeyAdapter.java85
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtJFXReparentingKeyAdapter.java102
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtReparentingKeyAdapter.java111
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01NEWT.java158
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01cSwingAWT.java5
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting02NEWT.java38
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting03AWT.java13
-rw-r--r--src/test/com/jogamp/opengl/test/junit/util/MiscUtils.java3
256 files changed, 12784 insertions, 4437 deletions
diff --git a/src/jogl/classes/com/jogamp/audio/windows/waveout/Mixer.java b/src/jogl/classes/com/jogamp/audio/windows/waveout/Mixer.java
index bbfe72b08..30b3fd278 100644
--- a/src/jogl/classes/com/jogamp/audio/windows/waveout/Mixer.java
+++ b/src/jogl/classes/com/jogamp/audio/windows/waveout/Mixer.java
@@ -36,6 +36,9 @@ import java.io.*;
import java.nio.*;
import java.util.*;
+import com.jogamp.common.util.InterruptSource;
+import com.jogamp.common.util.InterruptedRuntimeException;
+
// Needed only for NIO workarounds on CVM
import java.lang.reflect.*;
@@ -43,9 +46,10 @@ public class Mixer {
// This class is a singleton
private static Mixer mixer;
- private volatile boolean shutdown;
- private volatile Object shutdownLock = new Object();
- private volatile boolean shutdownDone;
+ volatile boolean fillerAlive;
+ volatile boolean mixerAlive;
+ volatile boolean shutdown;
+ volatile Object shutdownLock = new Object();
// Windows Event object
private final long event;
@@ -63,6 +67,9 @@ public class Mixer {
private Mixer() {
event = CreateEvent();
+ fillerAlive = false;
+ mixerAlive = false;
+ shutdown = false;
new FillerThread().start();
final MixerThread m = new MixerThread();
m.setPriority(Thread.MAX_PRIORITY - 1);
@@ -118,50 +125,57 @@ public class Mixer {
shutdown = true;
SetEvent(event);
try {
- shutdownLock.wait();
+ while(fillerAlive || mixerAlive) {
+ shutdownLock.wait();
+ }
} catch (final InterruptedException e) {
+ throw new InterruptedRuntimeException(e);
}
}
}
- class FillerThread extends Thread {
+ class FillerThread extends InterruptSource.Thread {
FillerThread() {
- super("Mixer Thread");
+ super(null, null, "Mixer Thread");
}
@Override
public void run() {
- while (!shutdown) {
- final List<Track> curTracks = tracks;
+ fillerAlive = true;
+ try {
+ while (!shutdown) {
+ final List<Track> curTracks = tracks;
- for (final Iterator<Track> iter = curTracks.iterator(); iter.hasNext(); ) {
- final Track track = iter.next();
+ for (final Iterator<Track> iter = curTracks.iterator(); iter.hasNext(); ) {
+ final Track track = iter.next();
+ try {
+ track.fill();
+ } catch (final IOException e) {
+ e.printStackTrace();
+ remove(track);
+ }
+ }
try {
- track.fill();
- } catch (final IOException e) {
- e.printStackTrace();
- remove(track);
+ // Run ten times per second
+ java.lang.Thread.sleep(100);
+ } catch (final InterruptedException e) {
+ throw new InterruptedRuntimeException(e);
}
}
-
- try {
- // Run ten times per second
- Thread.sleep(100);
- } catch (final InterruptedException e) {
- e.printStackTrace();
- }
+ } finally {
+ fillerAlive = false;
}
}
}
- class MixerThread extends Thread {
+ class MixerThread extends InterruptSource.Thread {
// Temporary mixing buffer
// Interleaved left and right channels
float[] mixingBuffer;
private final Vec3f temp = new Vec3f();
MixerThread() {
- super("Mixer Thread");
+ super(null, null, "Mixer Thread");
if (!initializeWaveOut(event)) {
throw new InternalError("Error initializing waveout device");
}
@@ -169,108 +183,113 @@ public class Mixer {
@Override
public void run() {
- while (!shutdown) {
- // Get the next buffer
- final long mixerBuffer = getNextMixerBuffer();
- if (mixerBuffer != 0) {
- ByteBuffer buf = getMixerBufferData(mixerBuffer);
-
- if (buf == null) {
- // This is happening on CVM because
- // JNI_NewDirectByteBuffer isn't implemented
- // by default and isn't compatible with the
- // JSR-239 NIO implementation (apparently)
- buf = newDirectByteBuffer(getMixerBufferDataAddress(mixerBuffer),
- getMixerBufferDataCapacity(mixerBuffer));
- }
+ mixerAlive = true;
+ try {
+ while (!shutdown) {
+ // Get the next buffer
+ final long mixerBuffer = getNextMixerBuffer();
+ if (mixerBuffer != 0) {
+ ByteBuffer buf = getMixerBufferData(mixerBuffer);
+
+ if (buf == null) {
+ // This is happening on CVM because
+ // JNI_NewDirectByteBuffer isn't implemented
+ // by default and isn't compatible with the
+ // JSR-239 NIO implementation (apparently)
+ buf = newDirectByteBuffer(getMixerBufferDataAddress(mixerBuffer),
+ getMixerBufferDataCapacity(mixerBuffer));
+ }
- if (buf == null) {
- throw new InternalError("Couldn't wrap the native address with a direct byte buffer");
- }
+ if (buf == null) {
+ throw new InternalError("Couldn't wrap the native address with a direct byte buffer");
+ }
- // System.out.println("Mixing buffer");
+ // System.out.println("Mixing buffer");
- // If we don't have enough samples in our mixing buffer, expand it
- // FIXME: knowledge of native output rendering format
- if ((mixingBuffer == null) || (mixingBuffer.length < (buf.capacity() / 2 /* bytes / sample */))) {
- mixingBuffer = new float[buf.capacity() / 2];
- } else {
- // Zap it
- for (int i = 0; i < mixingBuffer.length; i++) {
- mixingBuffer[i] = 0.0f;
+ // If we don't have enough samples in our mixing buffer, expand it
+ // FIXME: knowledge of native output rendering format
+ if ((mixingBuffer == null) || (mixingBuffer.length < (buf.capacity() / 2 /* bytes / sample */))) {
+ mixingBuffer = new float[buf.capacity() / 2];
+ } else {
+ // Zap it
+ for (int i = 0; i < mixingBuffer.length; i++) {
+ mixingBuffer[i] = 0.0f;
+ }
}
- }
-
- // This assertion should be in place if we have stereo
- if ((mixingBuffer.length % 2) != 0) {
- final String msg = "FATAL ERROR: odd number of samples in the mixing buffer";
- System.out.println(msg);
- throw new InternalError(msg);
- }
- // Run down all of the registered tracks mixing them in
- final List<Track> curTracks = tracks;
+ // This assertion should be in place if we have stereo
+ if ((mixingBuffer.length % 2) != 0) {
+ final String msg = "FATAL ERROR: odd number of samples in the mixing buffer";
+ System.out.println(msg);
+ throw new InternalError(msg);
+ }
- for (final Iterator<Track> iter = curTracks.iterator(); iter.hasNext(); ) {
- final Track track = iter.next();
- // Consider only playing tracks
- if (track.isPlaying()) {
- // First recompute its gain
- final Vec3f pos = track.getPosition();
- final float leftGain = gain(pos, leftSpeakerPosition);
- final float rightGain = gain(pos, rightSpeakerPosition);
- // Now mix it in
- int i = 0;
- while (i < mixingBuffer.length) {
- if (track.hasNextSample()) {
- final float sample = track.nextSample();
- mixingBuffer[i++] = sample * leftGain;
- mixingBuffer[i++] = sample * rightGain;
- } else {
- // This allows tracks to stall without being abruptly cancelled
- if (track.done()) {
- remove(track);
+ // Run down all of the registered tracks mixing them in
+ final List<Track> curTracks = tracks;
+
+ for (final Iterator<Track> iter = curTracks.iterator(); iter.hasNext(); ) {
+ final Track track = iter.next();
+ // Consider only playing tracks
+ if (track.isPlaying()) {
+ // First recompute its gain
+ final Vec3f pos = track.getPosition();
+ final float leftGain = gain(pos, leftSpeakerPosition);
+ final float rightGain = gain(pos, rightSpeakerPosition);
+ // Now mix it in
+ int i = 0;
+ while (i < mixingBuffer.length) {
+ if (track.hasNextSample()) {
+ final float sample = track.nextSample();
+ mixingBuffer[i++] = sample * leftGain;
+ mixingBuffer[i++] = sample * rightGain;
+ } else {
+ // This allows tracks to stall without being abruptly cancelled
+ if (track.done()) {
+ remove(track);
+ }
+ break;
}
- break;
}
}
}
- }
- // Now that we have our data, send it down to the card
- int outPos = 0;
- for (int i = 0; i < mixingBuffer.length; i++) {
- final short val = (short) mixingBuffer[i];
- buf.put(outPos++, (byte) val);
- buf.put(outPos++, (byte) (val >> 8));
- }
- if (!prepareMixerBuffer(mixerBuffer)) {
- throw new RuntimeException("Error preparing mixer buffer");
- }
- if (!writeMixerBuffer(mixerBuffer)) {
- throw new RuntimeException("Error writing mixer buffer to device");
- }
- } else {
- // System.out.println("No mixer buffer available");
+ // Now that we have our data, send it down to the card
+ int outPos = 0;
+ for (int i = 0; i < mixingBuffer.length; i++) {
+ final short val = (short) mixingBuffer[i];
+ buf.put(outPos++, (byte) val);
+ buf.put(outPos++, (byte) (val >> 8));
+ }
+ if (!prepareMixerBuffer(mixerBuffer)) {
+ throw new RuntimeException("Error preparing mixer buffer");
+ }
+ if (!writeMixerBuffer(mixerBuffer)) {
+ throw new RuntimeException("Error writing mixer buffer to device");
+ }
+ } else {
+ // System.out.println("No mixer buffer available");
- // Wait for a buffer to become available
- if (!WaitForSingleObject(event)) {
- throw new RuntimeException("Error while waiting for event object");
- }
+ // Wait for a buffer to become available
+ if (!WaitForSingleObject(event)) {
+ throw new RuntimeException("Error while waiting for event object");
+ }
- /*
- try {
- Thread.sleep(10);
- } catch (InterruptedException e) {
+ /*
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException e) {
+ throw new InterruptedRuntimeException(e);
+ }
+ */
}
- */
}
- }
-
- // Need to shut down
- shutdownWaveOut();
- synchronized(shutdownLock) {
- shutdownLock.notifyAll();
+ } finally {
+ mixerAlive = false;
+ // Need to shut down
+ shutdownWaveOut();
+ synchronized(shutdownLock) {
+ shutdownLock.notifyAll();
+ }
}
}
diff --git a/src/jogl/classes/com/jogamp/gluegen/opengl/BuildComposablePipeline.java b/src/jogl/classes/com/jogamp/gluegen/opengl/BuildComposablePipeline.java
index 9381d318b..9f885e55d 100644
--- a/src/jogl/classes/com/jogamp/gluegen/opengl/BuildComposablePipeline.java
+++ b/src/jogl/classes/com/jogamp/gluegen/opengl/BuildComposablePipeline.java
@@ -391,35 +391,16 @@ public class BuildComposablePipeline {
final PrintWriter output = new PrintWriter(new BufferedWriter(new FileWriter(file)));
- final List<Class<?>> baseInterfaces = Arrays.asList(baseInterfaceClass.getInterfaces());
- final HashSet<Class<?>> clazzList = new HashSet<Class<?>>();
- clazzList.add(baseInterfaceClass);
- clazzList.addAll(baseInterfaces);
- final int ifNamesNumber = clazzList.size();
-
- // keep original order ..
- clazzList.clear();
- final String[] ifNames = new String[ifNamesNumber];
- {
- int i = 0;
-
- for (final Iterator<Class<?>> iter = baseInterfaces.iterator(); iter.hasNext();) {
- final Class<?> ifClass = iter.next();
- if (!clazzList.contains(ifClass)) {
- ifNames[i++] = ifClass.getName();
- clazzList.add(ifClass);
- }
- }
+ final HashSet<Class<?>> importClazzList = new HashSet<Class<?>>();
+ importClazzList.add(baseInterfaceClass);
+ final String[] ifNames = new String[] { baseInterfaceClass.getName() };
- if ( !clazzList.contains(baseInterfaceClass) ) {
- ifNames[i++] = baseInterfaceClass.getName();
- clazzList.add(baseInterfaceClass);
- }
- }
+ final List<Class<?>> baseInterfaces = Arrays.asList(baseInterfaceClass.getInterfaces());
+ importClazzList.addAll(baseInterfaces);
- clazzList.add(downstreamClass);
+ importClazzList.add(downstreamClass);
if (null != prologClassOpt) {
- clazzList.add(prologClassOpt);
+ importClazzList.add(prologClassOpt);
}
final ArrayList<String> imports = new ArrayList<String>();
@@ -427,7 +408,7 @@ public class BuildComposablePipeline {
imports.add("com.jogamp.opengl.*");
imports.add("com.jogamp.gluegen.runtime.*");
imports.add(Buffer.class.getPackage().getName()+".*");
- for (final Class<?> clasS : clazzList) {
+ for (final Class<?> clasS : importClazzList) {
imports.add(clasS.getName());
}
diff --git a/src/jogl/classes/com/jogamp/gluegen/opengl/GLConfiguration.java b/src/jogl/classes/com/jogamp/gluegen/opengl/GLConfiguration.java
index d6f72ee29..1c034ebfb 100644
--- a/src/jogl/classes/com/jogamp/gluegen/opengl/GLConfiguration.java
+++ b/src/jogl/classes/com/jogamp/gluegen/opengl/GLConfiguration.java
@@ -254,6 +254,14 @@ public class GLConfiguration extends ProcAddressConfiguration {
super.logRenames();
}
+ protected boolean isIgnoredExtension(final String extensionName) {
+ if( ignoredExtensions.contains(extensionName) ) {
+ return !forcedExtensions.contains(extensionName);
+ } else {
+ return false;
+ }
+ }
+
protected boolean shouldIgnoreExtension(final AliasedSymbol symbol) {
final Set<String> symExtensionNames;
// collect current-name symbol extensions
diff --git a/src/jogl/classes/com/jogamp/gluegen/opengl/GLEmitter.java b/src/jogl/classes/com/jogamp/gluegen/opengl/GLEmitter.java
index 8df4a9488..a68fc6b2a 100644
--- a/src/jogl/classes/com/jogamp/gluegen/opengl/GLEmitter.java
+++ b/src/jogl/classes/com/jogamp/gluegen/opengl/GLEmitter.java
@@ -112,31 +112,35 @@ public class GLEmitter extends ProcAddressEmitter {
final Set<String> extensionSet = isSemHeader ? config.getExtensionsRenamedIntoCore() : glInfo.getExtensions();
for (final String extension : extensionSet) {
- LOG.log(INFO, "<RenameExtensionIntoCore: {0} BEGIN {1}", extension, headerType);
- final Set<String> declarations = glInfo.getDeclarations(extension);
- if (declarations != null) {
- for (final Iterator<String> iterator = declarations.iterator(); iterator.hasNext();) {
- final String decl = iterator.next();
- final boolean isGLFunction = GLNameResolver.isGLFunction(decl);
- boolean isGLEnumeration = false;
- if (!isGLFunction) {
- isGLEnumeration = GLNameResolver.isGLEnumeration(decl);
- }
- if (isGLFunction || isGLEnumeration) {
- final String renamed = GLNameResolver.normalize(decl, isGLFunction);
- if (!renamed.equals(decl)) {
- if( isSemHeader ) {
- // Sem + Doc
- config.addJavaSymbolRename(decl, renamed);
- } else {
- // Doc only
- config.addJavaDocSymbolRename(decl, renamed);
+ if( isSemHeader && config.isIgnoredExtension(extension) ) {
+ LOG.log(INFO, "<RenameExtensionIntoCore: {0} IGNORED {1}>", extension, headerType);
+ } else {
+ LOG.log(INFO, "<RenameExtensionIntoCore: {0} BEGIN {1}", extension, headerType);
+ final Set<String> declarations = glInfo.getDeclarations(extension);
+ if (declarations != null) {
+ for (final Iterator<String> iterator = declarations.iterator(); iterator.hasNext();) {
+ final String decl = iterator.next();
+ final boolean isGLFunction = GLNameResolver.isGLFunction(decl);
+ boolean isGLEnumeration = false;
+ if (!isGLFunction) {
+ isGLEnumeration = GLNameResolver.isGLEnumeration(decl);
+ }
+ if (isGLFunction || isGLEnumeration) {
+ final String renamed = GLNameResolver.normalize(decl, isGLFunction);
+ if (!renamed.equals(decl)) {
+ if( isSemHeader ) {
+ // Sem + Doc
+ config.addJavaSymbolRename(decl, renamed);
+ } else {
+ // Doc only
+ config.addJavaDocSymbolRename(decl, renamed);
+ }
}
}
}
}
+ LOG.log(INFO, "RenameExtensionIntoCore: {0} END>", extension, headerType);
}
- LOG.log(INFO, "RenameExtensionIntoCore: {0} END>", extension, headerType);
}
}
diff --git a/src/jogl/classes/com/jogamp/gluegen/runtime/opengl/GLNameResolver.java b/src/jogl/classes/com/jogamp/gluegen/runtime/opengl/GLNameResolver.java
index d400381c8..d7e340630 100644
--- a/src/jogl/classes/com/jogamp/gluegen/runtime/opengl/GLNameResolver.java
+++ b/src/jogl/classes/com/jogamp/gluegen/runtime/opengl/GLNameResolver.java
@@ -50,27 +50,30 @@ public class GLNameResolver {
private static final String[] extensionsARB = { "ARB", "GL2", "OES", "KHR", "OML" };
private static final String[] extensionsVEN = { "3DFX",
"AMD",
+ "ANDROID",
"ANGLE",
"ARM",
"APPLE",
"ATI",
"EXT",
+ "FJ",
"HI",
"HP",
"IBM",
"IMG",
+ "INGR",
+ "INTEL",
"MESA",
"MESAX",
"NV",
+ "PGI",
"QCOM",
"SGI",
"SGIS",
"SGIX",
"SUN",
"VIV",
- "WIN"
- };
-
+ "WIN" };
public static final boolean isGLFunction(final String str) {
return str.startsWith("gl") || /* str.startsWith("glu") || str.startsWith("glX") || */
diff --git a/src/jogl/classes/com/jogamp/graph/font/FontFactory.java b/src/jogl/classes/com/jogamp/graph/font/FontFactory.java
index be16e030f..76badcda8 100644
--- a/src/jogl/classes/com/jogamp/graph/font/FontFactory.java
+++ b/src/jogl/classes/com/jogamp/graph/font/FontFactory.java
@@ -199,7 +199,7 @@ public class FontFactory {
throw new IOException(e);
}
} else {
- stream = IOUtil.getResource(context, fname).getInputStream();
+ stream = IOUtil.getResource(fname, context.getClassLoader(), context).getInputStream();
}
if( null != stream ) {
return FontFactory.get ( stream, true ) ;
diff --git a/src/jogl/classes/com/jogamp/opengl/GLAnimatorControl.java b/src/jogl/classes/com/jogamp/opengl/GLAnimatorControl.java
index 549efd569..38b8f770b 100644
--- a/src/jogl/classes/com/jogamp/opengl/GLAnimatorControl.java
+++ b/src/jogl/classes/com/jogamp/opengl/GLAnimatorControl.java
@@ -58,7 +58,8 @@ public interface GLAnimatorControl extends FPSCounter {
* Any exception thrown by this method will be ignored.
* </p>
* @param animator the {@link GLAnimatorControl}
- * @param drawable the causing {@link GLAutoDrawable}
+ * @param drawable the causing {@link GLAutoDrawable},
+ * may be {@code null} in case {@link Throwable} caused unrelated to any {@link GLAutoDrawable}.
* @param cause the uncaught exception
* @see GLAnimatorControl#setUncaughtExceptionHandler(UncaughtExceptionHandler)
* @since 2.2
diff --git a/src/jogl/classes/com/jogamp/opengl/GLBase.java b/src/jogl/classes/com/jogamp/opengl/GLBase.java
index dee5f1488..0cbcbe40f 100644
--- a/src/jogl/classes/com/jogamp/opengl/GLBase.java
+++ b/src/jogl/classes/com/jogamp/opengl/GLBase.java
@@ -237,6 +237,19 @@ public interface GLBase {
public boolean isGLES31Compatible();
/**
+ * Indicates whether this GL object is compatible with the core OpenGL ES3.2 functionality.
+ * <p>
+ * Return true if the underlying context is an ES3 context &ge; 3.2 or implements
+ * the extension <code>GL_ARB_ES3_2_compatibility</code>, otherwise false.
+ * </p>
+ * <p>
+ * Includes [ GL &ge; 4.5, GL &ge; 3.1 w/ GL_ARB_ES3_2_compatibility and GLES3 &ge; 3.2 ]
+ * </p>
+ * @see GLContext#isGLES32Compatible()
+ */
+ public boolean isGLES32Compatible();
+
+ /**
* Indicates whether this GL object supports GLSL.
* @see GLContext#hasGLSL()
*/
@@ -446,29 +459,43 @@ public interface GLBase {
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
- causes the application to wait until the next vertical refresh
- until swapping buffers. The default, which is platform-specific,
- is usually either 0 or 1. This function is not guaranteed to
- have an effect, and in particular only affects heavyweight
- onscreen components.
-
- @see #getSwapInterval
- @throws GLException if this context is not the current
+ /**
+ * Set the swap interval of the current context and attached <i>onscreen {@link GLDrawable}</i>.
+ * <p>
+ * <i>offscreen {@link GLDrawable}</i> are ignored and {@code false} is returned.
+ * </p>
+ * <p>
+ * The {@code interval} semantics:
+ * <ul>
+ * <li><i>0</i> disables the vertical synchronization</li>
+ * <li><i>&ge;1</i> is the number of vertical refreshes before a swap buffer occurs</li>
+ * <li><i>&lt;0</i> enables <i>late swaps to occur without synchronization to the video frame</i>, a.k.a <i>EXT_swap_control_tear</i>.
+ * If supported, the absolute value is the minimum number of
+ * video frames between buffer swaps. If not supported, the absolute value is being used, see above.
+ * </li>
+ * </ul>
+ * </p>
+ * @param interval see above
+ * @return true if the operation was successful, otherwise false
+ * @throws GLException if the context is not current.
+ * @see GLContext#setSwapInterval(int)
+ * @see #getSwapInterval()
*/
- public void setSwapInterval(int interval);
+ public void setSwapInterval(int interval) throws GLException;
- /** Provides a platform-independent way to get the swap
- interval set by {@link #setSwapInterval}. <br>
-
- If the interval is not set by {@link #setSwapInterval} yet,
- -1 is returned, indicating that the platforms default
- is being used.
-
- @see #setSwapInterval
- */
+ /**
+ * Return the current swap interval.
+ * <p>
+ * If the context has not been made current at all,
+ * the default value {@code 0} is returned.
+ * </p>
+ * <p>
+ * For a valid context w/ an <o>onscreen {@link GLDrawable}</i> the default value is {@code 1},
+ * otherwise the default value is {@code 0}.
+ * </p>
+ * @see GLContext#getSwapInterval()
+ * @see #setSwapInterval(int)
+ */
public int getSwapInterval();
/**
@@ -494,12 +521,12 @@ public interface GLBase {
* for accessing it, including which class or interface contains the
* functions.
*
- * <P>
- *
+ * <p>
* Note: it is the intent to add new extensions as quickly as possible
* to the core GL API. Therefore it is unlikely that most vendors will
* use this extension mechanism, but it is being provided for
* completeness.
+ * </p>
*/
public Object getExtension(String extensionName);
diff --git a/src/jogl/classes/com/jogamp/opengl/GLContext.java b/src/jogl/classes/com/jogamp/opengl/GLContext.java
index f68c029df..606e4b4ed 100644
--- a/src/jogl/classes/com/jogamp/opengl/GLContext.java
+++ b/src/jogl/classes/com/jogamp/opengl/GLContext.java
@@ -198,16 +198,19 @@ public abstract class GLContext {
/** <code>GL_ARB_ES3_compatibility</code> implementation related: Context is compatible w/ ES3. Not a cache key. See {@link #isGLES3Compatible()}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */
protected static final int CTX_IMPL_ES3_COMPAT = 1 << 11;
- /** <code>GL_ARB_ES3_1_compatibility</code> implementation related: Context is compatible w/ ES3. Not a cache key. See {@link #isGLES31Compatible()}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */
+ /** <code>GL_ARB_ES3_1_compatibility</code> implementation related: Context is compatible w/ ES 3.1. Not a cache key. See {@link #isGLES31Compatible()}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */
protected static final int CTX_IMPL_ES31_COMPAT = 1 << 12;
+ /** <code>GL_ARB_ES3_2_compatibility</code> implementation related: Context is compatible w/ ES 3.2. Not a cache key. See {@link #isGLES32Compatible()}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */
+ protected static final int CTX_IMPL_ES32_COMPAT = 1 << 13;
+
/**
* Context supports basic FBO, details see {@link #hasBasicFBOSupport()}.
* Not a cache key.
* @see #hasBasicFBOSupport()
* @see #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)
*/
- protected static final int CTX_IMPL_FBO = 1 << 13;
+ protected static final int CTX_IMPL_FBO = 1 << 14;
/**
* Context supports <code>OES_single_precision</code>, fp32, fixed function point (FFP) compatibility entry points,
@@ -216,7 +219,7 @@ public abstract class GLContext {
* @see #hasFP32CompatAPI()
* @see #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)
*/
- protected static final int CTX_IMPL_FP32_COMPAT_API = 1 << 14;
+ protected static final int CTX_IMPL_FP32_COMPAT_API = 1 << 15;
private static final ThreadLocal<GLContext> currentContext = new ThreadLocal<GLContext>();
@@ -237,7 +240,6 @@ public abstract class GLContext {
protected String ctxVersionString;
protected VersionNumberString ctxVendorVersion;
protected VersionNumber ctxGLSLVersion;
- private int currentSwapInterval;
protected GLRendererQuirks glRendererQuirks;
/** Did the drawable association changed ? see {@link GLRendererQuirks#NoSetSwapIntervalPostRetarget} */
@@ -258,7 +260,6 @@ public abstract class GLContext {
ctxGLSLVersion = VersionNumber.zeroVersion;
attachedObjects.clear();
contextHandle=0;
- currentSwapInterval = -1;
glRendererQuirks = null;
drawableRetargeted = false;
}
@@ -925,6 +926,17 @@ public abstract class GLContext {
}
/**
+ * Return true if this context is an ES3 context &ge; 3.2 or implements
+ * the extension <code>GL_ARB_ES3_2_compatibility</code>, otherwise false.
+ * <p>
+ * Includes [ GL &ge; 4.5, GL &ge; 3.1 w/ GL_ARB_ES3_2_compatibility and GLES3 &ge; 3.2 ]
+ * </p>
+ */
+ public final boolean isGLES32Compatible() {
+ return 0 != ( ctxOptions & CTX_IMPL_ES32_COMPAT ) ;
+ }
+
+ /**
* @return true if impl. is a hardware rasterizer, otherwise false.
* @see #isHardwareRasterizer(AbstractGraphicsDevice, GLProfile)
* @see GLProfile#isHardwareRasterizer()
@@ -1182,8 +1194,9 @@ public abstract class GLContext {
if( 0 != ( ctxOptions & CTX_PROFILE_ES ) ) {
final int major = ctxVersion.getMajor();
return 2 == major || 3 == major;
+ } else {
+ return false;
}
- return false;
}
/**
@@ -1246,49 +1259,55 @@ public abstract class GLContext {
}
/**
- * Set the swap interval of the current context and attached drawable.
- * @param interval Should be &ge; 0. 0 disables the vertical synchronization,
- * where &ge; 1 is the number of vertical refreshes before a swap buffer occurs.
- * A value &lt; 0 is ignored.
+ * Set the swap interval of the current context and attached <i>onscreen {@link GLDrawable}</i>.
+ * <p>
+ * <i>offscreen {@link GLDrawable}</i> are ignored and {@code false} is returned.
+ * </p>
+ * <p>
+ * The {@code interval} semantics:
+ * <ul>
+ * <li><i>0</i> disables the vertical synchronization</li>
+ * <li><i>&ge;1</i> is the number of vertical refreshes before a swap buffer occurs</li>
+ * <li><i>&lt;0</i> enables <i>late swaps to occur without synchronization to the video frame</i>, a.k.a <i>EXT_swap_control_tear</i>.
+ * If supported, the absolute value is the minimum number of
+ * video frames between buffer swaps. If not supported, the absolute value is being used, see above.
+ * </li>
+ * </ul>
+ * </p>
+ * @param interval see above
* @return true if the operation was successful, otherwise false
- *
* @throws GLException if the context is not current.
+ * @see #getSwapInterval()
*/
- public final boolean setSwapInterval(final int interval) throws GLException {
- validateCurrent();
- if(0<=interval) {
- if( !drawableRetargeted || !hasRendererQuirk(GLRendererQuirks.NoSetSwapIntervalPostRetarget) ) {
- if( setSwapIntervalImpl(interval) ) {
- currentSwapInterval = interval;
- return true;
- }
- }
- }
- return false;
+ public /* abstract */ boolean setSwapInterval(final int interval) throws GLException {
+ // FIXME: Make abstract for next version - just here to *not* break SEMVER!
+ throw new InternalError("Implemented in GLContextImpl");
}
protected boolean setSwapIntervalImpl(final int interval) {
- return false;
+ // FIXME: Remove for next version - just here to *not* break SEMVER!
+ throw new InternalError("Implemented in GLContextImpl");
}
- /** Return the current swap interval.
+
+ /**
+ * Return the current swap interval.
* <p>
* If the context has not been made current at all,
- * the default value <code>-1</code> is returned.
+ * the default value {@code 0} is returned.
* </p>
* <p>
- * 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.
+ * For a valid context w/ an <o>onscreen {@link GLDrawable}</i> the default value is {@code 1},
+ * otherwise the default value is {@code 0}.
* </p>
+ * @see #setSwapInterval(int)
*/
- public final int getSwapInterval() {
- return currentSwapInterval;
+ public /* abstract */ int getSwapInterval() {
+ // FIXME: Make abstract for next version - just here to *not* break SEMVER!
+ throw new InternalError("Implemented in GLContextImpl");
}
- protected final void setDefaultSwapInterval() {
- if(this.isGLES()) {
- currentSwapInterval = 1;
- } else {
- currentSwapInterval = -1;
- }
+
+ protected void setDefaultSwapInterval() {
+ // FIXME: Remove for next version - just here to *not* break SEMVER!
+ throw new InternalError("Implemented in GLContextImpl");
}
public final boolean queryMaxSwapGroups(final int[] maxGroups, final int maxGroups_offset,
@@ -1492,7 +1511,7 @@ public abstract class GLContext {
/* 0.*/ { -1 },
/* 1.*/ { 0, 1 },
/* 2.*/ { 0 },
- /* 3.*/ { 0, 1 } };
+ /* 3.*/ { 0, 1, 2 } };
public static final int getMaxMajor(final int ctxProfile) {
return ( 0 != ( CTX_PROFILE_ES & ctxProfile ) ) ? ES_VERSIONS.length-1 : GL_VERSIONS.length-1;
@@ -1613,8 +1632,14 @@ public abstract class GLContext {
( ( b8 & 0x000000FF ) << 16 ) |
( ( c16 & 0x0000FFFF ) ) ;
}
+ protected static VersionNumber decomposeBits(final int bits32, final int[] ctp) {
+ final int major = ( bits32 & 0xFF000000 ) >>> 24 ;
+ final int minor = ( bits32 & 0x00FF0000 ) >>> 16 ;
+ ctp[0] = ( bits32 & 0x0000FFFF ) ;
+ return new VersionNumber(major, minor, 0);
+ }
- private static void validateProfileBits(final int bits, final String argName) {
+ protected static void validateProfileBits(final int bits, final String argName) {
int num = 0;
if( 0 != ( CTX_PROFILE_COMPAT & bits ) ) { num++; }
if( 0 != ( CTX_PROFILE_CORE & bits ) ) { num++; }
@@ -1660,7 +1685,7 @@ public abstract class GLContext {
deviceVersionsAvailableSet.remove(devKey);
}
if (DEBUG) {
- System.err.println(getThreadName() + ": createContextARB: SET mappedVersionsAvailableSet "+devKey);
+ System.err.println(getThreadName() + ": createContextARB-MapGLVersions SET "+devKey);
System.err.println(GLContext.dumpAvailableGLVersions(null).toString());
}
}
@@ -1675,38 +1700,6 @@ public abstract class GLContext {
return r.intern();
}
- /**
- * Called by {@link jogamp.opengl.GLContextImpl#createContextARBMapVersionsAvailable(int,int)} not intended to be used by
- * implementations. However, if {@link jogamp.opengl.GLContextImpl#createContextARB(long, boolean)} is not being used within
- * {@link com.jogamp.opengl.GLDrawableFactory#getOrCreateSharedContext(com.jogamp.nativewindow.AbstractGraphicsDevice)},
- * GLProfile has to map the available versions.
- *
- * @param reqMajor Key Value either 1, 2, 3 or 4
- * @param profile Key Value either {@link #CTX_PROFILE_COMPAT}, {@link #CTX_PROFILE_CORE} or {@link #CTX_PROFILE_ES}
- * @return the old mapped value
- *
- * @see #createContextARBMapVersionsAvailable
- */
- protected static Integer mapAvailableGLVersion(final AbstractGraphicsDevice device,
- final int reqMajor, final int profile, final int resMajor, final int resMinor, int resCtp)
- {
- 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();
- }
- final String objectKey = getDeviceVersionAvailableKey(device, reqMajor, profile);
- final Integer val = Integer.valueOf(composeBits(resMajor, resMinor, resCtp));
- synchronized(deviceVersionAvailable) {
- return deviceVersionAvailable.put( objectKey, val );
- }
- }
-
protected static StringBuilder dumpAvailableGLVersions(StringBuilder sb) {
if(null == sb) {
sb = new StringBuilder();
@@ -1714,19 +1707,17 @@ public abstract class GLContext {
synchronized(deviceVersionAvailable) {
final Set<String> keys = deviceVersionAvailable.keySet();
boolean needsSeparator = false;
- for(final Iterator<String> i = keys.iterator(); i.hasNext(); ) {
+ for(final Iterator<String> keyI = keys.iterator(); keyI.hasNext(); ) {
if(needsSeparator) {
sb.append(Platform.getNewline());
}
- final String key = i.next();
- sb.append(key).append(": ");
+ final String key = keyI.next();
+ sb.append("MapGLVersions ").append(key).append(": ");
final Integer valI = deviceVersionAvailable.get(key);
if(null != valI) {
- final int bits32 = valI.intValue();
- final int major = ( bits32 & 0xFF000000 ) >>> 24 ;
- final int minor = ( bits32 & 0x00FF0000 ) >>> 16 ;
- final int ctp = ( bits32 & 0x0000FFFF ) ;
- sb.append(GLContext.getGLVersion(major, minor, ctp, null));
+ final int[] ctp = { 0 };
+ final VersionNumber version = decomposeBits(valI.intValue(), ctp);
+ GLContext.getGLVersion(sb, version, ctp[0], null);
} else {
sb.append("n/a");
}
@@ -1949,15 +1940,7 @@ public abstract class GLContext {
return isGLVersionAvailable(device, 3, GLContext.CTX_PROFILE_ES, isHardware);
}
- /**
- * Returns true if a ES3 compatible profile is available,
- * i.e. either a &ge; 4.3 context or a &ge; 3.1 context supporting <code>GL_ARB_ES3_compatibility</code>,
- * otherwise false.
- * <p>
- * Includes [ GL &ge; 4.3, GL &ge; 3.1 w/ GL_ARB_ES3_compatibility and GLES3 ]
- * </p>
- */
- public static final boolean isGLES3CompatibleAvailable(final AbstractGraphicsDevice device) {
+ private static final int getGL3ctp(final AbstractGraphicsDevice device) {
final int major[] = { 0 };
final int minor[] = { 0 };
final int ctp[] = { 0 };
@@ -1970,7 +1953,19 @@ public abstract class GLContext {
if( !ok ) {
GLContext.getAvailableGLVersion(device, 3, GLContext.CTX_PROFILE_COMPAT, major, minor, ctp);
}
- return 0 != ( ctp[0] & CTX_IMPL_ES3_COMPAT );
+ return ctp[0];
+ }
+
+ /**
+ * Returns true if a ES3 compatible profile is available,
+ * i.e. either a &ge; 4.3 context or a &ge; 3.1 context supporting <code>GL_ARB_ES3_compatibility</code>,
+ * otherwise false.
+ * <p>
+ * Includes [ GL &ge; 4.3, GL &ge; 3.1 w/ GL_ARB_ES3_compatibility and GLES3 ]
+ * </p>
+ */
+ public static final boolean isGLES3CompatibleAvailable(final AbstractGraphicsDevice device) {
+ return 0 != ( getGL3ctp(device) & CTX_IMPL_ES3_COMPAT );
}
/**
* Returns true if a ES3 &ge; 3.1 compatible profile is available,
@@ -1981,19 +1976,18 @@ public abstract class GLContext {
* </p>
*/
public static final boolean isGLES31CompatibleAvailable(final AbstractGraphicsDevice device) {
- final int major[] = { 0 };
- final int minor[] = { 0 };
- final int ctp[] = { 0 };
- boolean ok;
-
- ok = GLContext.getAvailableGLVersion(device, 3, GLContext.CTX_PROFILE_ES, major, minor, ctp);
- if( !ok ) {
- ok = GLContext.getAvailableGLVersion(device, 3, GLContext.CTX_PROFILE_CORE, major, minor, ctp);
- }
- if( !ok ) {
- GLContext.getAvailableGLVersion(device, 3, GLContext.CTX_PROFILE_COMPAT, major, minor, ctp);
- }
- return 0 != ( ctp[0] & CTX_IMPL_ES31_COMPAT );
+ return 0 != ( getGL3ctp(device) & CTX_IMPL_ES31_COMPAT );
+ }
+ /**
+ * Returns true if a ES3 &ge; 3.2 compatible profile is available,
+ * i.e. either a &ge; 4.5 context or a &ge; 3.1 context supporting <code>GL_ARB_ES3_2_compatibility</code>,
+ * otherwise false.
+ * <p>
+ * Includes [ GL &ge; 4.5, GL &ge; 3.1 w/ GL_ARB_ES3_2_compatibility and GLES3 &ge; 3.2 ]
+ * </p>
+ */
+ public static final boolean isGLES32CompatibleAvailable(final AbstractGraphicsDevice device) {
+ return 0 != ( getGL3ctp(device) & CTX_IMPL_ES32_COMPAT );
}
public static boolean isGL4bcAvailable(final AbstractGraphicsDevice device, final boolean isHardware[]) {
@@ -2016,13 +2010,8 @@ public abstract class GLContext {
return isGLVersionAvailable(device, 2, CTX_PROFILE_COMPAT, isHardware);
}
- protected static String getGLVersion(final int major, final int minor, final int ctp, final String gl_version) {
+ protected static StringBuilder getGLProfile(final StringBuilder sb, final int ctp) {
boolean needColon = false;
- final StringBuilder sb = new StringBuilder();
- sb.append(major);
- sb.append(".");
- sb.append(minor);
- sb.append(" (");
needColon = appendString(sb, "ES profile", needColon, 0 != ( CTX_PROFILE_ES & ctp ));
needColon = appendString(sb, "Compat profile", needColon, 0 != ( CTX_PROFILE_COMPAT & ctp ));
needColon = appendString(sb, "Core profile", needColon, 0 != ( CTX_PROFILE_CORE & ctp ));
@@ -2035,6 +2024,7 @@ public abstract class GLContext {
needColon = appendString(sb, "ES2", needColon, 0 != ( CTX_IMPL_ES2_COMPAT & ctp ));
needColon = appendString(sb, "ES3", needColon, 0 != ( CTX_IMPL_ES3_COMPAT & ctp ));
needColon = appendString(sb, "ES31", needColon, 0 != ( CTX_IMPL_ES31_COMPAT & ctp ));
+ needColon = appendString(sb, "ES32", needColon, 0 != ( CTX_IMPL_ES32_COMPAT & ctp ));
needColon = appendString(sb, "FP32", needColon, 0 != ( CTX_IMPL_FP32_COMPAT_API & ctp ));
needColon = false;
}
@@ -2045,12 +2035,26 @@ public abstract class GLContext {
} else {
needColon = appendString(sb, "hardware", needColon, true);
}
+ return sb;
+ }
+ protected static StringBuilder getGLVersion(final StringBuilder sb, final VersionNumber version, final int ctp, final String gl_version) {
+ return getGLVersion(sb, version.getMajor(), version.getMinor(), ctp, gl_version);
+ }
+ protected static StringBuilder getGLVersion(final StringBuilder sb, final int major, final int minor, final int ctp, final String gl_version) {
+ sb.append(major);
+ sb.append(".");
+ sb.append(minor);
+ sb.append(" (");
+ getGLProfile(sb, ctp);
sb.append(")");
if(null!=gl_version) {
sb.append(" - ");
sb.append(gl_version);
}
- return sb.toString();
+ return sb;
+ }
+ protected static String getGLVersion(final int major, final int minor, final int ctp, final String gl_version) {
+ return getGLVersion(new StringBuilder(), major, minor, ctp, gl_version).toString();
}
//
diff --git a/src/jogl/classes/com/jogamp/opengl/GLDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/GLDrawableFactory.java
index 7d78e3409..51da34ce0 100644
--- a/src/jogl/classes/com/jogamp/opengl/GLDrawableFactory.java
+++ b/src/jogl/classes/com/jogamp/opengl/GLDrawableFactory.java
@@ -421,6 +421,18 @@ public abstract class GLDrawableFactory {
public abstract GLRendererQuirks getRendererQuirks(AbstractGraphicsDevice device, final GLProfile glp);
/**
+ * Method returns {@code true} if underlying implementation may support native desktop OpenGL,
+ * otherwise {@code false}.
+ */
+ public abstract boolean hasOpenGLDesktopSupport();
+
+ /**
+ * Method returns {@code true} if underlying implementation may support native embedded OpenGL ES,
+ * otherwise {@code false}.
+ */
+ public abstract boolean hasOpenGLESSupport();
+
+ /**
* Returns the sole GLDrawableFactory instance for the desktop (X11, WGL, ..) if exist or null
*/
public static GLDrawableFactory getDesktopFactory() {
diff --git a/src/jogl/classes/com/jogamp/opengl/GLExtensions.java b/src/jogl/classes/com/jogamp/opengl/GLExtensions.java
index 1bf8071ea..23e7dec31 100644
--- a/src/jogl/classes/com/jogamp/opengl/GLExtensions.java
+++ b/src/jogl/classes/com/jogamp/opengl/GLExtensions.java
@@ -36,6 +36,7 @@ public class GLExtensions {
public static final String VERSION_1_5 = "GL_VERSION_1_5";
public static final String VERSION_2_0 = "GL_VERSION_2_0";
+ public static final String GL_KHR_debug = "GL_KHR_debug";
public static final String ARB_debug_output = "GL_ARB_debug_output";
public static final String AMD_debug_output = "GL_AMD_debug_output";
@@ -53,6 +54,7 @@ public class GLExtensions {
public static final String ARB_ES2_compatibility = "GL_ARB_ES2_compatibility";
public static final String ARB_ES3_compatibility = "GL_ARB_ES3_compatibility";
public static final String ARB_ES3_1_compatibility = "GL_ARB_ES3_1_compatibility";
+ public static final String ARB_ES3_2_compatibility = "GL_ARB_ES3_2_compatibility";
public static final String EXT_abgr = "GL_EXT_abgr";
public static final String OES_rgb8_rgba8 = "GL_OES_rgb8_rgba8";
diff --git a/src/jogl/classes/com/jogamp/opengl/GLProfile.java b/src/jogl/classes/com/jogamp/opengl/GLProfile.java
index a36a21ad5..520db78ad 100644
--- a/src/jogl/classes/com/jogamp/opengl/GLProfile.java
+++ b/src/jogl/classes/com/jogamp/opengl/GLProfile.java
@@ -39,6 +39,7 @@ package com.jogamp.opengl;
import jogamp.opengl.Debug;
import jogamp.opengl.GLDrawableFactoryImpl;
+import jogamp.opengl.GLDynamicLookupHelper;
import jogamp.opengl.DesktopGLDynamicLookupHelper;
import com.jogamp.common.ExceptionUtils;
@@ -242,7 +243,7 @@ public class GLProfile {
initLock.unlock();
}
if(DEBUG) {
- if( justInitialized && ( hasGL234Impl || hasGLES1Impl || hasGLES3Impl ) ) {
+ if( justInitialized && ( hasGL234Impl || hasGL234OnEGLImpl || hasGLES1Impl || hasGLES3Impl ) ) {
System.err.println(JoglVersion.getDefaultOpenGLInfo(defaultDevice, null, true));
}
}
@@ -1629,6 +1630,7 @@ public class GLProfile {
private static /*final*/ boolean hasEGLFactory;
private static /*final*/ boolean hasGLES3Impl;
private static /*final*/ boolean hasGLES1Impl;
+ private static /*final*/ boolean hasGL234OnEGLImpl;
private static /*final*/ Constructor<?> ctorGL234Impl;
private static /*final*/ Constructor<?> ctorGLES3Impl;
private static /*final*/ Constructor<?> ctorGLES1Impl;
@@ -1681,6 +1683,7 @@ public class GLProfile {
ctorGL234ProcAddr = null;
}
}
+ hasGL234OnEGLImpl = hasGL234Impl;
// depends on hasEGLFactory
{
@@ -1745,10 +1748,9 @@ public class GLProfile {
try {
desktopFactory = (GLDrawableFactoryImpl) GLDrawableFactory.getFactoryImpl(GL2);
if(null != desktopFactory) {
- final DesktopGLDynamicLookupHelper glLookupHelper = (DesktopGLDynamicLookupHelper) desktopFactory.getGLDynamicLookupHelper(GL2);
- if(null!=glLookupHelper) {
- hasDesktopGLFactory = glLookupHelper.isLibComplete() && hasGL234Impl;
- }
+ final DesktopGLDynamicLookupHelper glLookupHelper = (DesktopGLDynamicLookupHelper) desktopFactory.getGLDynamicLookupHelper(2, GLContext.CTX_PROFILE_COMPAT);
+ hasGL234Impl = null!=glLookupHelper && glLookupHelper.isLibComplete() && hasGL234Impl;
+ hasDesktopGLFactory = hasGL234Impl;
}
} catch (final LinkageError le) {
t=le;
@@ -1780,10 +1782,14 @@ public class GLProfile {
try {
eglFactory = (GLDrawableFactoryImpl) GLDrawableFactory.getFactoryImpl(GLES2);
if(null != eglFactory) {
- hasEGLFactory = true;
- // update hasGLES1Impl, hasGLES3Impl based on EGL
- hasGLES3Impl = null!=eglFactory.getGLDynamicLookupHelper(GLES2) && hasGLES3Impl;
- hasGLES1Impl = null!=eglFactory.getGLDynamicLookupHelper(GLES1) && hasGLES1Impl;
+ // update hasGLES1Impl, hasGLES3Impl, hasGL234OnEGLImpl based on library completion
+ final GLDynamicLookupHelper es2DynLookup = eglFactory.getGLDynamicLookupHelper(2, GLContext.CTX_PROFILE_ES);
+ final GLDynamicLookupHelper es1DynLookup = eglFactory.getGLDynamicLookupHelper(1, GLContext.CTX_PROFILE_ES);
+ final GLDynamicLookupHelper glXDynLookup = eglFactory.getGLDynamicLookupHelper(3, GLContext.CTX_PROFILE_CORE);
+ hasGLES3Impl = null!=es2DynLookup && es2DynLookup.isLibComplete() && hasGLES3Impl;
+ hasGLES1Impl = null!=es1DynLookup && es1DynLookup.isLibComplete() && hasGLES1Impl;
+ hasGL234OnEGLImpl = null!=glXDynLookup && glXDynLookup.isLibComplete() && hasGL234OnEGLImpl;
+ hasEGLFactory = hasGLES3Impl || hasGLES1Impl || hasGL234OnEGLImpl;
}
} catch (final LinkageError le) {
t=le;
@@ -1803,6 +1809,8 @@ public class GLProfile {
final AbstractGraphicsDevice defaultEGLDevice;
if(null == eglFactory) {
+ hasEGLFactory = false;
+ hasGL234OnEGLImpl= false;
hasGLES3Impl = false;
hasGLES1Impl = false;
defaultEGLDevice = null;
@@ -1843,6 +1851,7 @@ public class GLProfile {
System.err.println("GLProfile.init hasEGLFactory "+hasEGLFactory);
System.err.println("GLProfile.init hasGLES1Impl "+hasGLES1Impl);
System.err.println("GLProfile.init hasGLES3Impl "+hasGLES3Impl);
+ System.err.println("GLProfile.init hasGL234OnEGLImpl "+hasGL234OnEGLImpl);
System.err.println("GLProfile.init defaultDevice "+defaultDevice);
System.err.println("GLProfile.init defaultDevice Desktop "+defaultDesktopDevice);
System.err.println("GLProfile.init defaultDevice EGL "+defaultEGLDevice);
@@ -1887,7 +1896,9 @@ public class GLProfile {
return null != map.get(GL_DEFAULT);
}
+ HashMap<String, GLProfile> mappedDesktopProfiles = null;
boolean addedDesktopProfile = false;
+ HashMap<String, GLProfile> mappedEGLProfiles = null;
boolean addedEGLProfile = false;
final boolean deviceIsDesktopCompatible = hasDesktopGLFactory && desktopFactory.getIsDeviceCompatible(device);
@@ -1906,21 +1917,23 @@ public class GLProfile {
if(null != sharedResourceThread) {
initLock.removeOwner(sharedResourceThread);
}
- if (DEBUG) {
- System.err.println("GLProfile.initProfilesForDevice: "+device+": desktop Shared Ctx "+desktopSharedCtxAvail);
- }
- if(!desktopSharedCtxAvail) {
- hasDesktopGLFactory = false;
- } else if( !GLContext.getAvailableGLVersionsSet(device) ) {
- throw new InternalError("Available GLVersions not set");
+ if( desktopSharedCtxAvail ) {
+ if( !GLContext.getAvailableGLVersionsSet(device) ) {
+ throw new InternalError("Available GLVersions not set for "+device);
+ }
+ mappedDesktopProfiles = computeProfileMap(device, false /* desktopCtxUndef*/, false /* esCtxUndef */);
+ addedDesktopProfile = mappedDesktopProfiles.size() > 0;
+ if (DEBUG) {
+ System.err.println("GLProfile.initProfilesForDevice: "+device+": desktop Shared Ctx "+desktopSharedCtxAvail+
+ ", profiles: "+(addedDesktopProfile ? mappedDesktopProfiles.size() : 0));
+ }
}
- addedDesktopProfile = computeProfileMap(device, false /* desktopCtxUndef*/, false /* esCtxUndef */);
}
final boolean deviceIsEGLCompatible = hasEGLFactory && eglFactory.getIsDeviceCompatible(device);
// also test GLES1, GLES2 and GLES3 on desktop, since we have implementations / emulations available.
- if( deviceIsEGLCompatible && ( hasGLES3Impl || hasGLES1Impl ) ) {
+ if( deviceIsEGLCompatible ) {
// 1st pretend we have all EGL profiles ..
computeProfileMap(device, true /* desktopCtxUndef*/, true /* esCtxUndef */);
@@ -1934,18 +1947,17 @@ public class GLProfile {
if(null != sharedResourceThread) {
initLock.removeOwner(sharedResourceThread);
}
- if(!eglSharedCtxAvail) {
- // Remark: On Windows there is a libEGL.dll delivered w/ Chrome 15.0.874.121m and Firefox 8.0.1
- // but it seems even EGL.eglInitialize(eglDisplay, null, null)
- // fails in some scenarios (eg VirtualBox 4.1.6) w/ EGL error 0x3001 (EGL_NOT_INITIALIZED).
- hasEGLFactory = false;
- hasGLES3Impl = false;
- hasGLES1Impl = false;
+ if( eglSharedCtxAvail ) {
+ if( !GLContext.getAvailableGLVersionsSet(device) ) {
+ throw new InternalError("Available GLVersions not set for "+device);
+ }
+ mappedEGLProfiles = computeProfileMap(device, false /* desktopCtxUndef*/, false /* esCtxUndef */);
+ addedEGLProfile = mappedEGLProfiles.size() > 0;
}
if (DEBUG) {
- System.err.println("GLProfile.initProfilesForDevice: "+device+": egl Shared Ctx "+eglSharedCtxAvail);
+ System.err.println("GLProfile.initProfilesForDevice: "+device+": egl Shared Ctx "+eglSharedCtxAvail+
+ ", profiles: "+(addedEGLProfile ? mappedEGLProfiles.size() : 0));
}
- addedEGLProfile = computeProfileMap(device, false /* desktopCtxUndef*/, false /* esCtxUndef */);
}
if( !addedDesktopProfile && !addedEGLProfile ) {
@@ -1959,13 +1971,22 @@ public class GLProfile {
System.err.println("GLProfile: hasGLES1Impl "+hasGLES1Impl);
System.err.println("GLProfile: hasGLES3Impl "+hasGLES3Impl);
}
+ } else {
+ final HashMap<String, GLProfile> mappedAllProfiles = new HashMap<String, GLProfile>();
+ if( addedEGLProfile ) {
+ mappedAllProfiles.putAll(mappedEGLProfiles);
+ }
+ if( addedDesktopProfile ) {
+ mappedAllProfiles.putAll(mappedDesktopProfiles);
+ }
+ setProfileMap(device, mappedAllProfiles); // union
}
GLContext.setAvailableGLVersionsSet(device, true);
if (DEBUG) {
- System.err.println("GLProfile.initProfilesForDevice: "+device.getConnection()+": added profile(s): desktop "+addedDesktopProfile+", egl "+addedEGLProfile);
- System.err.println("GLProfile.initProfilesForDevice: "+device.getConnection()+": "+glAvailabilityToString(device));
+ System.err.println("GLProfile.initProfilesForDevice: "+device.getUniqueID()+": added profile(s): desktop "+addedDesktopProfile+", egl "+addedEGLProfile);
+ System.err.println("GLProfile.initProfilesForDevice: "+device.getUniqueID()+": "+glAvailabilityToString(device));
if(addedDesktopProfile) {
dumpGLInfo(desktopFactory, device);
final List<GLCapabilitiesImmutable> availCaps = desktopFactory.getAvailableCapabilities(device);
@@ -1996,6 +2017,9 @@ public class GLProfile {
}
} else {
System.err.println("GLProfile.dumpGLInfo: shared context n/a");
+ System.err.println(device.getClass().getSimpleName()+"[type "+
+ device.getType()+", connection "+device.getConnection()+"]:");
+ System.err.println(GLProfile.glAvailabilityToString(device, null, "\t", 1).toString());
}
}
@@ -2026,9 +2050,9 @@ public class GLProfile {
sb.append("]");
}
- private static boolean computeProfileMap(final AbstractGraphicsDevice device, final boolean desktopCtxUndef, final boolean esCtxUndef) {
+ private static HashMap<String, GLProfile> computeProfileMap(final AbstractGraphicsDevice device, final boolean desktopCtxUndef, final boolean esCtxUndef) {
if (DEBUG) {
- System.err.println("GLProfile.init map "+device.getConnection()+", desktopCtxUndef "+desktopCtxUndef+", esCtxUndef "+esCtxUndef);
+ System.err.println("GLProfile.init map "+device.getUniqueID()+", desktopCtxUndef "+desktopCtxUndef+", esCtxUndef "+esCtxUndef);
}
final boolean isHardwareRasterizer[] = new boolean[1];
GLProfile defaultGLProfileAny = null;
@@ -2050,22 +2074,22 @@ public class GLProfile {
}
_mappedProfiles.put(profile, glProfile);
if (DEBUG) {
- System.err.println("GLProfile.init map "+glProfile+" on device "+device.getConnection());
+ System.err.println("GLProfile.init map "+glProfile+" on device "+device.getUniqueID());
}
if( null == defaultGLProfileHW && isHardwareRasterizer[0] ) {
defaultGLProfileHW=glProfile;
if (DEBUG) {
- System.err.println("GLProfile.init map defaultHW "+glProfile+" on device "+device.getConnection());
+ System.err.println("GLProfile.init map defaultHW "+glProfile+" on device "+device.getUniqueID());
}
} else if( null == defaultGLProfileAny ) {
defaultGLProfileAny=glProfile;
if (DEBUG) {
- System.err.println("GLProfile.init map defaultAny "+glProfile+" on device "+device.getConnection());
+ System.err.println("GLProfile.init map defaultAny "+glProfile+" on device "+device.getUniqueID());
}
}
} else {
if (DEBUG) {
- System.err.println("GLProfile.init map *** no mapping for "+profile+" on device "+device.getConnection());
+ System.err.println("GLProfile.init map *** no mapping for "+profile+" on device "+device.getUniqueID());
}
}
}
@@ -2075,13 +2099,14 @@ public class GLProfile {
_mappedProfiles.put(GL_DEFAULT, defaultGLProfileAny);
}
setProfileMap(device, _mappedProfiles);
- return _mappedProfiles.size() > 0;
+ return _mappedProfiles;
}
/**
* Returns the profile implementation
*/
private static String computeProfileImpl(final AbstractGraphicsDevice device, final String profile, final boolean desktopCtxUndef, final boolean esCtxUndef, final boolean isHardwareRasterizer[]) {
+ final boolean hasAnyGL234Impl = hasGL234Impl || hasGL234OnEGLImpl;
final boolean hardwareRasterizer[] = new boolean[1];
if ( GL2ES1 == profile ) {
final boolean gles1Available;
@@ -2093,7 +2118,7 @@ public class GLProfile {
gles1Available = false;
gles1HWAvailable = false;
}
- if(hasGL234Impl) {
+ if( hasAnyGL234Impl ) {
final boolean gl3bcAvailable = GLContext.isGL3bcAvailable(device, hardwareRasterizer);
final boolean gl3bcHWAvailable = gl3bcAvailable && hardwareRasterizer[0] ;
final boolean gl2Available = GLContext.isGL2Available(device, hardwareRasterizer);
@@ -2132,7 +2157,7 @@ public class GLProfile {
gles3Available = false;
gles3HWAvailable = false;
}
- if( hasGL234Impl ) {
+ if( hasAnyGL234Impl ) {
final boolean gl4bcAvailable = GLContext.isGL4bcAvailable(device, hardwareRasterizer);
final boolean gl4bcHWAvailable = gl4bcAvailable && hardwareRasterizer[0] ;
final boolean gl3Available = GLContext.isGL3Available(device, hardwareRasterizer);
@@ -2179,7 +2204,7 @@ public class GLProfile {
final boolean es3HardwareRasterizer[] = new boolean[1];
final boolean gles3Available = hasGLES3Impl && ( esCtxUndef || GLContext.isGLES3Available(device, es3HardwareRasterizer) );
final boolean gles3HWAvailable = gles3Available && es3HardwareRasterizer[0] ;
- if( hasGL234Impl ) {
+ if( hasAnyGL234Impl ) {
final boolean gl4bcAvailable = GLContext.isGL4bcAvailable(device, hardwareRasterizer);
final boolean gl4bcHWAvailable = gl4bcAvailable && hardwareRasterizer[0] ;
final boolean glAnyHWAvailable = gl4bcHWAvailable ||
@@ -2200,7 +2225,7 @@ public class GLProfile {
}
}
} else if(GL2GL3 == profile) {
- if(hasGL234Impl) {
+ if( hasAnyGL234Impl ) {
final boolean gl4Available = GLContext.isGL4Available(device, hardwareRasterizer);
final boolean gl4HWAvailable = gl4Available && hardwareRasterizer[0] ;
final boolean gl3Available = GLContext.isGL3Available(device, hardwareRasterizer);
@@ -2232,15 +2257,15 @@ public class GLProfile {
return GL2;
}
}
- } else if(GL4bc == profile && hasGL234Impl && ( desktopCtxUndef || GLContext.isGL4bcAvailable(device, isHardwareRasterizer))) {
+ } else if(GL4bc == profile && hasAnyGL234Impl && ( desktopCtxUndef || GLContext.isGL4bcAvailable(device, isHardwareRasterizer))) {
return desktopCtxUndef ? GL4bc : GLContext.getAvailableGLProfileName(device, 4, GLContext.CTX_PROFILE_COMPAT);
- } else if(GL4 == profile && hasGL234Impl && ( desktopCtxUndef || GLContext.isGL4Available(device, isHardwareRasterizer))) {
+ } else if(GL4 == profile && hasAnyGL234Impl && ( desktopCtxUndef || GLContext.isGL4Available(device, isHardwareRasterizer))) {
return desktopCtxUndef ? GL4 : GLContext.getAvailableGLProfileName(device, 4, GLContext.CTX_PROFILE_CORE);
- } else if(GL3bc == profile && hasGL234Impl && ( desktopCtxUndef || GLContext.isGL3bcAvailable(device, isHardwareRasterizer))) {
+ } else if(GL3bc == profile && hasAnyGL234Impl && ( desktopCtxUndef || GLContext.isGL3bcAvailable(device, isHardwareRasterizer))) {
return desktopCtxUndef ? GL3bc : GLContext.getAvailableGLProfileName(device, 3, GLContext.CTX_PROFILE_COMPAT);
- } else if(GL3 == profile && hasGL234Impl && ( desktopCtxUndef || GLContext.isGL3Available(device, isHardwareRasterizer))) {
+ } else if(GL3 == profile && hasAnyGL234Impl && ( desktopCtxUndef || GLContext.isGL3Available(device, isHardwareRasterizer))) {
return desktopCtxUndef ? GL3 : GLContext.getAvailableGLProfileName(device, 3, GLContext.CTX_PROFILE_CORE);
- } else if(GL2 == profile && hasGL234Impl && ( desktopCtxUndef || GLContext.isGL2Available(device, isHardwareRasterizer))) {
+ } else if(GL2 == profile && hasAnyGL234Impl && ( desktopCtxUndef || GLContext.isGL2Available(device, isHardwareRasterizer))) {
return desktopCtxUndef ? GL2 : GLContext.getAvailableGLProfileName(device, 2, GLContext.CTX_PROFILE_COMPAT);
} else if(GLES3 == profile && hasGLES3Impl && ( esCtxUndef || GLContext.isGLES3Available(device, isHardwareRasterizer))) {
return esCtxUndef ? GLES3 : GLContext.getAvailableGLProfileName(device, 3, GLContext.CTX_PROFILE_ES);
diff --git a/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java b/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java
index 55c02d92a..7898566f3 100644
--- a/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java
+++ b/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java
@@ -287,6 +287,7 @@ public class GLRendererQuirks {
* <li>EGL_VERSION 1.4</li>
* <li>GL_VENDOR NVIDIA Corporation</li>
* <li>GL_VERSION OpenGL ES 3.0 331.38 (probably w/ 1st NV EGL lib on x86)</li>
+ * <li>GL_VERSION OpenGL ES 3.1 NVIDIA 355.06 (unstable)</li>
* <li>Platform X11</li>
* <li>CPU Family {@link Platform.CPUFamily#X86}</li>
* </ul>
@@ -393,7 +394,7 @@ public class GLRendererQuirks {
* </p>
*/
public static final int NeedSharedObjectSync = 20;
-
+
/**
* No reliable ARB_create_context implementation,
* even if driver claims otherwise.
@@ -401,8 +402,8 @@ public class GLRendererQuirks {
* Some drivers wrongly claim to support ARB_create_context.
* However, the creation of such context fails:
* <pre>
- * com.jogamp.opengl.GLException: AWT-EventQueue-0: WindowsWGLContex.createContextImpl ctx !ARB, profile > GL2
- * requested (OpenGL >= 3.0.1). Requested: GLProfile[GL3bc/GL3bc.hw], current: 2.1 (Compat profile, FBO, hardware)
+ * com.jogamp.opengl.GLException: AWT-EventQueue-0: WindowsWGLContex.createContextImpl ctx !ARB, profile > GL2
+ * requested (OpenGL >= 3.0.1). Requested: GLProfile[GL3bc/GL3bc.hw], current: 2.1 (Compat profile, FBO, hardware)
* - 2.1.8787
* </pre>
* </p>
diff --git a/src/jogl/classes/com/jogamp/opengl/GLUniformData.java b/src/jogl/classes/com/jogamp/opengl/GLUniformData.java
index 44f7f29c7..55a2e0cf1 100644
--- a/src/jogl/classes/com/jogamp/opengl/GLUniformData.java
+++ b/src/jogl/classes/com/jogamp/opengl/GLUniformData.java
@@ -84,6 +84,7 @@ public class GLUniformData {
public IntBuffer intBufferValue() { return (IntBuffer)data; };
public FloatBuffer floatBufferValue() { return (FloatBuffer)data; };
+ @SuppressWarnings("deprecation")
public StringBuilder toString(StringBuilder sb) {
if(null == sb) {
sb = new StringBuilder();
diff --git a/src/jogl/classes/com/jogamp/opengl/JoglVersion.java b/src/jogl/classes/com/jogamp/opengl/JoglVersion.java
index 7589b3776..560d99025 100644
--- a/src/jogl/classes/com/jogamp/opengl/JoglVersion.java
+++ b/src/jogl/classes/com/jogamp/opengl/JoglVersion.java
@@ -144,8 +144,7 @@ public class JoglVersion extends JogampVersion {
}
sb.append(VersionUtil.SEPERATOR).append(Platform.getNewline());
- sb.append(device.getClass().getSimpleName()).append("[type ")
- .append(device.getType()).append(", connection ").append(device.getConnection()).append("]: ").append(Platform.getNewline());
+ sb.append(device.toString()).append(':').append(Platform.getNewline());
if( withAvailabilityInfo ) {
GLProfile.glAvailabilityToString(device, sb, "\t", 1);
}
diff --git a/src/jogl/classes/com/jogamp/opengl/awt/GLJPanel.java b/src/jogl/classes/com/jogamp/opengl/awt/GLJPanel.java
index 5bf4c106c..20dc71958 100644
--- a/src/jogl/classes/com/jogamp/opengl/awt/GLJPanel.java
+++ b/src/jogl/classes/com/jogamp/opengl/awt/GLJPanel.java
@@ -98,6 +98,7 @@ import jogamp.opengl.awt.AWTTilePainter;
import jogamp.opengl.awt.Java2D;
import jogamp.opengl.util.glsl.GLSLTextureRaster;
+import com.jogamp.common.util.InterruptSource;
import com.jogamp.common.util.PropertyAccess;
import com.jogamp.common.util.awt.AWTEDTExecutor;
import com.jogamp.common.util.locks.LockFactory;
@@ -395,7 +396,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
*/
public final boolean initializeBackend(final boolean offthread) {
if( offthread ) {
- new Thread(getThreadName()+"-GLJPanel_Init") {
+ new InterruptSource.Thread(null, null, getThreadName()+"-GLJPanel_Init") {
public void run() {
if( !isInitialized ) {
initializeBackendImpl();
diff --git a/src/jogl/classes/com/jogamp/opengl/cg/CgDynamicLibraryBundleInfo.java b/src/jogl/classes/com/jogamp/opengl/cg/CgDynamicLibraryBundleInfo.java
index 8f033a8b8..d3f4c002d 100644
--- a/src/jogl/classes/com/jogamp/opengl/cg/CgDynamicLibraryBundleInfo.java
+++ b/src/jogl/classes/com/jogamp/opengl/cg/CgDynamicLibraryBundleInfo.java
@@ -99,6 +99,16 @@ public final class CgDynamicLibraryBundleInfo implements DynamicLibraryBundleInf
}
@Override
+ public final boolean searchToolLibInSystemPath() {
+ return true;
+ }
+
+ @Override
+ public final boolean searchToolLibSystemPathFirst() {
+ return true;
+ }
+
+ @Override
public final List<List<String>> getToolLibNames() {
final List<List<String>> libsList = new ArrayList<List<String>>();
final List<String> libsCg = new ArrayList<String>();
diff --git a/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java b/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java
index 7f630f9d5..d24ca5b7e 100644
--- a/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java
+++ b/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java
@@ -1738,7 +1738,6 @@ public final class FloatUtil {
* @param a 4x4 matrix in column-major order
* @param b 4x4 matrix in column-major order
* @param d result a*b in column-major order
- * @deprecated use on of the float[] variants
*/
public static void multMatrix(final FloatBuffer a, final FloatBuffer b, final float[] d) {
final int a_off = a.position();
@@ -1758,7 +1757,6 @@ public final class FloatUtil {
* Multiply matrix: [a] = [a] x [b]
* @param a 4x4 matrix in column-major order (also result)
* @param b 4x4 matrix in column-major order
- * @deprecated use on of the float[] variants
*/
public static void multMatrix(final FloatBuffer a, final FloatBuffer b) {
final int a_off = a.position();
@@ -1831,7 +1829,6 @@ public final class FloatUtil {
* @param m_in 4x4 matrix in column-major order
* @param v_in 4-component column-vector
* @param v_out m_in * v_in
- * @deprecated use on of the float[] variants
*/
public static void multMatrixVec(final FloatBuffer m_in, final float[] v_in, final float[] v_out) {
final int m_in_off = m_in.position();
@@ -1900,7 +1897,6 @@ public final class FloatUtil {
* @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
- * @deprecated use on of the float[] variants
*/
public static StringBuilder matrixRowToString(StringBuilder sb, final String f,
final FloatBuffer a, final int aOffset,
@@ -1959,7 +1955,6 @@ public final class FloatUtil {
* @param columns
* @param rowMajorOrder if true floats are layed out in row-major-order, otherwise column-major-order (OpenGL)
* @return matrix string representation
- * @deprecated use on of the float[] variants
*/
public static StringBuilder matrixToString(StringBuilder sb, final String rowPrefix, final String f,
final FloatBuffer a, final int aOffset, final int rows, final int columns, final boolean rowMajorOrder) {
@@ -2012,7 +2007,6 @@ public final class FloatUtil {
* @param columns
* @param rowMajorOrder if true floats are layed out in row-major-order, otherwise column-major-order (OpenGL)
* @return side by side representation
- * @deprecated use on of the float[] variants
*/
public static StringBuilder matrixToString(StringBuilder sb, final String rowPrefix, final String f,
final FloatBuffer a, final int aOffset, final FloatBuffer b, final int bOffset,
diff --git a/src/jogl/classes/com/jogamp/opengl/util/AWTAnimatorImpl.java b/src/jogl/classes/com/jogamp/opengl/util/AWTAnimatorImpl.java
index 76d64963f..9e9cc8e44 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/AWTAnimatorImpl.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/AWTAnimatorImpl.java
@@ -56,7 +56,7 @@ import com.jogamp.opengl.util.AnimatorBase.UncaughtAnimatorException;
class AWTAnimatorImpl implements AnimatorBase.AnimatorImpl {
// For efficient rendering of Swing components, in particular when
// they overlap one another
- private final List<JComponent> lightweights = new ArrayList<JComponent>();
+ private final List<JComponent> lightweights = new ArrayList<JComponent>();
private final Map<RepaintManager,RepaintManager> repaintManagers = new IdentityHashMap<RepaintManager,RepaintManager>();
private final Map<JComponent,Rectangle> dirtyRegions = new IdentityHashMap<JComponent,Rectangle>();
@@ -64,34 +64,40 @@ class AWTAnimatorImpl implements AnimatorBase.AnimatorImpl {
public void display(final ArrayList<GLAutoDrawable> drawables,
final boolean ignoreExceptions,
final boolean printExceptions) throws UncaughtAnimatorException {
- for (int i=0; i<drawables.size(); i++) {
- final GLAutoDrawable drawable = drawables.get(i);
- if (drawable instanceof JComponent) {
- // Lightweight components need a more efficient drawing
- // scheme than simply forcing repainting of each one in
- // turn since drawing one can force another one to be
- // drawn in turn
- lightweights.add((JComponent)drawable);
- } else {
- try {
+ boolean hasException = false;
+ for (int i=0; !hasException && i<drawables.size(); i++) {
+ GLAutoDrawable drawable = null;
+ boolean catch1 = true;
+ try {
+ drawable = drawables.get(i);
+ catch1 = false;
+ if (drawable instanceof JComponent) {
+ // Lightweight components need a more efficient drawing
+ // scheme than simply forcing repainting of each one in
+ // turn since drawing one can force another one to be
+ // drawn in turn
+ lightweights.add((JComponent)drawable);
+ } else {
drawable.display();
- } catch (final Throwable t) {
- if (ignoreExceptions) {
- if (printExceptions) {
- t.printStackTrace();
- }
- } else {
- throw new UncaughtAnimatorException(drawable, t);
+ }
+ } catch (final Throwable t) {
+ if( catch1 && t instanceof IndexOutOfBoundsException ) {
+ // concurrent pulling of GLAutoDrawables ..
+ hasException = true;
+ } else if ( ignoreExceptions ) {
+ if ( printExceptions ) {
+ t.printStackTrace();
}
+ } else {
+ throw new UncaughtAnimatorException(drawable, t);
}
}
}
-
if (lightweights.size() > 0) {
try {
SwingUtilities.invokeAndWait(drawWithRepaintManagerRunnable);
- } catch (final Exception e) {
- e.printStackTrace();
+ } catch (final Throwable t) {
+ t.printStackTrace();
}
lightweights.clear();
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/Animator.java b/src/jogl/classes/com/jogamp/opengl/util/Animator.java
index 066709316..10b0b6b5a 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/Animator.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/Animator.java
@@ -40,6 +40,9 @@
package com.jogamp.opengl.util;
+import com.jogamp.common.ExceptionUtils;
+import com.jogamp.common.util.InterruptSource;
+import com.jogamp.common.util.SourcedInterruptedException;
import com.jogamp.opengl.GLAutoDrawable;
import com.jogamp.opengl.GLException;
@@ -174,6 +177,9 @@ public class Animator extends AnimatorBase {
try {
Animator.this.wait();
} catch (final InterruptedException e) {
+ caughtException = new UncaughtAnimatorException(null, SourcedInterruptedException.wrap(e));
+ stopIssued = true;
+ break; // end pause loop
}
if (wasPaused) {
// resume from pause -> reset counter
@@ -209,8 +215,7 @@ public class Animator extends AnimatorBase {
}
} catch(final ThreadDeath td) {
if(DEBUG) {
- System.err.println("Animator caught: "+td.getClass().getName()+": "+td.getMessage());
- td.printStackTrace();
+ ExceptionUtils.dumpThrowable("", td);
}
caughtThreadDeath = td;
}
@@ -222,8 +227,7 @@ public class Animator extends AnimatorBase {
if( null == caughtException ) {
caughtException = dre;
} else {
- System.err.println("Animator.setExclusiveContextThread: caught: "+dre.getMessage());
- dre.printStackTrace();
+ ExceptionUtils.dumpThrowable("(setExclusiveContextThread)", dre);
}
}
}
@@ -233,8 +237,7 @@ public class Animator extends AnimatorBase {
if(DEBUG) {
System.err.println("Animator stop on " + animThread.getName() + ": " + toString());
if( null != caughtException ) {
- System.err.println("Animator caught: "+caughtException.getMessage());
- caughtException.printStackTrace();
+ ExceptionUtils.dumpThrowable("", caughtException);
}
}
stopIssued = false;
@@ -291,13 +294,7 @@ public class Animator extends AnimatorBase {
runnable = new MainLoop();
}
fpsCounter.resetFPSCounter();
- final String threadName = getThreadName()+"-"+baseName;
- Thread thread;
- if(null==threadGroup) {
- thread = new Thread(runnable, threadName);
- } else {
- thread = new Thread(threadGroup, runnable, threadName);
- }
+ final Thread thread = new InterruptSource.Thread(threadGroup, runnable, getThreadName()+"-"+baseName);
thread.setDaemon(false); // force to be non daemon, regardless of parent thread
if(DEBUG) {
final Thread ct = Thread.currentThread();
diff --git a/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java b/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java
index aafdf63f8..41b969551 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java
@@ -40,6 +40,7 @@ import com.jogamp.opengl.GLException;
import com.jogamp.opengl.GLProfile;
import com.jogamp.common.ExceptionUtils;
+import com.jogamp.common.util.InterruptedRuntimeException;
/**
* Base implementation of GLAnimatorControl<br>
@@ -596,7 +597,9 @@ public abstract class AnimatorBase implements GLAnimatorControl {
notifyAll();
try {
wait(pollPeriod);
- } catch (final InterruptedException ie) { }
+ } catch (final InterruptedException ie) {
+ throw new InterruptedRuntimeException(ie);
+ }
remaining -= System.currentTimeMillis() - t1 ;
nok = waitCondition.eval();
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/DefaultAnimatorImpl.java b/src/jogl/classes/com/jogamp/opengl/util/DefaultAnimatorImpl.java
index 6cded29d9..d8c8465d9 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/DefaultAnimatorImpl.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/DefaultAnimatorImpl.java
@@ -48,12 +48,19 @@ class DefaultAnimatorImpl implements AnimatorBase.AnimatorImpl {
public void display(final ArrayList<GLAutoDrawable> drawables,
final boolean ignoreExceptions,
final boolean printExceptions) throws UncaughtAnimatorException {
- for (int i=0; i<drawables.size(); i++) {
- final GLAutoDrawable drawable = drawables.get(i);
+ boolean hasException = false;
+ for (int i=0; !hasException && i<drawables.size(); i++) {
+ boolean catch1 = true;
+ GLAutoDrawable drawable = null;
try {
+ drawable = drawables.get(i);
+ catch1 = false;
drawable.display();
} catch (final Throwable t) {
- if (ignoreExceptions) {
+ if( catch1 && t instanceof IndexOutOfBoundsException ) {
+ // concurrent pulling of GLAutoDrawables ..
+ hasException = true;
+ } else if (ignoreExceptions) {
if (printExceptions) {
t.printStackTrace();
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLPixelBuffer.java b/src/jogl/classes/com/jogamp/opengl/util/GLPixelBuffer.java
index c82f63898..0e3497bd4 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/GLPixelBuffer.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLPixelBuffer.java
@@ -262,6 +262,8 @@ public class GLPixelBuffer {
case GL.GL_UNSIGNED_SHORT_5_5_5_1:
pixFmt = PixelFormat.ABGR1555;
break;
+ case GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV:
+ // fall through intended
case GL.GL_UNSIGNED_BYTE:
pixFmt = PixelFormat.RGBA8888;
break;
@@ -280,6 +282,8 @@ public class GLPixelBuffer {
case GL2GL3.GL_UNSIGNED_INT_8_8_8_8:
pixFmt = PixelFormat.ARGB8888;
break;
+ case GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV:
+ // fall through intended
case GL.GL_UNSIGNED_BYTE:
pixFmt = PixelFormat.BGRA8888;
break;
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLReadBufferUtil.java b/src/jogl/classes/com/jogamp/opengl/util/GLReadBufferUtil.java
index cc3462f99..3fa856a47 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/GLReadBufferUtil.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLReadBufferUtil.java
@@ -245,8 +245,8 @@ public class GLReadBufferUtil {
readTexture.updateImage(gl, readTextureData);
} else {
readTexture.updateSubImage(gl, readTextureData, 0,
- 0, 0, // src offset
- 0, 0, // dst offset
+ inX, inY, // dst offset
+ 0, 0, // src offset
width, height);
}
readPixelBuffer.rewind();
diff --git a/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java b/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java
index 196acf9ab..5383f91be 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java
@@ -920,7 +920,6 @@ public final class PMVMatrix implements GLMatrixFunc {
* or {@link #glGetFrustum() Frustum get} methods.
* </p>
*
- * @deprecated Function is exposed for debugging purposes only.
* @see #DIRTY_INVERSE_MODELVIEW
* @see #DIRTY_INVERSE_TRANSPOSED_MODELVIEW
* @see #DIRTY_FRUSTUM
@@ -941,7 +940,6 @@ public final class PMVMatrix implements GLMatrixFunc {
* or {@link #glGetFrustum() Frustum get} methods.
* </p>
*
- * @deprecated Function is exposed for debugging purposes only.
* @see #clearAllUpdateRequests()
* @see #DIRTY_INVERSE_MODELVIEW
* @see #DIRTY_INVERSE_TRANSPOSED_MODELVIEW
diff --git a/src/jogl/classes/com/jogamp/opengl/util/PNGPixelRect.java b/src/jogl/classes/com/jogamp/opengl/util/PNGPixelRect.java
index f28774afa..1dded7882 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/PNGPixelRect.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/PNGPixelRect.java
@@ -78,7 +78,8 @@ public class PNGPixelRect extends PixelRectangle.GenericPixelRect {
public static PNGPixelRect read(final InputStream in,
final PixelFormat ddestFmt, final boolean destDirectBuffer, final int destMinStrideInBytes,
final boolean destIsGLOriented) throws IOException {
- final PngReader pngr = new PngReader(new BufferedInputStream(in), null);
+ final BufferedInputStream bin = (in instanceof BufferedInputStream) ? (BufferedInputStream)in : new BufferedInputStream(in);
+ final PngReader pngr = new PngReader(bin, null);
final ImageInfo imgInfo = pngr.imgInfo;
final PngChunkPLTE plte = pngr.getMetadata().getPLTE();
final PngChunkTRNS trns = pngr.getMetadata().getTRNS();
diff --git a/src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java b/src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java
index 662cf74b7..c2de32372 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java
@@ -205,22 +205,29 @@ public interface GLMediaPlayer extends TextureSequence {
* {@link Uri#scheme Uri scheme} name {@value} for camera input. E.g. <code>camera:/0</code>
* for the 1st camera device.
* <p>
- * The {@link Uri#path Uri path} is being used to identify the camera (<i>ID</i>),
+ * The {@link Uri#path Uri path} is being used to identify the camera (<i>&lt;id&gt;</i>),
* where the root fwd-slash is being cut-off.
* </p>
* <p>
- * The <i>ID</i> is usually an integer value indexing the camera
+ * The <i>&lt;id&gt;</i> is usually an integer value indexing the camera
* ranging from [0..<i>max-number</i>].
* </p>
* <p>
+ * The <i>&lt;somewhere&gt;</i> is usually empty, since it would imply a networking camera protocol.
+ * </p>
+ * <p>
* The {@link Uri#query Uri query} is used to pass options to the camera
* using <i>;</i> as the separator. The latter avoids trouble w/ escaping.
* </p>
* <pre>
- * camera:/<id>
- * camera://somewhere/<id>
- * camera://somewhere/<id>?width=640;height=480;rate=15
- * camera://somewhere/<id>?size=640x480;rate=15
+ * camera:/&lt;id&gt;
+ * camera:/&lt;id&gt;?width=640;height=480;rate=15
+ * camera:/&lt;id&gt;?size=640x480;rate=15
+ * camera://&lt;somewhere&gt;/&lt;id&gt;
+ * camera://&lt;somewhere&gt;/&lt;id&gt;?width=640;height=480;rate=15
+ * camera://&lt;somewhere&gt;/&lt;id&gt;?size=640x480;rate=15
+ * camera:///&lt;id&gt;?width=640;height=480;rate=15
+ * camera:///&lt;id&gt;?size=640x480;rate=15
* </pre>
* <pre>
* Uri: [scheme:][//authority][path][?query][#fragment]
diff --git a/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java b/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java
index e6f5aaa2e..38bac06cc 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java
@@ -40,6 +40,7 @@
package com.jogamp.opengl.util.awt;
import com.jogamp.common.nio.Buffers;
+import com.jogamp.common.util.InterruptSource;
import com.jogamp.common.util.PropertyAccess;
import com.jogamp.opengl.GLExtensions;
import com.jogamp.opengl.util.*;
@@ -915,7 +916,7 @@ public class TextRenderer {
// Run this on another thread than the AWT event queue to
// make sure the call to Animator.stop() completes before
// exiting
- new Thread(new Runnable() {
+ new InterruptSource.Thread(null, new Runnable() {
@Override
public void run() {
anim.stop();
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 e1db3f7a3..532db3a7a 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderCode.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderCode.java
@@ -47,6 +47,7 @@ import java.util.Set;
import com.jogamp.opengl.GL;
import com.jogamp.opengl.GL2ES2;
import com.jogamp.opengl.GL3;
+import com.jogamp.opengl.GL3ES3;
import com.jogamp.opengl.GL4;
import com.jogamp.opengl.GLES2;
import com.jogamp.opengl.GLContext;
@@ -87,6 +88,18 @@ public class ShaderCode {
public static final String SUFFIX_GEOMETRY_BINARY = "bgp" ;
/**
+ * Unique resource suffix for {@link GL3ES3#GL_COMPUTE_SHADER} in source code: <code>{@value}</code>
+ * @since 2.3.2
+ */
+ public static final String SUFFIX_COMPUTE_SOURCE = "cp" ;
+
+ /**
+ * Unique resource suffix for {@link GL3ES3#GL_COMPUTE_SHADER} in binary: <code>{@value}</code>
+ * @since 2.3.2
+ */
+ public static final String SUFFIX_COMPUTE_BINARY = "bcp" ;
+
+ /**
* Unique resource suffix for {@link GL4#GL_TESS_CONTROL_SHADER} in source code: <code>{@value}</code>
* @since 2.2.1
*/
@@ -121,7 +134,7 @@ public class ShaderCode {
/**
* @param type either {@link GL2ES2#GL_VERTEX_SHADER}, {@link GL2ES2#GL_FRAGMENT_SHADER}, {@link GL3#GL_GEOMETRY_SHADER},
- * {@link GL4#GL_TESS_CONTROL_SHADER} or {@link GL4#GL_TESS_EVALUATION_SHADER}.
+ * {@link GL4#GL_TESS_CONTROL_SHADER}, {@link GL4#GL_TESS_EVALUATION_SHADER} or {@link GL3ES3#GL_COMPUTE_SHADER}.
* @param count number of shaders
* @param source CharSequence array containing the shader sources, organized as <code>source[count][strings-per-shader]</code>.
* May be either an immutable <code>String</code> - or mutable <code>StringBuilder</code> array.
@@ -135,9 +148,10 @@ public class ShaderCode {
switch (type) {
case GL2ES2.GL_VERTEX_SHADER:
case GL2ES2.GL_FRAGMENT_SHADER:
- case GL3.GL_GEOMETRY_SHADER:
- case GL3.GL_TESS_CONTROL_SHADER:
- case GL3.GL_TESS_EVALUATION_SHADER:
+ case GL3ES3.GL_GEOMETRY_SHADER:
+ case GL3ES3.GL_TESS_CONTROL_SHADER:
+ case GL3ES3.GL_TESS_EVALUATION_SHADER:
+ case GL3ES3.GL_COMPUTE_SHADER:
break;
default:
throw new GLException("Unknown shader type: "+type);
@@ -157,7 +171,7 @@ public class ShaderCode {
/**
* @param type either {@link GL2ES2#GL_VERTEX_SHADER}, {@link GL2ES2#GL_FRAGMENT_SHADER}, {@link GL3#GL_GEOMETRY_SHADER},
- * {@link GL4#GL_TESS_CONTROL_SHADER} or {@link GL4#GL_TESS_EVALUATION_SHADER}.
+ * {@link GL4#GL_TESS_CONTROL_SHADER}, {@link GL4#GL_TESS_EVALUATION_SHADER} or {@link GL3ES3#GL_COMPUTE_SHADER}.
* @param count number of shaders
* @param binary binary buffer containing the shader binaries,
*/
@@ -165,9 +179,10 @@ public class ShaderCode {
switch (type) {
case GL2ES2.GL_VERTEX_SHADER:
case GL2ES2.GL_FRAGMENT_SHADER:
- case GL3.GL_GEOMETRY_SHADER:
- case GL3.GL_TESS_CONTROL_SHADER:
- case GL3.GL_TESS_EVALUATION_SHADER:
+ case GL3ES3.GL_GEOMETRY_SHADER:
+ case GL3ES3.GL_TESS_CONTROL_SHADER:
+ case GL3ES3.GL_TESS_EVALUATION_SHADER:
+ case GL3ES3.GL_COMPUTE_SHADER:
break;
default:
throw new GLException("Unknown shader type: "+type);
@@ -186,7 +201,7 @@ public class ShaderCode {
*
* @param gl current GL object to determine whether a shader compiler is available. If null, no validation is performed.
* @param type either {@link GL2ES2#GL_VERTEX_SHADER}, {@link GL2ES2#GL_FRAGMENT_SHADER}, {@link GL3#GL_GEOMETRY_SHADER},
- * {@link GL4#GL_TESS_CONTROL_SHADER} or {@link GL4#GL_TESS_EVALUATION_SHADER}.
+ * {@link GL4#GL_TESS_CONTROL_SHADER}, {@link GL4#GL_TESS_EVALUATION_SHADER} or {@link GL3ES3#GL_COMPUTE_SHADER}.
* @param count number of shaders
* @param context class used to help resolving the source location
* @param sourceFiles array of source locations, organized as <code>sourceFiles[count]</code> -> <code>shaderSources[count][1]</code>
@@ -233,7 +248,7 @@ public class ShaderCode {
*
* @param gl current GL object to determine whether a shader compiler is available. If null, no validation is performed.
* @param type either {@link GL2ES2#GL_VERTEX_SHADER}, {@link GL2ES2#GL_FRAGMENT_SHADER}, {@link GL3#GL_GEOMETRY_SHADER},
- * {@link GL4#GL_TESS_CONTROL_SHADER} or {@link GL4#GL_TESS_EVALUATION_SHADER}.
+ * {@link GL4#GL_TESS_CONTROL_SHADER}, {@link GL4#GL_TESS_EVALUATION_SHADER} or {@link GL3ES3#GL_COMPUTE_SHADER}.
* @param count number of shaders
* @param sourceLocations array of {@link Uri} source locations, organized as <code>sourceFiles[count]</code> -> <code>shaderSources[count][1]</code>
* @param mutableStringBuilder if <code>true</code> method returns a mutable <code>StringBuilder</code> instance
@@ -279,7 +294,7 @@ public class ShaderCode {
* which location is resolved using the <code>context</code> class, see {@link #readShaderBinary(Class, String)}.
*
* @param type either {@link GL2ES2#GL_VERTEX_SHADER}, {@link GL2ES2#GL_FRAGMENT_SHADER}, {@link GL3#GL_GEOMETRY_SHADER},
- * {@link GL4#GL_TESS_CONTROL_SHADER} or {@link GL4#GL_TESS_EVALUATION_SHADER}.
+ * {@link GL4#GL_TESS_CONTROL_SHADER}, {@link GL4#GL_TESS_EVALUATION_SHADER} or {@link GL3ES3#GL_COMPUTE_SHADER}.
* @param count number of shaders
* @param context class used to help resolving the source location
* @param binFormat a valid native binary format as they can be queried by {@link ShaderUtil#getShaderBinaryFormats(GL)}.
@@ -310,7 +325,7 @@ public class ShaderCode {
* Creates a complete {@link ShaderCode} object while reading the shader binary from {@link Uri} <code>binLocations</code>
* via {@link #readShaderBinary(Uri)}.
* @param type either {@link GL2ES2#GL_VERTEX_SHADER}, {@link GL2ES2#GL_FRAGMENT_SHADER}, {@link GL3#GL_GEOMETRY_SHADER},
- * {@link GL4#GL_TESS_CONTROL_SHADER} or {@link GL4#GL_TESS_EVALUATION_SHADER}.
+ * {@link GL4#GL_TESS_CONTROL_SHADER}, {@link GL4#GL_TESS_EVALUATION_SHADER} or {@link GL3ES3#GL_COMPUTE_SHADER}.
* @param count number of shaders
* @param binFormat a valid native binary format as they can be queried by {@link ShaderUtil#getShaderBinaryFormats(GL)}.
* @param binLocations {@link Uri} binary location
@@ -346,6 +361,7 @@ public class ShaderCode {
* <li>{@link GL3#GL_GEOMETRY_SHADER geometry}: {@link #SUFFIX_GEOMETRY_SOURCE}</li>
* <li>{@link GL4#GL_TESS_CONTROL_SHADER tess-ctrl}: {@link #SUFFIX_TESS_CONTROL_SOURCE}</li>
* <li>{@link GL4#GL_TESS_EVALUATION_SHADER tess-eval}: {@link #SUFFIX_TESS_EVALUATION_SOURCE}</li>
+ * <li>{@link GL3ES3#GL_COMPUTE_SHADER}: {@link #SUFFIX_COMPUTE_SOURCE}</li>
* </ul></li>
* <li>Binary<ul>
* <li>{@link GL2ES2#GL_VERTEX_SHADER vertex}: {@link #SUFFIX_VERTEX_BINARY}</li>
@@ -353,11 +369,12 @@ public class ShaderCode {
* <li>{@link GL3#GL_GEOMETRY_SHADER geometry}: {@link #SUFFIX_GEOMETRY_BINARY}</li>
* <li>{@link GL4#GL_TESS_CONTROL_SHADER tess-ctrl}: {@link #SUFFIX_TESS_CONTROL_BINARY}</li>
* <li>{@link GL4#GL_TESS_EVALUATION_SHADER tess-eval}: {@link #SUFFIX_TESS_EVALUATION_BINARY}</li>
+ * <li>{@link GL3ES3#GL_COMPUTE_SHADER}: {@link #SUFFIX_COMPUTE_BINARY}</li>
* </ul></li>
* </ul>
* @param binary true for a binary resource, false for a source resource
* @param type either {@link GL2ES2#GL_VERTEX_SHADER}, {@link GL2ES2#GL_FRAGMENT_SHADER}, {@link GL3#GL_GEOMETRY_SHADER},
- * {@link GL4#GL_TESS_CONTROL_SHADER} or {@link GL4#GL_TESS_EVALUATION_SHADER}.
+ * {@link GL4#GL_TESS_CONTROL_SHADER}, {@link GL4#GL_TESS_EVALUATION_SHADER} or {@link GL3ES3#GL_COMPUTE_SHADER}.
*
* @throws GLException if <code>type</code> is not supported
*
@@ -369,12 +386,14 @@ public class ShaderCode {
return binary?SUFFIX_VERTEX_BINARY:SUFFIX_VERTEX_SOURCE;
case GL2ES2.GL_FRAGMENT_SHADER:
return binary?SUFFIX_FRAGMENT_BINARY:SUFFIX_FRAGMENT_SOURCE;
- case GL3.GL_GEOMETRY_SHADER:
+ case GL3ES3.GL_GEOMETRY_SHADER:
return binary?SUFFIX_GEOMETRY_BINARY:SUFFIX_GEOMETRY_SOURCE;
- case GL3.GL_TESS_CONTROL_SHADER:
+ case GL3ES3.GL_TESS_CONTROL_SHADER:
return binary?SUFFIX_TESS_CONTROL_BINARY:SUFFIX_TESS_CONTROL_SOURCE;
- case GL3.GL_TESS_EVALUATION_SHADER:
+ case GL3ES3.GL_TESS_EVALUATION_SHADER:
return binary?SUFFIX_TESS_EVALUATION_BINARY:SUFFIX_TESS_EVALUATION_SOURCE;
+ case GL3ES3.GL_COMPUTE_SHADER:
+ return binary?SUFFIX_COMPUTE_BINARY:SUFFIX_COMPUTE_SOURCE;
default:
throw new GLException("illegal shader type: "+type);
}
@@ -457,7 +476,7 @@ public class ShaderCode {
* @param gl current GL object to determine whether a shader compiler is available (if <code>source</code> is used),
* or to determine the shader binary format (if <code>binary</code> is used).
* @param type either {@link GL2ES2#GL_VERTEX_SHADER}, {@link GL2ES2#GL_FRAGMENT_SHADER}, {@link GL3#GL_GEOMETRY_SHADER},
- * {@link GL4#GL_TESS_CONTROL_SHADER} or {@link GL4#GL_TESS_EVALUATION_SHADER}.
+ * {@link GL4#GL_TESS_CONTROL_SHADER}, {@link GL4#GL_TESS_EVALUATION_SHADER} or {@link GL3ES3#GL_COMPUTE_SHADER}.
* @param count number of shaders
* @param context class used to help resolving the source and binary location
* @param srcRoot relative <i>root</i> path for <code>srcBasenames</code> optional
@@ -591,7 +610,7 @@ public class ShaderCode {
* @param gl current GL object to determine whether a shader compiler is available (if <code>source</code> is used),
* or to determine the shader binary format (if <code>binary</code> is used).
* @param type either {@link GL2ES2#GL_VERTEX_SHADER}, {@link GL2ES2#GL_FRAGMENT_SHADER}, {@link GL3#GL_GEOMETRY_SHADER},
- * {@link GL4#GL_TESS_CONTROL_SHADER} or {@link GL4#GL_TESS_EVALUATION_SHADER}.
+ * {@link GL4#GL_TESS_CONTROL_SHADER}, {@link GL4#GL_TESS_EVALUATION_SHADER} or {@link GL3ES3#GL_COMPUTE_SHADER}.
* @param count number of shaders
* @param context class used to help resolving the source and binary location
* @param srcRoot relative <i>root</i> path for <code>srcBasenames</code> optional
@@ -659,7 +678,7 @@ public class ShaderCode {
* @param gl current GL object to determine whether a shader compiler is available (if <code>source</code> is used),
* or to determine the shader binary format (if <code>binary</code> is used).
* @param type either {@link GL2ES2#GL_VERTEX_SHADER}, {@link GL2ES2#GL_FRAGMENT_SHADER}, {@link GL3#GL_GEOMETRY_SHADER},
- * {@link GL4#GL_TESS_CONTROL_SHADER} or {@link GL4#GL_TESS_EVALUATION_SHADER}.
+ * {@link GL4#GL_TESS_CONTROL_SHADER}, {@link GL4#GL_TESS_EVALUATION_SHADER} or {@link GL3ES3#GL_COMPUTE_SHADER}.
* @param context class used to help resolving the source and binary location
* @param srcRoot relative <i>root</i> path for <code>basename</code> optional
* @param binRoot relative <i>root</i> path for <code>basename</code>
@@ -726,11 +745,16 @@ public class ShaderCode {
* @param gl current GL object to determine whether a shader compiler is available (if <code>source</code> is used),
* or to determine the shader binary format (if <code>binary</code> is used).
* @param type either {@link GL2ES2#GL_VERTEX_SHADER}, {@link GL2ES2#GL_FRAGMENT_SHADER}, {@link GL3#GL_GEOMETRY_SHADER},
- * {@link GL4#GL_TESS_CONTROL_SHADER} or {@link GL4#GL_TESS_EVALUATION_SHADER}.
+ * {@link GL4#GL_TESS_CONTROL_SHADER}, {@link GL4#GL_TESS_EVALUATION_SHADER} or {@link GL3ES3#GL_COMPUTE_SHADER}.
* @param context class used to help resolving the source and binary location
* @param srcRoot relative <i>root</i> path for <code>basename</code> optional
* @param binRoot relative <i>root</i> path for <code>basename</code>
- * @param mutableStringBuilder TODO
+ * @param mutableStringBuilder if <code>true</code> method returns a mutable <code>StringBuilder</code> instance
+ * which can be edited later on at the costs of a String conversion when passing to
+ * {@link GL2ES2#glShaderSource(int, int, String[], IntBuffer)}.
+ * If <code>false</code> method returns an immutable <code>String</code> instance,
+ * which can be passed to {@link GL2ES2#glShaderSource(int, int, String[], IntBuffer)}
+ * at no additional costs.
* @param basenames basename w/o path or suffix relative to <code>srcRoot</code> and <code>binRoot</code>
* for the shader's source and binary code.
* @param mutableStringBuilder if <code>true</code> method returns a mutable <code>StringBuilder</code> instance
@@ -761,12 +785,14 @@ public class ShaderCode {
return "VERTEX_SHADER";
case GL2ES2.GL_FRAGMENT_SHADER:
return "FRAGMENT_SHADER";
- case GL3.GL_GEOMETRY_SHADER:
+ case GL3ES3.GL_GEOMETRY_SHADER:
return "GEOMETRY_SHADER";
- case GL3.GL_TESS_CONTROL_SHADER:
+ case GL3ES3.GL_TESS_CONTROL_SHADER:
return "TESS_CONTROL_SHADER";
- case GL3.GL_TESS_EVALUATION_SHADER:
+ case GL3ES3.GL_TESS_EVALUATION_SHADER:
return "TESS_EVALUATION_SHADER";
+ case GL3ES3.GL_COMPUTE_SHADER:
+ return "COMPUTE_SHADER";
}
return "UNKNOWN_SHADER";
}
@@ -1072,7 +1098,15 @@ public class ShaderCode {
while ((line = reader.readLine()) != null) {
lineno++;
if (line.startsWith("#include ")) {
- final String includeFile = line.substring(9).trim();
+ final String includeFile;
+ {
+ String s = line.substring(9).trim();
+ // Bug 1283: Remove shader include filename quotes if exists at start and end only
+ if( s.startsWith("\"") && s.endsWith("\"")) {
+ s = s.substring(1, s.length()-1);
+ }
+ includeFile = s;
+ }
URLConnection nextConn = null;
// Try relative of current shader location
@@ -1080,7 +1114,7 @@ public class ShaderCode {
nextConn = IOUtil.openURL(relUri.toURL(), "ShaderCode.relativeOf ");
if (nextConn == null) {
// Try relative of class and absolute
- nextConn = IOUtil.getResource(context, includeFile);
+ nextConn = IOUtil.getResource(includeFile, context.getClassLoader(), context);
}
if (nextConn == null) {
// Fail
@@ -1132,7 +1166,7 @@ public class ShaderCode {
* @see IOUtil#getResource(Class, String)
*/
public static CharSequence readShaderSource(final Class<?> context, final String path, final boolean mutableStringBuilder) throws IOException {
- final URLConnection conn = IOUtil.getResource(context, path);
+ final URLConnection conn = IOUtil.getResource(path, context.getClassLoader(), context);
if (conn == null) {
return null;
}
@@ -1178,7 +1212,7 @@ public class ShaderCode {
* @see IOUtil#getResource(Class, String)
*/
public static ByteBuffer readShaderBinary(final Class<?> context, final String path) throws IOException {
- final URLConnection conn = IOUtil.getResource(context, path);
+ final URLConnection conn = IOUtil.getResource(path, context.getClassLoader(), context);
if (conn == null) {
return null;
}
@@ -1284,6 +1318,8 @@ public class ShaderCode {
defaultPrecision = es3_default_precision_vp; break;
case GL2ES2.GL_FRAGMENT_SHADER:
defaultPrecision = es3_default_precision_fp; break;
+ case GL3ES3.GL_COMPUTE_SHADER:
+ defaultPrecision = es3_default_precision_fp; break;
default:
defaultPrecision = null;
break;
@@ -1302,12 +1338,14 @@ public class ShaderCode {
// GLSL [ 1.30 .. 1.50 [ needs at least fragement float default precision!
switch ( shaderType ) {
case GL2ES2.GL_VERTEX_SHADER:
- case GL3.GL_GEOMETRY_SHADER:
- case GL3.GL_TESS_CONTROL_SHADER:
- case GL3.GL_TESS_EVALUATION_SHADER:
+ case GL3ES3.GL_GEOMETRY_SHADER:
+ case GL3ES3.GL_TESS_CONTROL_SHADER:
+ case GL3ES3.GL_TESS_EVALUATION_SHADER:
defaultPrecision = gl3_default_precision_vp_gp; break;
case GL2ES2.GL_FRAGMENT_SHADER:
defaultPrecision = gl3_default_precision_fp; break;
+ case GL3ES3.GL_COMPUTE_SHADER:
+ defaultPrecision = gl3_default_precision_fp; break;
default:
defaultPrecision = null;
break;
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/sdk/CompileShader.java b/src/jogl/classes/com/jogamp/opengl/util/glsl/sdk/CompileShader.java
index f5dec1cab..376afb8ce 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/glsl/sdk/CompileShader.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/sdk/CompileShader.java
@@ -52,7 +52,7 @@ public abstract class CompileShader {
final String justName = basename(resourceName);
outName = justName.substring(0, justName.length() - suffixLen) +
ShaderCode.getFileSuffix(true, type);
- final URL resourceURL = IOUtil.getResource(null, resourceName).getURL();
+ final URL resourceURL = IOUtil.getResource(resourceName, this.getClass().getClassLoader(), null).getURL();
final String dirName = dirname(resourceURL.getPath());
outName = dirName + File.separator + "bin" + File.separator +
@@ -64,7 +64,7 @@ public abstract class CompileShader {
public void processOneShader(final String resourceName, final String outName, final int type)
throws IOException, UnsupportedEncodingException, InterruptedException
{
- final URL resourceURL = IOUtil.getResource(null, resourceName).getURL();
+ final URL resourceURL = IOUtil.getResource(resourceName, this.getClass().getClassLoader(), null).getURL();
final String dirName = dirname(resourceURL.getPath());
final CharSequence shader = ShaderCode.readShaderSource(null, resourceName, false);
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/ImageIOUtil.java b/src/jogl/classes/com/jogamp/opengl/util/texture/ImageIOUtil.java
deleted file mode 100644
index 1e50f843d..000000000
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/ImageIOUtil.java
+++ /dev/null
@@ -1,445 +0,0 @@
-/**
- * Copyright 2014 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.util.texture;
-
-import java.io.BufferedInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * Utilities for image input and output
- *
- */
-public class ImageIOUtil {
-
- /**
- * Determines the file suffix (i.e the image format) of the given InputStream. The given
- * InputStream must return true from markSupported() and support a minimum of 32 bytes
- * of read-ahead.
- *
- * @param stream stream to check
- * @return the file suffix if any, otherwise <code>null</code>
- * @throws java.io.IOException if an I/O exception occurred
- */
- public static String getFileSuffix(InputStream stream) throws IOException {
- if (stream == null) {
- throw new IOException("Stream was null");
- }
- if (!(stream instanceof BufferedInputStream)) {
- stream = new BufferedInputStream(stream);
- }
- if (!stream.markSupported()) {
- throw new IOException("Can not get non-destructively the image format");
- }
- if (stream.available() < 32) {
- throw new IOException("Not enough bytes to read in order to get the image format");
- }
- try {
- stream.mark(32);
- final byte[] b = new byte[32];
- stream.read(b);
- return getFileSuffix(b);
- } finally {
- stream.reset();
- }
-
- }
-
- /**
- * Determines the file suffix (i.e the image format) of the given bytes from the header
- * of a file.
- *
- * @param stream stream to check
- * @return the file suffix if any, otherwise <code>null</code>
- * @throws java.io.IOException if an I/O exception occurred
- */
- public static String getFileSuffix(final byte[] b) {
- /**
- * http://www.faqs.org/faqs/jpeg-faq/part1/
- * http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=54989
- */
- if ((b[0] == 0xff && b[1] == 0xd8 /* && b[2] == 0xff */)
- || (b[0] == 0x4A && b[1] == 0x46 && b[2] == 0x49 && b[3] == 0x46)/* JFIF */
- || (b[0] == 0x45 && b[1] == 0x78 && b[2] == 0x69 && b[3] == 0x66)/* EXIF */) {
- return TextureIO.JPG;
- }
- /**
- * http://www.libpng.org/pub/png/spec/1.1/PNG-Rationale.html#R.PNG-file-signature
- */
- if (b[0] == 0x89 && b[1] == 0x50 && b[2] == 0x4E && b[3] == 0x47 /* 'P' 'N' 'G', ascii code */
- && b[4] == 0x0D && b[5] == 0x0A && b[6] == 0x1A && b[7] == 0x0A) {
- return TextureIO.PNG;
- }
- /**
- * Apple Icon Image
- *
- * 'i' 'c' 'n' 's' ascii code
- */
- if (b[0] == 0x69 && b[1] == 0x63 && b[2] == 0x6E && b[3] == 0x73) {
- return "icns";
- }
- /**
- * http://www.w3.org/Graphics/GIF/spec-gif87a.txt http://www.w3.org/Graphics/GIF/spec-gif89a.txt
- *
- * GIF87A or GIF89A ascii code
- */
- if (b[0] == 0x47 && b[1] == 0x49 && b[2] == 0x46 && b[3] == 0x38 && (b[4] == 0x37 || b[4] == 0x39)
- && b[5] == 0x61) {
- return TextureIO.GIF;
- }
- /**
- * http://www.fileformat.info/format/bmp/spec/e27073c25463436f8a64fa789c886d9c/view.htm
- *
- * BM ascii code
- */
- if (b[0] == 0x42 && b[1] == 0x4d) {
- return "bmp";
- }
- if (b[0] == 0x3A && b[1] == 0xDE && b[2] == 0x68 && b[3] == 0xB1) {
- return "dcx";
- }
- if (b[0] == 0x0A && b[1] == 0x05 && b[2] == 0x01 && b[3] == 0x08) {
- return "pcx";
- }
- /**
- * http://netpbm.sourceforge.net/doc/ppm.html
- */
- if (b[0] == 0x50 && (b[1] == 0x33 /* plain */|| b[1] == 0x36)) {
- return TextureIO.PPM;
- }
- if (b[0] == 0x38 && b[1] == 0x42 && b[2] == 0x50 && b[3] == 0x53 && b[4] == 0x00 && b[5] == 0x01
- && b[6] == 0x00 && b[7] == 0x00 && b[8] == 0x00 && b[9] == 0x00) {
- // Adobe PhotoShop
- return "psd";
- }
- /**
- * http://partners.adobe.com/public/developer/en/tiff/TIFF6.pdf
- *
- * intentionally detects only the little endian tiff images ("II" in the spec)
- */
- if (b[0] == 0x49 && b[1] == 0x49 && b[2] == 0x2A && b[3] == 0x00) {
- return TextureIO.TIFF;
- }
- /**
- * http://paulbourke.net/dataformats/sgirgb/sgiversion.html
- *
- * "474 saved as a short" 474 = 0x01DA
- */
- if (b[0] == 0x01 && b[1] == 0xDA /* && b[2] == 0x01 && b[3] == 0x01 && b[4] == 0x00 && b[5] == 0x03 */) {
- return TextureIO.SGI_RGB;
- }
- /**
- * 'D' 'D' 'S' ' ' ascii code
- */
- if (b[0] == 0x44 && b[1] == 0x44 && b[2] == 0x53 && b[3] == 0x20) {
- return TextureIO.DDS;
- }
- /**
- * http://netpbm.sourceforge.net/doc/pam.html
- */
- if (b[0] == 0x50 && b[1] == 0x37) {
- return TextureIO.PAM;
- }
- /**
- * http://netpbm.sourceforge.net/doc/pgm.html
- */
- if (b[0] == 0x50 && (b[1] == 0x32 /* plain */|| b[1] == 0x35)) {
- return "pgm";
- }
- /**
- * http://netpbm.sourceforge.net/doc/pbm.html
- */
- if (b[0] == 0x50 && (b[1] == 0x31 /* plain */|| b[1] == 0x34)) {
- return "pbm";
- }
- if (b[0] == 0x3D && b[1] == 0x02) {
- return "3d2";
- }
- if (b[0] == 0x33 && b[1] == 0x44 && b[2] == 0x4D && b[3] == 0x46) {
- return "3dmf";
- }
- if (b[0] == 0x2A && b[1] == 0x2A && b[2] == 0x54 && b[3] == 0x49 && b[4] == 0x39 && b[5] == 0x32
- && b[6] == 0x2A && b[7] == 0x2A && b[8] == 0x01 && b[9] == 0x00 && b[10] == 0x58
- && b[11] == 0x6E && b[12] == 0x56 && b[13] == 0x69) {
- return "92i";
- }
- if (b[0] == 0x41 && b[1] == 0x4D && b[2] == 0x46 && b[3] == 0x46) {
- return "amff";
- }
- if (b[0] == 0x4A && b[1] == 0x47 && (b[2] == 0x03 || b[2] == 0x04) && b[3] == 0x0E && b[4] == 0x00
- && b[5] == 0x00 && b[6] == 0x00) {
- return "art";
- }
- if (b[0] == 0x73 && b[1] == 0x72 && b[2] == 0x63 && b[3] == 0x64 && b[4] == 0x6F && b[5] == 0x63
- && b[6] == 0x69 && b[7] == 0x64 && b[8] == 0x3A) {
- return "cals";
- }
- if (b[0] == 0x07 && b[1] == 0x20 && b[2] == 0x4D && b[3] == 0x4D) {
- return "cam";
- }
- if (b[0] == 0x20 && b[1] == 0x77 && b[2] == 0x00 && b[3] == 0x02) {
- return "cbd";
- }
- if (b[0] == 0x45 && b[1] == 0x59 && b[2] == 0x45 && b[3] == 0x53) {
- return "ce2";
- }
- if (b[0] == 0x80 && b[1] == 0x2A && b[2] == 0x5F && b[3] == 0xD7 && b[4] == 0x00 && b[5] == 0x00
- && b[6] == 0x08 && b[7] == 0x00 && b[8] == 0x00 && b[9] == 0x00 && b[10] == 0x04
- && b[11] == 0x00 && b[12] == 0x00 && b[13] == 0x00) {
- return "cin";
- }
- if (b[0] == 0x43 && b[1] == 0x61 && b[2] == 0x6C && b[3] == 0x69 && b[4] == 0x67 && b[5] == 0x61
- && b[6] == 0x72 && b[7] == 0x69) {
- return "cob";
- }
- if (b[0] == 0x43 && b[1] == 0x50 && b[2] == 0x54 && b[3] == 0x46 && b[4] == 0x49 && b[5] == 0x4C
- && b[6] == 0x45) {
- return "cpt";
- }
- if (b[0] == 0x43 && b[1] == 0x41 && b[2] == 0x4C && b[3] == 0x41 && b[4] == 0x4D && b[5] == 0x55
- && b[6] == 0x53 && b[7] == 0x43 && b[8] == 0x56 && b[9] == 0x47) {
- return "cvg";
- }
- if (b[0] == 0x56 && b[1] == 0x69 && b[2] == 0x73 && b[3] == 0x74 && b[4] == 0x61 && b[5] == 0x20
- && b[6] == 0x44 && b[7] == 0x45 && b[8] == 0x4D && b[9] == 0x20 && b[10] == 0x46
- && b[11] == 0x69 && b[12] == 0x6C && b[13] == 0x65) {
- return "dem";
- }
- if (b[0] == 0x42 && b[1] == 0x4D && b[2] == 0x36) {
- return "dib";
- }
- if (b[0] == 0x53 && b[1] == 0x44 && b[2] == 0x50 && b[3] == 0x58) {
- return "dpx";
- }
- if (b[0] == 0x01 && b[1] == 0xFF && b[2] == 0x02 && b[3] == 0x04 && b[4] == 0x03 && b[5] == 0x02) {
- return "drw";
- }
- if (b[0] == 0x41 && b[1] == 0x43 && b[2] == 0x31 && b[3] == 0x30) {
- return "dwg";
- }
- if (b[0] == 0x65 && b[1] == 0x02 && b[2] == 0x01 && b[3] == 0x02) {
- return "ecw";
- }
- if (b[0] == 0x01 && b[1] == 0x00 && b[2] == 0x00 && b[3] == 0x00 && b[4] == 0x58 && b[5] == 0x00
- && b[6] == 0x00 && b[7] == 0x00) {
- return "emf";
- }
- if (b[0] == 0xD0 && b[1] == 0xCF && b[2] == 0x11 && b[3] == 0xE0 && b[4] == 0xA1 && b[5] == 0xB1
- && b[6] == 0x1A && b[7] == 0xE1 && b[8] == 0x00) {
- return "fpx";
- }
- if (b[0] == 0x53 && b[1] == 0x49 && b[2] == 0x4D && b[3] == 0x50 && b[4] == 0x4C && b[5] == 0x45
- && b[6] == 0x20 && b[7] == 0x20 && b[8] == 0x3D) {
- return "fts";
- }
- if (b[0] == 0x48 && b[1] == 0x50 && b[2] == 0x48 && b[3] == 0x50 && b[4] == 0x34 && b[5] == 0x38
- && b[6] == 0x2D && b[7] == 0x45 && b[8] == 0x1E && b[9] == 0x2B) {
- return "gro";
- }
- if (b[0] == 0x6E && b[1] == 0x63 && b[2] == 0x6F && b[3] == 0x6C && b[4] == 0x73) {
- return "hdr";
- }
- if (b[0] == 0x35 && b[1] == 0x4B && b[2] == 0x50 && b[3] == 0x35 && b[4] == 0x31 && b[5] == 0x5D
- && b[6] == 0x2A && b[7] == 0x67 && b[8] == 0x72 && b[9] == 0x72 && b[10] == 0x80
- && b[11] == 0x83 && b[12] == 0x85 && b[13] == 0x63) {
- return "hru";
- }
- if (b[0] == 0xEB && b[1] == 0x3C && b[2] == 0x90 && b[3] == 0x2A) {
- return "img";
- }
- if (b[0] == 0x65 && b[1] == 0x6C && b[2] == 0x6D && b[3] == 0x6F) {
- return "infini-d";
- }
- if (b[0] == 0x49 && b[1] == 0x57 && b[2] == 0x43 && b[3] == 0x01) {
- return "iwc";
- }
- if (b[0] == 0x80 && b[1] == 0x3E && b[2] == 0x44 && b[3] == 0x53 && b[4] == 0x43 && b[5] == 0x49
- && b[6] == 0x4D) {
- return "j6i";
- }
- if (b[0] == 0x4A && b[1] == 0x49 && b[2] == 0x46 && b[3] == 0x39 && b[4] == 0x39 && b[5] == 0x61) {
- return "jif";
- }
- if (b[0] == 0x00 && b[1] == 0x00 && b[2] == 0x00 && b[3] == 0x0C && b[4] == 0x6A && b[5] == 0x50
- && b[6] == 0x20 && b[7] == 0x20 && b[8] == 0x0D && b[9] == 0x0A && b[10] == 0x87
- && b[11] == 0x0A) {
- return "jp2";
- }
- if (b[0] == 0x4D && b[1] == 0x4D && b[2] == 0x00 && b[3] == 0x2A) {
- return "kdc";
- }
- if (b[0] == 0x36 && b[1] == 0x34 && b[2] == 0x4C && b[3] == 0x41 && b[4] == 0x4E && b[5] == 0x20
- && b[6] == 0x49 && b[7] == 0x44 && b[8] == 0x42 && b[9] == 0x4C && b[10] == 0x4F
- && b[11] == 0x43 && b[12] == 0x4B) {
- return "l64";
- }
- if (b[0] == 0x46 && b[1] == 0x4F && b[2] == 0x52 && b[3] == 0x4D) {
- return "lbm";
- }
- if (b[0] == 0x49 && b[1] == 0x49 && b[2] == 0x2A && b[3] == 0x00 && b[4] == 0x08 && b[5] == 0x00
- && b[6] == 0x00 && b[7] == 0x00 && b[8] == 0x0E && b[9] == 0x00 && b[10] == 0x00
- && b[11] == 0x01 && b[12] == 0x04 && b[13] == 0x00) {
- return "ldf";
- }
- if (b[0] == 0x57 && b[1] == 0x56 && b[2] == 0x02 && b[3] == 0x00 && b[4] == 0x47 && b[5] == 0x45
- && b[6] == 0x00 && b[7] == 0x0E) {
- return "lwf";
- }
- if (b[0] == 0x37 && b[1] == 0x00 && b[2] == 0x00 && b[3] == 0x10 && b[4] == 0x42 && b[5] == 0x00
- && b[6] == 0x00 && b[7] == 0x10 && b[8] == 0x00 && b[9] == 0x00 && b[10] == 0x00
- && b[11] == 0x00 && b[12] == 0x39 && b[13] == 0x64) {
- return "mbm";
- }
- if (b[0] == 0x4D && b[1] == 0x47 && b[2] == 0x4C) {
- return "mgl";
- }
- if (b[0] == 0x7B && b[1] == 0x0A && b[2] == 0x20 && b[3] == 0x20 && b[4] == 0x43 && b[5] == 0x72
- && b[6] == 0x65 && b[7] == 0x61 && b[8] == 0x74 && b[9] == 0x65 && b[10] == 0x64) {
- return "mif";
- }
- if (b[0] == 0x8A && b[1] == 0x4D && b[2] == 0x4E && b[3] == 0x47 && b[4] == 0x0D && b[5] == 0x0A
- && b[6] == 0x1A && b[7] == 0x0A) {
- return "mng";
- }
- if (b[0] == 0x4D && b[1] == 0x50 && b[2] == 0x46) {
- return "mpw";
- }
- if (b[0] == 0x44 && b[1] == 0x61 && b[2] == 0x6E && b[3] == 0x4D) {
- return "msp";
- }
- if (b[0] == 0x43 && b[1] == 0x36 && b[2] == 0x34) {
- return "n64";
- }
- if (b[0] == 0x6E && b[1] == 0x6E && b[2] == 0x0A && b[3] == 0x00 && b[4] == 0x5E && b[5] == 0x00) {
- return "ncr";
- }
- if (b[0] == 0x6E && b[1] == 0x66 && b[2] == 0x66) {
- return "nff";
- }
- if (b[0] == 0x4E && b[1] == 0x47 && b[2] == 0x47 && b[3] == 0x00 && b[4] == 0x01 && b[5] == 0x00) {
- return "ngg";
- }
- if (b[0] == 0x4E && b[1] == 0x4C && b[2] == 0x4D && b[3] == 0x20 && b[4] == 0x01 && b[5] == 0x02
- && b[6] == 0x00) {
- return "nlm";
- }
- if (b[0] == 0x4E && b[1] == 0x4F && b[2] == 0x4C && b[3] == 0x00 && b[4] == 0x01 && b[5] == 0x00
- && b[6] == 0x06 && b[7] == 0x01 && b[8] == 0x03 && b[9] == 0x00) {
- return "nol";
- }
- if (b[0] == 0x41 && b[1] == 0x48) {
- return "pal";
- }
- if (b[0] == 0x50 && b[1] == 0x41 && b[2] == 0x58) {
- return "pax";
- }
- if (b[0] == 0x63 && b[1] == 0x52 && b[2] == 0x01 && b[3] == 0x01 && b[4] == 0x38 && b[5] == 0x09
- && b[6] == 0x3D && b[7] == 0x00) {
- return "pcd";
- }
- if (b[0] == 0x1B && b[1] == 0x45 && b[2] == 0x1B && b[3] == 0x26 && b[4] == 0x6C && b[5] == 0x30
- && b[6] == 0x4F && b[7] == 0x1B && b[8] == 0x26 && b[9] == 0x6C && b[10] == 0x30
- && b[11] == 0x45 && b[12] == 0x1B && b[13] == 0x26) {
- return "pcl";
- }
- if (b[0] == 0x50 && b[1] == 0x49 && b[2] == 0x58 && b[3] == 0x20) {
- return "pix";
- }
- if (b[0] == 0x50 && b[1] == 0x4F && b[2] == 0x4C && b[3] == 0x20 && b[4] == 0x46 && b[5] == 0x6F
- && b[6] == 0x72 && b[7] == 0x6D && b[8] == 0x61 && b[9] == 0x74) {
- return "pol";
- }
- // Paint Shop Pro
- if (b[0] == 0x7E && b[1] == 0x42 && b[2] == 0x4B && b[3] == 0x00) {
- return "psp";
- }
- if (b[0] == 0x50 && b[1] == 0x61 && b[2] == 0x69 && b[3] == 0x6E && b[4] == 0x74 && b[5] == 0x20
- && b[6] == 0x53 && b[7] == 0x68 && b[8] == 0x6F && b[9] == 0x70 && b[10] == 0x20
- && b[11] == 0x50 && b[12] == 0x72 && b[13] == 0x6F && b[14] == 0x20 && b[15] == 0x49
- && b[16] == 0x6D && b[17] == 0x61 && b[18] == 0x67 && b[19] == 0x65 && b[20] == 0x20
- && b[21] == 0x46 && b[22] == 0x69 && b[23] == 0x6C && b[24] == 0x65) {
- return "psp";
- }
- if (b[0] == 0x51 && b[1] == 0x4C && b[2] == 0x49 && b[3] == 0x49 && b[4] == 0x46 && b[5] == 0x41
- && b[6] == 0x58) {
- return "qfx";
- }
- if (b[0] == 0x6D && b[1] == 0x6F && b[2] == 0x6F && b[3] == 0x76) {
- return "qtm";
- }
- if (b[0] == 0x46 && b[1] == 0x4F && b[2] == 0x52 && b[3] == 0x4D && b[4] == 0x41 && b[5] == 0x54
- && b[6] == 0x3D) {
- return "rad";
- }
- if (b[0] == 0x59 && b[1] == 0xA6 && b[2] == 0x6A && b[3] == 0x95) {
- return "ras";
- }
- if (b[0] == 0x52 && b[1] == 0x49 && b[2] == 0x58 && b[3] == 0x33) {
- return "rix";
- }
- if (b[0] == 0x23 && b[1] == 0x20 && b[2] == 0x24 && b[3] == 0x49 && b[4] == 0x64 && b[5] == 0x3A
- && b[6] == 0x20) {
- return "sid";
- }
- if (b[0] == 0x41 && b[1] == 0x75 && b[2] == 0x74 && b[3] == 0x6F && b[4] == 0x43 && b[5] == 0x41
- && b[6] == 0x44 && b[7] == 0x20 && b[8] == 0x53 && b[9] == 0x6C && b[10] == 0x69
- && b[11] == 0x64 && b[12] == 0x65) {
- return "sld";
- }
- if (b[0] == 0x53 && b[1] == 0x74 && b[2] == 0x6F && b[3] == 0x72 && b[4] == 0x6D && b[5] == 0x33
- && b[6] == 0x44) {
- return "sod";
- }
- if (b[0] == 0xFA && b[1] == 0xDE && b[2] == 0xBA && b[3] == 0xBE && b[4] == 0x01 && b[5] == 0x01) {
- return "wic";
- }
- if (b[0] == 0xD3 && b[1] == 0x23 && b[2] == 0x00 && b[3] == 0x00 && b[4] == 0x03 && b[5] == 0x00
- && b[6] == 0x00 && b[7] == 0x00) {
- return "wlm";
- }
- if (b[0] == 0xD7 && b[1] == 0xCD && b[2] == 0xC6 && b[3] == 0x9A) {
- return "wmf";
- }
- if (b[0] == 0xFF && b[1] == 0x57 && b[2] == 0x50 && b[3] == 0x43 && b[4] == 0x10) {
- return "wpg";
- }
- if (b[0] == 0x23 && b[1] == 0x56 && b[2] == 0x52 && b[3] == 0x4D && b[4] == 0x4C && b[5] == 0x20
- && b[6] == 0x56 && b[7] == 0x32 && b[8] == 0x2E && b[9] == 0x30) {
- return "wrl";
- }
- if (b[0] == 0x23 && b[1] == 0x64 && b[2] == 0x65 && b[3] == 0x66 && b[4] == 0x69 && b[5] == 0x6E
- && b[6] == 0x65) {
- return "xbm";
- }
- if (b[0] == 0x2F && b[1] == 0x2A && b[2] == 0x20 && b[3] == 0x58 && b[4] == 0x50 && b[5] == 0x4D
- && b[6] == 0x20 && b[7] == 0x2A && b[8] == 0x2F) {
- return "xpm";
- }
- return null;
- }
-}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/ImageSequence.java b/src/jogl/classes/com/jogamp/opengl/util/texture/ImageSequence.java
index 0f51c2e14..e485e5452 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/ImageSequence.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/ImageSequence.java
@@ -77,7 +77,7 @@ public class ImageSequence implements TextureSequence {
}
public final void addFrame(final GL gl, final Class<?> context, final String imageResourcePath, final String imageSuffix) throws IOException {
- final URLConnection urlConn = IOUtil.getResource(context, imageResourcePath);
+ final URLConnection urlConn = IOUtil.getResource(imageResourcePath, context.getClassLoader(), context);
if(null != urlConn) {
final TextureData texData = TextureIO.newTextureData(GLProfile.getGL2ES2(), urlConn.getInputStream(), false, imageSuffix);
final Texture tex = new Texture(getTextureTarget());
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/ImageType.java b/src/jogl/classes/com/jogamp/opengl/util/texture/ImageType.java
new file mode 100644
index 000000000..8a3bae554
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/ImageType.java
@@ -0,0 +1,1579 @@
+/**
+ * Copyright 2014 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.util.texture;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Image type classification.
+ * <p>
+ * Allows to classify the {@link ImageType} of an {@link InputStream} via {@link #ImageType(InputStream)}
+ * or to simply define one {@link ImageType} via {@link #ImageType(String)}.
+ * </p>
+ * @since 2.3.2
+ */
+public class ImageType {
+ /**
+ * Minimum number of bytes to determine the image data type, i.e. {@value} bytes.
+ */
+ public static final int MAGIC_MAX_SIZE = 25;
+
+ /**
+ * Constant which can be used as a file suffix to indicate a JPEG stream, value {@value}.
+ * <ul>
+ * <li>{@code http://www.faqs.org/faqs/jpeg-faq/part1/}</li>
+ * <li>{@code http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=54989}</li>
+ * </ul>
+ */
+ public static final String T_JPG = "jpg";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a PNG stream, value {@value}.
+ * <ul>
+ * <li>{@code http://www.libpng.org/pub/png/spec/1.1/PNG-Rationale.html#R.PNG-file-signature}</li>
+ * </ul>
+ */
+ public static final String T_PNG = "png";
+
+ /**
+ * Constant which can be used as a file suffix to indicate an Apple Icon Image stream, value {@value}.
+ * <p>
+ * {@code 'i' 'c' 'n' 's' ascii code}
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_ICNS = "icns";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a Microsoft Windows Icon stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code https://msdn.microsoft.com/en-us/library/ms997538.aspx}</li>
+ * </ul>
+ */
+ public static final String T_ICO = "ico";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a Microsoft Windows Cursor stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_CUR = "cur";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a GIF stream, value {@value}.
+ * <p>
+ * {@code GIF87A or GIF89A ascii code}
+ * </p>
+ * <ul>
+ * <li>{@code http://www.w3.org/Graphics/GIF/spec-gif87a.txt http://www.w3.org/Graphics/GIF/spec-gif89a.txt}</li>
+ * </ul>
+ */
+ public static final String T_GIF = "gif";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a GIF stream, value {@value}.
+ * <p>
+ * {@code BM ascii code}
+ * </p>
+ * <p>
+ * FIXME: Collision or supertype of {@link #T_DIB}?
+ * </p>
+ * <ul>
+ * <li>{@code http://www.fileformat.info/format/bmp/spec/e27073c25463436f8a64fa789c886d9c/view.htm}</li>
+ * </ul>
+ */
+ public static final String T_BMP = "bmp";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * FIXME: Collision or subtype of {@link #T_BMP}?
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_DIB = "dib";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_DCX = "dcx";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_PCX = "pcx";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a PAM stream, NetPbm magic 6 - binary RGB.
+ * <ul>
+ * <li>{@code http://netpbm.sourceforge.net/doc/ppm.html}</li>
+ * </ul>
+ */
+ public static final String T_PPM = "ppm";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a Adobe PhotoShop stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_PSD = "psd";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a TIFF stream, value {@value}.
+ * <p>
+ * Intentionally detects only the little endian tiff images ("II" in the spec).
+ * </p>
+ * <p>
+ * FIXME: Collision or supertype of {@link #T_LDF}?
+ * </p>
+ * <ul>
+ * <li>{@code http://partners.adobe.com/public/developer/en/tiff/TIFF6.pdf}</li>
+ * </ul>
+ */
+ public static final String T_TIFF = "tiff";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * FIXME: Collision or subtype of {@link #T_TIFF}?
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_LDF = "ldf";
+
+ /**
+ * Constant which can be used as a file suffix to indicate an SGI RGB stream, value {@value}.
+ * <p>
+ * "474 saved as a short" 474 = 0x01DA
+ * </p>
+ * <ul>
+ * <li>{@code http://paulbourke.net/dataformats/sgirgb/sgiversion.html}</li>
+ * </ul>
+ */
+ public static final String T_SGI_RGB = "rgb";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a DirectDraw Surface stream, value {@value}.
+ * <p>
+ * 'D' 'D' 'S' ' ' ascii code
+ * </p>
+ * <ul>
+ * <li>{@code https://msdn.microsoft.com/en-us/library/windows/desktop/bb943991%28v=vs.85%29.aspx#File_Layout1}</li>
+ * </ul>
+ */
+ public static final String T_DDS = "dds";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a Portable Arbitrary Map stream, NetPbm magic 7 - binary RGB and RGBA.
+ * <ul>
+ * <li>{@code http://netpbm.sourceforge.net/doc/pam.html}</li>
+ * </ul>
+ */
+ public static final String T_PAM = "pam";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a PGM stream, NetPbm magic 5 - binary grayscale.
+ * <ul>
+ * <li>{@code http://netpbm.sourceforge.net/doc/pgm.html}</li>
+ * </ul>
+ */
+ public static final String T_PGM = "pgm";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a PGM stream, NetPbm magic 4 - binary monochrome.
+ * <ul>
+ * <li>{@code http://netpbm.sourceforge.net/doc/pbm.html}</li>
+ * </ul>
+ */
+ public static final String T_PBM = "pbm";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_3D2 = "3d2";
+
+ /**
+ * Constant which can be used as a file suffix to indicate an Apple QuickDraw 3D 3DMF stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_3DMF = "3dmf";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a Texas Instruments TI-92 Bitmap stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_92I = "92i";
+
+ /**
+ * Constant which can be used as a file suffix to indicate an Amiga metafile stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_AMFF = "amff";
+
+ /**
+ * Constant which can be used as a file suffix to indicate an America Online Art stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_ART = "art";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a United States Department of Defence Continuous Acquisition and Life-cycle Support Raster stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code http://www.fileformat.info/format/cals/egff.htm}</li>
+ * </ul>
+ */
+ public static final String T_CALS = "cals";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_CAM = "cam";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_CBD = "cbd";
+
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_CE2 = "ce2";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a Kodak Cineon System stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code http://www.cineon.com/ff_draft.php}</li>
+ * </ul>
+ */
+ public static final String T_CIN = "cin";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_COB = "cob";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a Corel Photo Paint stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_CPT = "cpt";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_CVG = "cvg";
+
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_DEM = "dem";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a Digital Picture Exchange stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_DPX = "dpx";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_DRW = "drw";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a Autocad drawing stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_DWG = "dwg";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a Hexagon Geospatial Enhanced Compression Wavelet stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_ECW = "ecw";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a Microsoft Windows Enhanced metafile stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_EMF = "emf";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a FlashPix stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_FPX = "fpx";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_FTS = "fts";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_GRO = "gro";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_HDR = "hdr";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_HRU = "hru";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_IMG = "img";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_INFINI_D = "infini-d";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_IWC = "iwc";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_J6I = "j6i";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_JIF = "jif";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a JPEG-2000 stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_JP2 = "jp2";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_KDC = "kdc";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_L64 = "l64";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * FIXME: Collision or supertype of {@link #T_RAD}?
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_LBM = "lbm";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * FIXME: Collision or subtype of {@link #T_LBM}?
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_RAD = "rad";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_LWF = "lwf";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_MBM = "mbm";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_MGL = "mgl";
+
+ /**
+ * Constant which can be used as a file suffix to indicate an Imagemagick stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_MIF = "mif";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a Multiple-image Network Graphics stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_MNG = "mng";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_MPW = "mpw";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_MSP = "msp";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_N64 = "n64";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_NCR = "ncr";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_NFF = "nff";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_NGG = "ngg";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_NLM = "nlm";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_NOL = "nol";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_PAL = "pal";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_PAX = "pax";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_PCD = "pcd";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_PCL = "pcl";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a Softimage pic stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code http://paulbourke.net/dataformats/softimagepic/}</li>
+ * </ul>
+ */
+ public static final String T_PIC = "pic";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_PIX = "pix";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_POL = "pol";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a PaintShop Pro stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_PSP = "psp";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_QFX = "qfx";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_QTM = "qtm";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a Sun Raster stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_RAS = "ras";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_RIX = "rix";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_SID = "sid";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_SLD = "sld";
+
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_SOD = "sod";
+
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_WIC = "wic";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_WLM = "wlm";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_WMF = "wmf";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a Wordperfect Graphics vectors stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_WPG = "wpg";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_WRL = "wrl";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_XBM = "xbm";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a X PixMap stream, value {@value}.
+ * <p>
+ * TODO
+ * </p>
+ * <ul>
+ * <li>{@code TODO}</li>
+ * </ul>
+ */
+ public static final String T_XPM = "xpm";
+
+ /**
+ * Constant which can be used as a file suffix to indicate a Targa stream, value {@value}.
+ * <ul>
+ * <li>{@code }</li>
+ * </ul>
+ */
+ public static final String T_TGA = "tga";
+
+ /**
+ * The determined unique type, e.g. {@link #T_PNG}, {@link #T_JPG}, etc.
+ * <p>
+ * Maybe {@code null} if undetermined, i.e. {@link #isDefined()} returns {@code false}.
+ * </p>
+ */
+ public final String type;
+
+ /**
+ * The optionally read header of size {@link #MAGIC_MAX_SIZE} bytes as used to determine the {@link #type},
+ * i.e. {@link #ImageType(InputStream)}.
+ * <p>
+ * May be {@code null}, if {@link #type} has been determined otherwise, i.e {@link #ImageType(String)}.
+ * </p>
+ * <p>
+ * The header is <i>not</i> being used for {@link #hashCode()} and {@link #equals(Object)}!
+ * </p>
+ */
+ public final byte[] header;
+
+ private final int hash;
+
+ /**
+ * Creates instance based on given stream.
+ * @param stream stream to parse, {@link InputStream#available()} must be &ge; {@link #MAGIC_MAX_SIZE}
+ * @throws java.io.IOException if an I/O exception occurred
+ */
+ public ImageType(final InputStream stream) throws IOException {
+ final byte[] _header = new byte[MAGIC_MAX_SIZE];
+ type = Util.getFileSuffix(stream, _header);
+ this.header = _header;
+ this.hash = null != this.type ? this.type.hashCode() : 0;
+ }
+ /**
+ * Creates instance based on the given type.
+ * @param type must be one of {@link #T_PNG}, {@link #T_JPG}, etc.
+ */
+ public ImageType(final String type) {
+ this.header = null;
+ this.type = type;
+ this.hash = this.type.hashCode();
+ }
+ /** Returns {@code true} if {@link #type} is determined, i.e. not {@code null}, otherwise {@code false}. */
+ public final boolean isDefined() { return null != type; }
+
+ @Override
+ public final int hashCode() {
+ return hash;
+ }
+ @Override
+ public boolean equals(final Object o) {
+ if( o == this ) {
+ return true;
+ } else if( o instanceof ImageType ) {
+ final ImageType t = (ImageType)o;
+ return this.type.equals(t.type);
+ } else {
+ return false;
+ }
+ }
+ @Override
+ public String toString() { return "ImageType["+type+"]"; }
+
+ /**
+ * Static utility functions for {@link ImageType}
+ * to determine the {@link ImageType#type}.
+ * @since 2.3.2
+ */
+ public static class Util {
+ /**
+ * Determines the file suffix (i.e the image format) of the given InputStream. The given
+ * InputStream must return true from markSupported() and support a minimum of {@link #MAGIC_MAX_SIZE} bytes
+ * of read-ahead.
+ *
+ * @param stream stream to parse, {@link InputStream#available()} must be &ge; {@link #MAGIC_MAX_SIZE}
+ * @return the file suffix if any, otherwise <code>null</code>
+ * @throws java.io.IOException if an I/O exception occurred
+ */
+ public static String getFileSuffix(final InputStream stream) throws IOException {
+ return getFileSuffix(stream, new byte[MAGIC_MAX_SIZE]);
+ }
+ /**
+ * Determines the file suffix (i.e the image format) of the given InputStream. The given
+ * InputStream must return true from markSupported() and support a minimum of {@link #MAGIC_MAX_SIZE} bytes
+ * of read-ahead.
+ *
+ * @param stream stream to parse, {@link InputStream#available()} must be &ge; {@link #MAGIC_MAX_SIZE}
+ * @param b byte array sink, size must be &ge; {@link #MAGIC_MAX_SIZE}
+ * @return the file suffix if any, otherwise <code>null</code>
+ * @throws java.io.IOException if an I/O exception occurred
+ */
+ public static String getFileSuffix(InputStream stream, final byte[] b) throws IOException {
+ if (stream == null) {
+ throw new IOException("Stream was null");
+ }
+ if (!(stream instanceof BufferedInputStream)) {
+ stream = new BufferedInputStream(stream);
+ }
+ if (!stream.markSupported()) {
+ throw new IOException("Mark not supported");
+ }
+ if (stream.available() < MAGIC_MAX_SIZE) {
+ throw new IOException("Requires "+MAGIC_MAX_SIZE+" bytes, has "+stream.available()+" bytes");
+ }
+ try {
+ stream.mark(MAGIC_MAX_SIZE);
+ final int bytesRead = stream.read(b);
+ if( MAGIC_MAX_SIZE > bytesRead ) {
+ throw new IOException("Could not read "+MAGIC_MAX_SIZE+" bytes, read "+bytesRead+" bytes");
+ }
+ return getFileSuffix(b);
+ } finally {
+ stream.reset();
+ }
+
+ }
+
+ /**
+ * Determines the file suffix (i.e the image format) of the given bytes from the header
+ * of a file.
+ *
+ * @param b byte array to parse, size must be &ge; {@link #MAGIC_MAX_SIZE}
+ * @return the file suffix if any, otherwise <code>null</code>
+ * @throws java.io.IOException if an I/O exception occurred
+ */
+ public static String getFileSuffix(final byte[] b) {
+ if( b.length < MAGIC_MAX_SIZE ) {
+ throw new IllegalArgumentException("byte array must be >= "+MAGIC_MAX_SIZE+", has "+b.length);
+ }
+ final byte b0 = b[0];
+ final byte b1 = b[1];
+ final byte b2 = b[2];
+ final byte b3 = b[3];
+ final byte b4 = b[4];
+ final byte b5 = b[5];
+
+ // T_TGA: NO Signature!
+
+ if (b0 == (byte)0x00) {
+ if (b1 == (byte)0x00 && b2 == (byte)0x00 && b3 == (byte)0x0C &&
+ b4 == (byte)0x6A && b5 == (byte)0x50 &&
+ b[6] == (byte)0x20 && b[7] == (byte)0x20 && b[8] == (byte)0x0D && b[9] == (byte)0x0A && b[10] == (byte)0x87 &&
+ b[11] == (byte)0x0A) {
+ return T_JP2;
+ }
+ else if (b1 == (byte)0x01) {
+ return T_ICO;
+ }
+ else if (b1 == (byte)0x02) {
+ return T_CUR;
+ }
+ }
+ else if (b0 == (byte)0x01) {
+ if (b1 == (byte)0xDA /* && b2 == (byte)0x01 && b3 == (byte)0x01 && b4 == (byte)0x00 && b5 == (byte)0x03 */) {
+ return T_SGI_RGB;
+ }
+ else if (b1 == (byte)0xFF && b2 == (byte)0x02 && b3 == (byte)0x04 &&
+ b4 == (byte)0x03 && b5 == (byte)0x02) {
+ return T_DRW;
+ }
+ else if (b1 == (byte)0x00 && b2 == (byte)0x00 && b3 == (byte)0x00 &&
+ b4 == (byte)0x58 && b5 == (byte)0x00 &&
+ b[6] == (byte)0x00 && b[7] == (byte)0x00) {
+ return T_EMF;
+ }
+ }
+ else if (b0 == (byte)0x07 && b1 == (byte)0x20 && b2 == (byte)0x4D && b3 == (byte)0x4D) {
+ return T_CAM;
+ }
+ else if (b0 == (byte)0x0A && b1 == (byte)0x05 && b2 == (byte)0x01 && b3 == (byte)0x08) {
+ return T_PCX;
+ }
+ else if (b0 == (byte)0x1B && b1 == (byte)0x45 && b2 == (byte)0x1B && b3 == (byte)0x26 &&
+ b4 == (byte)0x6C && b5 == (byte)0x30 &&
+ b[6] == (byte)0x4F && b[7] == (byte)0x1B && b[8] == (byte)0x26 && b[9] == (byte)0x6C && b[10] == (byte)0x30 &&
+ b[11] == (byte)0x45 && b[12] == (byte)0x1B && b[13] == (byte)0x26) {
+ return T_PCL;
+ }
+ else if (b0 == (byte)0x20 && b1 == (byte)0x77 && b2 == (byte)0x00 && b3 == (byte)0x02) {
+ return T_CBD;
+ }
+ else if (b0 == (byte)0x23) {
+ if (b1 == (byte)0x20 && b2 == (byte)0x24 && b3 == (byte)0x49 &&
+ b4 == (byte)0x64 && b5 == (byte)0x3A &&
+ b[6] == (byte)0x20) {
+ return T_SID;
+ }
+ else if (b1 == (byte)0x56 && b2 == (byte)0x52 && b3 == (byte)0x4D &&
+ b4 == (byte)0x4C && b5 == (byte)0x20 &&
+ b[6] == (byte)0x56 && b[7] == (byte)0x32 && b[8] == (byte)0x2E && b[9] == (byte)0x30) {
+ return T_WRL;
+ }
+ else if (b1 == (byte)0x64 && b2 == (byte)0x65 && b3 == (byte)0x66 &&
+ b4 == (byte)0x69 && b5 == (byte)0x6E &&
+ b[6] == (byte)0x65) {
+ return T_XBM;
+ }
+ }
+ else if (b0 == (byte)0x2A && b1 == (byte)0x2A && b2 == (byte)0x54 && b3 == (byte)0x49 &&
+ b4 == (byte)0x39 && b5 == (byte)0x32 &&
+ b[6] == (byte)0x2A && b[7] == (byte)0x2A && b[8] == (byte)0x01 && b[9] == (byte)0x00 && b[10] == (byte)0x58 &&
+ b[11] == (byte)0x6E && b[12] == (byte)0x56 && b[13] == (byte)0x69) {
+ return T_92I;
+ }
+ else if (b0 == (byte)0x2F && b1 == (byte)0x2A && b2 == (byte)0x20 && b3 == (byte)0x58 &&
+ b4 == (byte)0x50 && b5 == (byte)0x4D &&
+ b[6] == (byte)0x20 && b[7] == (byte)0x2A && b[8] == (byte)0x2F) {
+ return T_XPM;
+ }
+ else if (b0 == (byte)0x33 && b1 == (byte)0x44 && b2 == (byte)0x4D && b3 == (byte)0x46) {
+ return T_3DMF;
+ }
+ else if (b0 == (byte)0x35 && b1 == (byte)0x4B && b2 == (byte)0x50 && b3 == (byte)0x35 &&
+ b4 == (byte)0x31 && b5 == (byte)0x5D &&
+ b[6] == (byte)0x2A && b[7] == (byte)0x67 && b[8] == (byte)0x72 && b[9] == (byte)0x72 && b[10] == (byte)0x80 &&
+ b[11] == (byte)0x83 && b[12] == (byte)0x85 && b[13] == (byte)0x63) {
+ return T_HRU;
+ }
+ else if (b0 == (byte)0x36 && b1 == (byte)0x34 && b2 == (byte)0x4C && b3 == (byte)0x41 &&
+ b4 == (byte)0x4E && b5 == (byte)0x20 &&
+ b[6] == (byte)0x49 && b[7] == (byte)0x44 && b[8] == (byte)0x42 && b[9] == (byte)0x4C && b[10] == (byte)0x4F &&
+ b[11] == (byte)0x43 && b[12] == (byte)0x4B) {
+ return T_L64;
+ }
+ else if (b0 == (byte)0x37 && b1 == (byte)0x00 && b2 == (byte)0x00 && b3 == (byte)0x10 &&
+ b4 == (byte)0x42 && b5 == (byte)0x00 &&
+ b[6] == (byte)0x00 && b[7] == (byte)0x10 && b[8] == (byte)0x00 && b[9] == (byte)0x00 && b[10] == (byte)0x00 &&
+ b[11] == (byte)0x00 && b[12] == (byte)0x39 && b[13] == (byte)0x64) {
+ return T_MBM;
+ }
+ else if (b0 == (byte)0x38 && b1 == (byte)0x42 && b2 == (byte)0x50 && b3 == (byte)0x53 &&
+ b4 == (byte)0x00 && b5 == (byte)0x01 &&
+ b[6] == (byte)0x00 && b[7] == (byte)0x00 && b[8] == (byte)0x00 && b[9] == (byte)0x00) {
+ return T_PSD;
+ }
+ else if (b0 == (byte)0x3A && b1 == (byte)0xDE && b2 == (byte)0x68 && b3 == (byte)0xB1) {
+ return T_DCX;
+ }
+ else if (b0 == (byte)0x3D && b1 == (byte)0x02) {
+ return T_3D2;
+ }
+ else if (b0 == (byte)0x41) {
+ if (b1 == (byte)0x43 && b2 == (byte)0x31 && b3 == (byte)0x30) {
+ return T_DWG;
+ }
+ else if (b1 == (byte)0x48) {
+ return T_PAL;
+ }
+ else if (b1 == (byte)0x4D && b2 == (byte)0x46 && b3 == (byte)0x46) {
+ return T_AMFF;
+ }
+ else if (b1 == (byte)0x75 && b2 == (byte)0x74 && b3 == (byte)0x6F &&
+ b4 == (byte)0x43 && b5 == (byte)0x41 &&
+ b[6] == (byte)0x44 && b[7] == (byte)0x20 && b[8] == (byte)0x53 && b[9] == (byte)0x6C && b[10] == (byte)0x69 &&
+ b[11] == (byte)0x64 && b[12] == (byte)0x65) {
+ return T_SLD;
+ }
+ }
+ else if (b0 == (byte)0x42 && b1 == (byte)0x4D) {
+ if (b2 == (byte)0x36) {
+ // FIXME: Collision or subtype of T_BMP?
+ return T_DIB;
+ } else {
+ return T_BMP;
+ }
+ }
+ else if (b0 == (byte)0x43) {
+ if (b1 == (byte)0x36 && b2 == (byte)0x34) {
+ return T_N64;
+ }
+ else if (b1 == (byte)0x41 && b2 == (byte)0x4C && b3 == (byte)0x41 &&
+ b4 == (byte)0x4D && b5 == (byte)0x55 &&
+ b[6] == (byte)0x53 && b[7] == (byte)0x43 && b[8] == (byte)0x56 && b[9] == (byte)0x47) {
+ return T_CVG;
+ }
+ else if (b1 == (byte)0x50 && b2 == (byte)0x54 && b3 == (byte)0x46 &&
+ b4 == (byte)0x49 && b5 == (byte)0x4C &&
+ b[6] == (byte)0x45) {
+ return T_CPT;
+ }
+ else if (b1 == (byte)0x61 && b2 == (byte)0x6C && b3 == (byte)0x69 &&
+ b4 == (byte)0x67 && b5 == (byte)0x61 &&
+ b[6] == (byte)0x72 && b[7] == (byte)0x69) {
+ return T_COB;
+ }
+ }
+ else if (b0 == (byte)0x44) {
+ if (b1 == (byte)0x44 && b2 == (byte)0x53 && b3 == (byte)0x20) {
+ return T_DDS;
+ }
+ else if (b1 == (byte)0x61 && b2 == (byte)0x6E && b3 == (byte)0x4D) {
+ return T_MSP;
+ }
+ }
+ else if (b0 == (byte)0x45) {
+ if (b1 == (byte)0x59 && b2 == (byte)0x45 && b3 == (byte)0x53) {
+ return T_CE2;
+ }
+ else if (b1 == (byte)0x78 && b2 == (byte)0x69 && b3 == (byte)0x66) { /* EXIF */
+ /**
+ * (b0 == (byte)0x45 && b1 == (byte)0x78 && b2 == (byte)0x69 && b3 == (byte)0x66) || // EXIF
+ * (b0 == (byte)0x4A && b1 == (byte)0x46 && b2 == (byte)0x49 && b3 == (byte)0x46) || // JFIF
+ * (b0 == (byte)0xff && b1 == (byte)0xd8 ) // && b2 == (byte)0xff
+ */
+ return T_JPG;
+ }
+ }
+ else if (b0 == (byte)0x46 && b1 == (byte)0x4F && b2 == (byte)0x52 && b3 == (byte)0x4D) {
+ if (b4 == (byte)0x41 && b5 == (byte)0x54 && b[6] == (byte)0x3D) {
+ // FIXME: Collision or subtype of T_LBM?
+ return T_RAD;
+ } else {
+ return T_LBM;
+ }
+ }
+ else if (b0 == (byte)0x47 && b1 == (byte)0x49 && b2 == (byte)0x46 && b3 == (byte)0x38 &&
+ (b4 == (byte)0x37 || b4 == (byte)0x39) && b5 == (byte)0x61) {
+ return T_GIF;
+ }
+ else if (b0 == (byte)0x48 && b1 == (byte)0x50 && b2 == (byte)0x48 && b3 == (byte)0x50 &&
+ b4 == (byte)0x34 && b5 == (byte)0x38 &&
+ b[6] == (byte)0x2D && b[7] == (byte)0x45 && b[8] == (byte)0x1E && b[9] == (byte)0x2B) {
+ return T_GRO;
+ }
+ else if (b0 == (byte)0x49) {
+ if (b1 == (byte)0x49 && b2 == (byte)0x2A && b3 == (byte)0x00) {
+ if (b4 == (byte)0x08 && b5 == (byte)0x00 &&
+ b[6] == (byte)0x00 && b[7] == (byte)0x00 && b[8] == (byte)0x0E && b[9] == (byte)0x00 && b[10] == (byte)0x00 &&
+ b[11] == (byte)0x01 && b[12] == (byte)0x04 && b[13] == (byte)0x00) {
+ // FIXME: Collision or subtype of T_TIFF?
+ return T_LDF;
+ } else {
+ return T_TIFF;
+ }
+ }
+ else if (b1 == (byte)0x57 && b2 == (byte)0x43 && b3 == (byte)0x01) {
+ return T_IWC;
+ }
+ }
+ else if (b0 == (byte)0x4A) {
+ if (b1 == (byte)0x46 && b2 == (byte)0x49 && b3 == (byte)0x46) { /* JFIF */
+ /**
+ * (b0 == (byte)0x45 && b1 == (byte)0x78 && b2 == (byte)0x69 && b3 == (byte)0x66) || // EXIF
+ * (b0 == (byte)0x4A && b1 == (byte)0x46 && b2 == (byte)0x49 && b3 == (byte)0x46) || // JFIF
+ * (b0 == (byte)0xff && b1 == (byte)0xd8 ) // && b2 == (byte)0xff
+ */
+ return T_JPG;
+ }
+ else if (b1 == (byte)0x47 && (b2 == (byte)0x03 || b2 == (byte)0x04) && b3 == (byte)0x0E &&
+ b4 == (byte)0x00 && b5 == (byte)0x00 &&
+ b[6] == (byte)0x00) {
+ return T_ART;
+ }
+ else if (b1 == (byte)0x49 && b2 == (byte)0x46 && b3 == (byte)0x39 &&
+ b4 == (byte)0x39 && b5 == (byte)0x61) {
+ return T_JIF;
+ }
+ }
+ else if (b0 == (byte)0x4D) {
+ if (b1 == (byte)0x47 && b2 == (byte)0x4C) {
+ return T_MGL;
+ }
+ else if (b1 == (byte)0x4D && b2 == (byte)0x00 && b3 == (byte)0x2A) {
+ return T_KDC;
+ }
+ else if (b1 == (byte)0x50 && b2 == (byte)0x46) {
+ return T_MPW;
+ }
+ }
+ else if (b0 == (byte)0x4E) {
+ if (b1 == (byte)0x47 && b2 == (byte)0x47 && b3 == (byte)0x00 &&
+ b4 == (byte)0x01 && b5 == (byte)0x00) {
+ return T_NGG;
+ }
+ else if (b1 == (byte)0x4C && b2 == (byte)0x4D && b3 == (byte)0x20 &&
+ b4 == (byte)0x01 && b5 == (byte)0x02 &&
+ b[6] == (byte)0x00) {
+ return T_NLM;
+ }
+ else if (b1 == (byte)0x4F && b2 == (byte)0x4C && b3 == (byte)0x00 &&
+ b4 == (byte)0x01 && b5 == (byte)0x00 &&
+ b[6] == (byte)0x06 && b[7] == (byte)0x01 && b[8] == (byte)0x03 && b[9] == (byte)0x00) {
+ return T_NOL;
+ }
+ }
+ else if (b0 == (byte)0x50) {
+ if (b1 == (byte)0x31 /* plain */|| b1 == (byte)0x34) {
+ return T_PBM;
+ }
+ else if (b1 == (byte)0x32 /* plain */|| b1 == (byte)0x35) {
+ return T_PGM;
+ }
+ else if (b1 == (byte)0x33 /* plain */|| b1 == (byte)0x36) {
+ return T_PPM;
+ }
+ else if (b1 == (byte)0x37) {
+ return T_PAM;
+ }
+ else if (b1 == (byte)0x41 && b2 == (byte)0x58) {
+ return T_PAX;
+ }
+ else if (b1 == (byte)0x49 && b2 == (byte)0x58 && b3 == (byte)0x20) {
+ return T_PIX;
+ }
+ else if (b1 == (byte)0x4F && b2 == (byte)0x4C && b3 == (byte)0x20 &&
+ b4 == (byte)0x46 && b5 == (byte)0x6F &&
+ b[6] == (byte)0x72 && b[7] == (byte)0x6D && b[8] == (byte)0x61 && b[9] == (byte)0x74) {
+ return T_POL;
+ }
+ else if (b1 == (byte)0x61 && b2 == (byte)0x69 && b3 == (byte)0x6E &&
+ b4 == (byte)0x74 && b5 == (byte)0x20 &&
+ b[6] == (byte)0x53 && b[7] == (byte)0x68 && b[8] == (byte)0x6F && b[9] == (byte)0x70 && b[10] == (byte)0x20 &&
+ b[11] == (byte)0x50 && b[12] == (byte)0x72 && b[13] == (byte)0x6F && b[14] == (byte)0x20 && b[15] == (byte)0x49 &&
+ b[16] == (byte)0x6D && b[17] == (byte)0x61 && b[18] == (byte)0x67 && b[19] == (byte)0x65 && b[20] == (byte)0x20 &&
+ b[21] == (byte)0x46 && b[22] == (byte)0x69 && b[23] == (byte)0x6C && b[24] == (byte)0x65) {
+ return T_PSP;
+ }
+ }
+ else if (b0 == (byte)0x51 && b1 == (byte)0x4C && b2 == (byte)0x49 && b3 == (byte)0x49 &&
+ b4 == (byte)0x46 && b5 == (byte)0x41 &&
+ b[6] == (byte)0x58) {
+ return T_QFX;
+ }
+ else if (b0 == (byte)0x52 && b1 == (byte)0x49 && b2 == (byte)0x58 && b3 == (byte)0x33) {
+ return T_RIX;
+ }
+ else if (b0 == (byte)0x53) {
+ if (b1 == (byte)0x44 && b2 == (byte)0x50 && b3 == (byte)0x58) {
+ return T_DPX;
+ }
+ else if (b1 == (byte)0x49 && b2 == (byte)0x4D && b3 == (byte)0x50 &&
+ b4 == (byte)0x4C && b5 == (byte)0x45 &&
+ b[6] == (byte)0x20 && b[7] == (byte)0x20 && b[8] == (byte)0x3D) {
+ return T_FTS;
+ }
+ else if (b1 == (byte)0x74 && b2 == (byte)0x6F && b3 == (byte)0x72 &&
+ b4 == (byte)0x6D && b5 == (byte)0x33 &&
+ b[6] == (byte)0x44) {
+ return T_SOD;
+ }
+ else if (b1 == (byte)0x80 && b2 == (byte)0xf6 && b3 == (byte)0x34) {
+ return T_PIC;
+ }
+ }
+ else if (b0 == (byte)0x56 && b1 == (byte)0x69 && b2 == (byte)0x73 && b3 == (byte)0x74 &&
+ b4 == (byte)0x61 && b5 == (byte)0x20 &&
+ b[6] == (byte)0x44 && b[7] == (byte)0x45 && b[8] == (byte)0x4D && b[9] == (byte)0x20 && b[10] == (byte)0x46 &&
+ b[11] == (byte)0x69 && b[12] == (byte)0x6C && b[13] == (byte)0x65) {
+ return T_DEM;
+ }
+ else if (b0 == (byte)0x57 && b1 == (byte)0x56 && b2 == (byte)0x02 && b3 == (byte)0x00 &&
+ b4 == (byte)0x47 && b5 == (byte)0x45 &&
+ b[6] == (byte)0x00 && b[7] == (byte)0x0E) {
+ return T_LWF;
+ }
+ else if (b0 == (byte)0x59 && b1 == (byte)0xA6 && b2 == (byte)0x6A && b3 == (byte)0x95) {
+ return T_RAS;
+ }
+ else if (b0 == (byte)0x63 && b1 == (byte)0x52 && b2 == (byte)0x01 && b3 == (byte)0x01 &&
+ b4 == (byte)0x38 && b5 == (byte)0x09 &&
+ b[6] == (byte)0x3D && b[7] == (byte)0x00) {
+ return T_PCD;
+ }
+ else if (b0 == (byte)0x65) {
+ if (b1 == (byte)0x02 && b2 == (byte)0x01 && b3 == (byte)0x02) {
+ return T_ECW;
+ }
+ else if (b1 == (byte)0x6C && b2 == (byte)0x6D && b3 == (byte)0x6F) {
+ return T_INFINI_D;
+ }
+ }
+ else if (b0 == (byte)0x69 && b1 == (byte)0x63 && b2 == (byte)0x6E && b3 == (byte)0x73) {
+ return T_ICNS;
+ }
+ else if (b0 == (byte)0x6D && b1 == (byte)0x6F && b2 == (byte)0x6F && b3 == (byte)0x76) {
+ return T_QTM;
+ }
+ else if (b0 == (byte)0x6E) {
+ if (b1 == (byte)0x63 && b2 == (byte)0x6F && b3 == (byte)0x6C &&
+ b4 == (byte)0x73) {
+ return T_HDR;
+ }
+ else if (b1 == (byte)0x66 && b2 == (byte)0x66) {
+ return T_NFF;
+ }
+ else if (b1 == (byte)0x6E && b2 == (byte)0x0A && b3 == (byte)0x00 &&
+ b4 == (byte)0x5E && b5 == (byte)0x00) {
+ return T_NCR;
+ }
+ }
+ else if (b0 == (byte)0x73 && b1 == (byte)0x72 && b2 == (byte)0x63 && b3 == (byte)0x64 &&
+ b4 == (byte)0x6F && b5 == (byte)0x63 &&
+ b[6] == (byte)0x69 && b[7] == (byte)0x64 && b[8] == (byte)0x3A) {
+ return T_CALS;
+ }
+ else if (b0 == (byte)0x7B && b1 == (byte)0x0A && b2 == (byte)0x20 && b3 == (byte)0x20 &&
+ b4 == (byte)0x43 && b5 == (byte)0x72 &&
+ b[6] == (byte)0x65 && b[7] == (byte)0x61 && b[8] == (byte)0x74 && b[9] == (byte)0x65 && b[10] == (byte)0x64) {
+ return T_MIF;
+ }
+ else if (b0 == (byte)0x7E && b1 == (byte)0x42 && b2 == (byte)0x4B && b3 == (byte)0x00) {
+ return T_PSP;
+ }
+ else if (b0 == (byte)0x80) {
+ if (b1 == (byte)0x2A && b2 == (byte)0x5F && b3 == (byte)0xD7 &&
+ b4 == (byte)0x00 && b5 == (byte)0x00 &&
+ b[6] == (byte)0x08 && b[7] == (byte)0x00 && b[8] == (byte)0x00 && b[9] == (byte)0x00 && b[10] == (byte)0x04 &&
+ b[11] == (byte)0x00 && b[12] == (byte)0x00 && b[13] == (byte)0x00) {
+ return T_CIN;
+ }
+ else if (b1 == (byte)0x3E && b2 == (byte)0x44 && b3 == (byte)0x53 &&
+ b4 == (byte)0x43 && b5 == (byte)0x49 &&
+ b[6] == (byte)0x4D) {
+ return T_J6I;
+ }
+ }
+ else if (b0 == (byte)0x89 && b1 == (byte)0x50 && b2 == (byte)0x4E && b3 == (byte)0x47 && /* 'P' 'N' 'G', ascii code */
+ b4 == (byte)0x0D && b5 == (byte)0x0A && b[6] == (byte)0x1A && b[7] == (byte)0x0A) {
+ // -119, 80, 78, 71, 13, 10, 26, 10
+ return T_PNG;
+ }
+ else if (b0 == (byte)0x8A && b1 == (byte)0x4D && b2 == (byte)0x4E && b3 == (byte)0x47 &&
+ b4 == (byte)0x0D && b5 == (byte)0x0A &&
+ b[6] == (byte)0x1A && b[7] == (byte)0x0A) {
+ return T_MNG;
+ }
+ else if (b0 == (byte)0xD0 && b1 == (byte)0xCF && b2 == (byte)0x11 && b3 == (byte)0xE0 &&
+ b4 == (byte)0xA1 && b5 == (byte)0xB1 &&
+ b[6] == (byte)0x1A && b[7] == (byte)0xE1 && b[8] == (byte)0x00) {
+ return T_FPX;
+ }
+ else if (b0 == (byte)0xD3 && b1 == (byte)0x23 && b2 == (byte)0x00 && b3 == (byte)0x00 &&
+ b4 == (byte)0x03 && b5 == (byte)0x00 &&
+ b[6] == (byte)0x00 && b[7] == (byte)0x00) {
+ return T_WLM;
+ }
+ else if (b0 == (byte)0xD7 && b1 == (byte)0xCD && b2 == (byte)0xC6 && b3 == (byte)0x9A) {
+ return T_WMF;
+ }
+ else if (b0 == (byte)0xEB && b1 == (byte)0x3C && b2 == (byte)0x90 && b3 == (byte)0x2A) {
+ return T_IMG;
+ }
+ else if (b0 == (byte)0xFA && b1 == (byte)0xDE && b2 == (byte)0xBA && b3 == (byte)0xBE &&
+ b4 == (byte)0x01 && b5 == (byte)0x01) {
+ return T_WIC;
+ }
+ else if (b0 == (byte)0xFF) {
+ if (b1 == (byte)0xD8 /* && b2 == (byte)0xff */) {
+ /**
+ * (b0 == (byte)0x45 && b1 == (byte)0x78 && b2 == (byte)0x69 && b3 == (byte)0x66) || // EXIF
+ * (b0 == (byte)0x4A && b1 == (byte)0x46 && b2 == (byte)0x49 && b3 == (byte)0x46) || // JFIF
+ * (b0 == (byte)0xff && b1 == (byte)0xd8 ) // && b2 == (byte)0xff
+ */
+ return T_JPG;
+ }
+ else if (b1 == (byte)0x57 && b2 == (byte)0x50 && b3 == (byte)0x43 && b4 == (byte)0x10) {
+ return T_WPG;
+ }
+ }
+ return null;
+ }
+ }
+}
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 18a7527b6..bdaa2d792 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java
@@ -163,8 +163,10 @@ import com.jogamp.opengl.util.texture.spi.*;
* @author Chris Campbell, Kenneth Russell, et.al.
*/
public class Texture {
- /** The GL target type. */
+ /** The GL target type for this texture. */
private int target;
+ /** The image GL target type for this texture, or its sub-components if cubemap. */
+ private int imageTarget;
/** The GL texture ID. */
private int texID;
/** The width of the texture. */
@@ -190,7 +192,8 @@ public class Texture {
@Override
public String toString() {
- return "Texture[target 0x"+Integer.toHexString(target)+", name "+texID+", "+
+ final String targetS = target == imageTarget ? Integer.toHexString(target) : Integer.toHexString(target) + " - image "+Integer.toHexString(imageTarget);
+ return "Texture[target "+targetS+", name "+texID+", "+
imgWidth+"/"+texWidth+" x "+imgHeight+"/"+texHeight+", y-flip "+mustFlipVertically+
", "+estimatedMemorySize+" bytes]";
}
@@ -206,7 +209,9 @@ public class Texture {
private static final boolean disableTexRect = Debug.isPropertyDefined("jogl.texture.notexrect", true);
public Texture(final GL gl, final TextureData data) throws GLException {
- texID = 0;
+ this.texID = 0;
+ this.target = 0;
+ this.imageTarget = 0;
updateImage(gl, data);
}
@@ -217,8 +222,9 @@ public class Texture {
* GL2.GL_TEXTURE_RECTANGLE
*/
public Texture(final int target) {
- texID = 0;
+ this.texID = 0;
this.target = target;
+ this.imageTarget = target;
}
/**
@@ -250,11 +256,14 @@ public class Texture {
final boolean mustFlipVertically) {
this.texID = textureID;
this.target = target;
+ this.imageTarget = target;
this.mustFlipVertically = mustFlipVertically;
this.texWidth = texWidth;
this.texHeight = texHeight;
- aspectRatio = (float) imgWidth / (float) imgHeight;
- setImageSize(imgWidth, imgHeight, target);
+ this.aspectRatio = (float) imgWidth / (float) imgHeight;
+ this.imgWidth = imgWidth;
+ this.imgHeight = imgHeight;
+ this.updateTexCoords();
}
/**
@@ -344,8 +353,6 @@ public class Texture {
/**
* Returns the OpenGL "target" of this texture.
- *
- * @return the OpenGL target of this texture
* @see com.jogamp.opengl.GL#GL_TEXTURE_2D
* @see com.jogamp.opengl.GL2#GL_TEXTURE_RECTANGLE_ARB
*/
@@ -354,6 +361,15 @@ public class Texture {
}
/**
+ * Returns the image OpenGL "target" of this texture, or its sub-components if cubemap.
+ * @see com.jogamp.opengl.GL#GL_TEXTURE_2D
+ * @see com.jogamp.opengl.GL2#GL_TEXTURE_RECTANGLE_ARB
+ */
+ public int getImageTarget() {
+ return imageTarget;
+ }
+
+ /**
* Returns the width of the allocated OpenGL texture in pixels.
* Note that the texture width will be greater than or equal to the
* width of the image contained within.
@@ -438,7 +454,7 @@ public class Texture {
* @return the texture coordinates corresponding to the specified sub-image
*/
public TextureCoords getSubImageTexCoords(final int x1, final int y1, final int x2, final int y2) {
- if (target == GL2.GL_TEXTURE_RECTANGLE_ARB) {
+ if (GL2.GL_TEXTURE_RECTANGLE_ARB == imageTarget) {
if (mustFlipVertically) {
return new TextureCoords(x1, texHeight - y1, x2, texHeight - y2);
} else {
@@ -616,17 +632,17 @@ public class Texture {
texHeight = nextPowerOfTwo(imgHeight);
texTarget = GL.GL_TEXTURE_2D;
}
-
texParamTarget = texTarget;
- setImageSize(imgWidth, imgHeight, texTarget);
+ imageTarget = texTarget;
+ updateTexCoords();
if (targetOverride != 0) {
// Allow user to override auto detection and skip bind step (for
// cubemap construction)
- texTarget = targetOverride;
if (this.target == 0) {
throw new GLException("Override of target failed; no target specified yet");
}
+ texTarget = targetOverride;
texParamTarget = this.target;
gl.glBindTexture(texParamTarget, texID);
} else {
@@ -977,17 +993,8 @@ public class Texture {
return ret;
}
- /**
- * Updates the actual image dimensions; usually only called from
- * <code>updateImage</code>.
- */
- private void setImageSize(final int width, final int height, final int target) {
- imgWidth = width;
- imgHeight = height;
- updateTexCoords();
- }
private void updateTexCoords() {
- if (target == GL2.GL_TEXTURE_RECTANGLE_ARB) {
+ if ( GL2.GL_TEXTURE_RECTANGLE_ARB == imageTarget ) {
if (mustFlipVertically) {
coords = new TextureCoords(0, imgHeight, imgWidth, 0);
} else {
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureData.java b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureData.java
index 615d8c24f..5799f95a6 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureData.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureData.java
@@ -83,6 +83,9 @@ public class TextureData {
protected GLProfile glProfile;
protected ColorSpace pixelCS = ColorSpace.RGB;
+ // TODO: final, and set via ctor for 2.4.X
+ /* pp */ ImageType srcImageType;
+
/**
* Constructs a new TextureData object with the specified parameters
* and data contained in the given Buffer. The optional Flusher can
@@ -341,6 +344,14 @@ public class TextureData {
/** Used only by subclasses */
protected TextureData(final GLProfile glp) { this.glProfile = glp; this.pixelAttributes = GLPixelAttributes.UNDEF; }
+ /**
+ * Returns the source {@link ImageType} if applicable and known, otherwise {@code null}.
+ * @since 2.3.2
+ */
+ public final ImageType getSourceImageType() {
+ return srcImageType;
+ }
+
/** Returns the width in pixels of the texture data. */
public int getWidth() { return width; }
/** Returns the height in pixels of the texture data. */
@@ -501,8 +512,9 @@ public class TextureData {
@Override
public String toString() {
+ final String optImageType = null != srcImageType ? ", "+srcImageType : "";
return "TextureData["+width+"x"+height+", y-flip "+mustFlipVertically+", internFormat 0x"+Integer.toHexString(internalFormat)+", "+
- pixelAttributes+", border "+border+", estSize "+estimatedMemorySize+", alignment "+alignment+", rowlen "+rowLength;
+ pixelAttributes+", border "+border+", estSize "+estimatedMemorySize+", alignment "+alignment+", rowlen "+rowLength+optImageType;
}
//----------------------------------------------------------------------
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java
index 80b195642..2ac7c796d 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java
@@ -52,8 +52,10 @@ import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import com.jogamp.nativewindow.util.Dimension;
import com.jogamp.nativewindow.util.DimensionImmutable;
@@ -72,6 +74,7 @@ import com.jogamp.common.util.IOUtil;
import com.jogamp.opengl.util.GLPixelStorageModes;
import com.jogamp.opengl.util.PNGPixelRect;
import com.jogamp.opengl.util.GLPixelBuffer.GLPixelAttributes;
+import com.jogamp.opengl.util.texture.ImageType;
import com.jogamp.opengl.util.texture.spi.DDSImage;
import com.jogamp.opengl.util.texture.spi.JPEGImage;
import com.jogamp.opengl.util.texture.spi.NetPbmTextureWriter;
@@ -134,44 +137,60 @@ import com.jogamp.opengl.util.texture.spi.TextureWriter;
public class TextureIO {
/** Constant which can be used as a file suffix to indicate a
- DirectDraw Surface file. */
- public static final String DDS = "dds";
+ DirectDraw Surface file, value {@value}.
+ <p>Alias for {@link ImageType#T_DDS}.</p>
+ */
+ public static final String DDS = ImageType.T_DDS;
- /** Constant which can be used as a file suffix to indicate an SGI
- RGB file. */
+ /**
+ * Constant which can be used as a file suffix to indicate an SGI RGB file, value {@value}.
+ * <p>
+ * Same semantics as {@link ImageType#SGI_RGB} and {@link #SGI_RGB}.
+ * </p>
+ */
public static final String SGI = "sgi";
- /** Constant which can be used as a file suffix to indicate an SGI
- RGB file. */
- public static final String SGI_RGB = "rgb";
+ /** Constant which can be used as a file suffix to indicate an SGI RGB file, value {@value}.
+ <p>Alias for {@link ImageType#T_SGI_RGB}. </p>
+ */
+ public static final String SGI_RGB = ImageType.T_SGI_RGB;
- /** Constant which can be used as a file suffix to indicate a GIF
- file. */
- public static final String GIF = "gif";
+ /** Constant which can be used as a file suffix to indicate a GIF file, value {@value}.
+ <p>Alias for {@link ImageType#T_GIF}.</p>
+ */
+ public static final String GIF = ImageType.T_GIF;
- /** Constant which can be used as a file suffix to indicate a JPEG
- file. */
- public static final String JPG = "jpg";
+ /** Constant which can be used as a file suffix to indicate a JPEG file, value {@value}.
+ <p>Alias for {@link ImageType#T_JPG}.</p>
+ */
+ public static final String JPG = ImageType.T_JPG;
- /** Constant which can be used as a file suffix to indicate a PNG
- file. */
- public static final String PNG = "png";
+ /** Constant which can be used as a file suffix to indicate a PNG file, value {@value}.
+ <p>Alias for {@link ImageType#T_PNG}.</p>
+ */
+ public static final String PNG = ImageType.T_PNG;
- /** Constant which can be used as a file suffix to indicate a Targa
- file. */
- public static final String TGA = "tga";
+ /** Constant which can be used as a file suffix to indicate a Targa file, value {@value}.
+ <p>Alias for {@link ImageType#T_TGA}.</p>
+ */
+ public static final String TGA = ImageType.T_TGA;
- /** Constant which can be used as a file suffix to indicate a TIFF
- file. */
- public static final String TIFF = "tiff";
+ /** Constant which can be used as a file suffix to indicate a TIFF file, value {@value}.
+ <p>Alias for {@link ImageType#T_TIFF}.</p>
+ */
+ public static final String TIFF = ImageType.T_TIFF;
/** Constant which can be used as a file suffix to indicate a PAM
- file, NetPbm magic 7 - binary RGB and RGBA. Write support only. */
- public static final String PAM = "pam";
+ file, NetPbm magic 7 - binary RGB and RGBA. Write support only, value {@value}.
+ <p>Alias for {@link ImageType#T_PAM}.</p>
+ */
+ public static final String PAM = ImageType.T_PAM;
/** Constant which can be used as a file suffix to indicate a PAM
- file, NetPbm magic 6 - binary RGB. Write support only. */
- public static final String PPM = "ppm";
+ file, NetPbm magic 6 - binary RGB. Write support only, value {@value}.
+ <p>Alias for {@link ImageType#T_PPM}.</p>
+ */
+ public static final String PPM = ImageType.T_PPM;
private static final boolean DEBUG = Debug.debug("TextureIO");
@@ -677,16 +696,27 @@ public class TextureIO {
//
/**
- * Adds a TextureProvider to support reading of a new file format.
+ * Adds a {@link TextureProvider} to support reading of a new file format.
* <p>
* The last provider added, will be the first provider to be tested.
* </p>
+ * <p>
+ * The {@link TextureProvider} is being mapped to its supporting {@link ImageType}s
+ * allowing an O(1) association, if {@link TextureProvider#}
+ * </p>
*/
public static void addTextureProvider(final TextureProvider provider) {
// Must always add at the front so the ImageIO provider is last,
// so we don't accidentally use it instead of a user's possibly
// more optimal provider
textureProviders.add(0, provider);
+
+ final ImageType[] imageTypes = provider.getImageTypes();
+ if( null != imageTypes ) {
+ for(int i=0; i<imageTypes.length; i++) {
+ imageType2TextureProvider.put(imageTypes[i], provider);
+ }
+ }
}
/**
@@ -736,6 +766,7 @@ public class TextureIO {
//
private static List<TextureProvider> textureProviders = new ArrayList<TextureProvider>();
+ private static Map<ImageType,TextureProvider> imageType2TextureProvider = new HashMap<ImageType,TextureProvider>();
private static List<TextureWriter> textureWriters = new ArrayList<TextureWriter>();
static {
@@ -787,32 +818,6 @@ public class TextureIO {
}
// Implementation methods
- private static TextureData newTextureDataImpl(final GLProfile glp, final File file,
- final int internalFormat,
- final int pixelFormat,
- final boolean mipmap,
- String fileSuffix) throws IOException {
- if (file == null) {
- throw new IOException("File was null");
- }
-
- fileSuffix = toLowerCase(fileSuffix);
-
- for (final Iterator<TextureProvider> iter = textureProviders.iterator(); iter.hasNext(); ) {
- final TextureProvider provider = iter.next();
- final TextureData data = provider.newTextureData(glp, file,
- internalFormat,
- pixelFormat,
- mipmap,
- fileSuffix);
- if (data != null) {
- return data;
- }
- }
-
- throw new IOException("No suitable reader for given file "+file.getAbsolutePath());
- }
-
private static TextureData newTextureDataImpl(final GLProfile glp, InputStream stream,
final int internalFormat,
final int pixelFormat,
@@ -822,70 +827,97 @@ public class TextureIO {
throw new IOException("Stream was null");
}
- fileSuffix = toLowerCase(fileSuffix);
-
// Note: use of BufferedInputStream works around 4764639/4892246
if (!(stream instanceof BufferedInputStream)) {
stream = new BufferedInputStream(stream);
}
+ // First attempt to use an ImageType mapped TextureProvider for O(1)
+ // using stream parsed data, ignoring the given fileSuffix!
+ try {
+ final ImageType imageType = new ImageType(stream);
+ if( imageType.isDefined() ) {
+ final TextureProvider mappedProvider = imageType2TextureProvider.get(imageType);
+ if( null != mappedProvider ) {
+ final TextureData data = mappedProvider.newTextureData(glp, stream,
+ internalFormat,
+ pixelFormat,
+ mipmap,
+ imageType.type);
+ if (data != null) {
+ data.srcImageType = imageType;
+ return data;
+ }
+ }
+ }
+ } catch (final IOException ioe) {
+ if(DEBUG) {
+ System.err.println("Caught "+ioe.getMessage());
+ ioe.printStackTrace();
+ }
+ }
+
+ fileSuffix = toLowerCase(fileSuffix);
+
for (final Iterator<TextureProvider> iter = textureProviders.iterator(); iter.hasNext(); ) {
final TextureProvider provider = iter.next();
final TextureData data = provider.newTextureData(glp, stream,
- internalFormat,
- pixelFormat,
- mipmap,
- fileSuffix);
+ internalFormat,
+ pixelFormat,
+ mipmap,
+ fileSuffix);
if (data != null) {
+ final ImageType[] imageTypes = provider.getImageTypes();
+ data.srcImageType = null != imageTypes ? imageTypes[0] : null;
return data;
}
}
throw new IOException("No suitable reader for given stream");
}
-
+ private static TextureData newTextureDataImpl(final GLProfile glp, final File file,
+ final int internalFormat,
+ final int pixelFormat,
+ final boolean mipmap,
+ final String fileSuffix) throws IOException {
+ if (file == null) {
+ throw new IOException("File was null");
+ }
+ final InputStream stream = new BufferedInputStream(new FileInputStream(file));
+ try {
+ return newTextureDataImpl( glp, stream, internalFormat, pixelFormat, mipmap,
+ (fileSuffix != null) ? fileSuffix : IOUtil.getFileSuffix(file) );
+ } catch(final IOException ioe) {
+ throw new IOException(ioe.getMessage()+", given file "+file.getAbsolutePath(), ioe);
+ } finally {
+ stream.close();
+ }
+ }
private static TextureData newTextureDataImpl(final GLProfile glp, final URL url,
final int internalFormat,
final int pixelFormat,
final boolean mipmap,
- String fileSuffix) throws IOException {
+ final String fileSuffix) throws IOException {
if (url == null) {
throw new IOException("URL was null");
}
-
- fileSuffix = toLowerCase(fileSuffix);
-
- for (final Iterator<TextureProvider> iter = textureProviders.iterator(); iter.hasNext(); ) {
- final TextureProvider provider = iter.next();
- final TextureData data = provider.newTextureData(glp, url,
- internalFormat,
- pixelFormat,
- mipmap,
- fileSuffix);
- if (data != null) {
- return data;
- }
+ final InputStream stream = new BufferedInputStream(url.openStream());
+ try {
+ return newTextureDataImpl(glp, stream, internalFormat, pixelFormat, mipmap, fileSuffix);
+ } catch(final IOException ioe) {
+ throw new IOException(ioe.getMessage()+", given URL "+url, ioe);
+ } finally {
+ stream.close();
}
-
- throw new IOException("No suitable reader for given URL "+url);
}
//----------------------------------------------------------------------
- // DDS provider -- supports files only for now
+ // DDS image provider
static class DDSTextureProvider implements TextureProvider {
+ private static final ImageType[] imageTypes = new ImageType[] { new ImageType(ImageType.T_DDS) };
@Override
- public TextureData newTextureData(final GLProfile glp, final File file,
- final int internalFormat,
- final int pixelFormat,
- final boolean mipmap,
- final String fileSuffix) throws IOException {
- if (DDS.equals(fileSuffix) ||
- DDS.equals(IOUtil.getFileSuffix(file))) {
- final DDSImage image = DDSImage.read(file);
- return newTextureData(glp, image, internalFormat, pixelFormat, mipmap);
- }
-
- return null;
+ public final ImageType[] getImageTypes() {
+ return imageTypes;
}
@Override
@@ -894,8 +926,8 @@ public class TextureIO {
final int pixelFormat,
final boolean mipmap,
final String fileSuffix) throws IOException {
- if (DDS.equals(fileSuffix) ||
- DDS.equals(ImageIOUtil.getFileSuffix(stream))) {
+ if (ImageType.T_DDS.equals(fileSuffix) ||
+ ImageType.T_DDS.equals(ImageType.Util.getFileSuffix(stream))) {
final byte[] data = IOUtil.copyStream2ByteArray(stream);
final ByteBuffer buf = ByteBuffer.wrap(data);
final DDSImage image = DDSImage.read(buf);
@@ -905,20 +937,6 @@ public class TextureIO {
return null;
}
- @Override
- public TextureData newTextureData(final GLProfile glp, final URL url,
- final int internalFormat,
- final int pixelFormat,
- final boolean mipmap,
- final String fileSuffix) throws IOException {
- final InputStream stream = new BufferedInputStream(url.openStream());
- try {
- return newTextureData(glp, stream, internalFormat, pixelFormat, mipmap, fileSuffix);
- } finally {
- stream.close();
- }
- }
-
private TextureData newTextureData(final GLProfile glp, final DDSImage image,
int internalFormat,
int pixelFormat,
@@ -1003,47 +1021,14 @@ public class TextureIO {
}
//----------------------------------------------------------------------
- // Base class for SGI RGB and TGA image providers
- static abstract class StreamBasedTextureProvider implements TextureProvider {
- @Override
- public TextureData newTextureData(final GLProfile glp, final File file,
- final int internalFormat,
- final int pixelFormat,
- final boolean mipmap,
- final String fileSuffix) throws IOException {
- final InputStream inStream = new BufferedInputStream(new FileInputStream(file));
- try {
- // The SGIImage and TGAImage implementations use InputStreams
- // anyway so there isn't much point in having a separate code
- // path for files
- return newTextureData(glp, inStream,
- internalFormat,
- pixelFormat,
- mipmap,
- ((fileSuffix != null) ? fileSuffix : IOUtil.getFileSuffix(file)));
- } finally {
- inStream.close();
- }
- }
-
+ // SGI RGB image provider
+ static class SGITextureProvider implements TextureProvider {
+ private static final ImageType[] imageTypes = new ImageType[] { new ImageType(ImageType.T_SGI_RGB) };
@Override
- public TextureData newTextureData(final GLProfile glp, final URL url,
- final int internalFormat,
- final int pixelFormat,
- final boolean mipmap,
- final String fileSuffix) throws IOException {
- final InputStream stream = new BufferedInputStream(url.openStream());
- try {
- return newTextureData(glp, stream, internalFormat, pixelFormat, mipmap, fileSuffix);
- } finally {
- stream.close();
- }
+ public final ImageType[] getImageTypes() {
+ return imageTypes;
}
- }
- //----------------------------------------------------------------------
- // SGI RGB image provider
- static class SGITextureProvider extends StreamBasedTextureProvider {
@Override
public TextureData newTextureData(final GLProfile glp, final InputStream stream,
int internalFormat,
@@ -1051,9 +1036,9 @@ public class TextureIO {
final boolean mipmap,
final String fileSuffix) throws IOException {
if (SGI.equals(fileSuffix) ||
- SGI_RGB.equals(fileSuffix) ||
- SGI.equals(ImageIOUtil.getFileSuffix(stream)) ||
- SGI_RGB.equals(ImageIOUtil.getFileSuffix(stream))) {
+ ImageType.T_SGI_RGB.equals(fileSuffix) ||
+ SGI.equals(ImageType.Util.getFileSuffix(stream)) ||
+ ImageType.T_SGI_RGB.equals(ImageType.Util.getFileSuffix(stream))) {
final SGIImage image = SGIImage.read(stream);
if (pixelFormat == 0) {
pixelFormat = image.getFormat();
@@ -1080,14 +1065,20 @@ public class TextureIO {
//----------------------------------------------------------------------
// TGA (Targa) image provider
- static class TGATextureProvider extends StreamBasedTextureProvider {
+ static class TGATextureProvider implements TextureProvider {
+ private static final ImageType[] imageTypes = new ImageType[] { new ImageType(ImageType.T_TGA) };
+ @Override
+ public final ImageType[] getImageTypes() {
+ return imageTypes;
+ }
+
@Override
public TextureData newTextureData(final GLProfile glp, final InputStream stream,
int internalFormat,
int pixelFormat,
final boolean mipmap,
final String fileSuffix) throws IOException {
- if (TGA.equals(fileSuffix)) {
+ if (ImageType.T_TGA.equals(fileSuffix)) {
final TGAImage image = TGAImage.read(glp, stream);
if (pixelFormat == 0) {
pixelFormat = image.getGLFormat();
@@ -1118,15 +1109,21 @@ public class TextureIO {
//----------------------------------------------------------------------
// PNG image provider
- static class PNGTextureProvider extends StreamBasedTextureProvider {
+ static class PNGTextureProvider implements TextureProvider {
+ private static final ImageType[] imageTypes = new ImageType[] { new ImageType(ImageType.T_PNG) };
+ @Override
+ public final ImageType[] getImageTypes() {
+ return imageTypes;
+ }
+
@Override
public TextureData newTextureData(final GLProfile glp, final InputStream stream,
int internalFormat,
int pixelFormat,
final boolean mipmap,
final String fileSuffix) throws IOException {
- if (PNG.equals(fileSuffix) ||
- PNG.equals(ImageIOUtil.getFileSuffix(stream))) {
+ if (ImageType.T_PNG.equals(fileSuffix) ||
+ ImageType.T_PNG.equals(ImageType.Util.getFileSuffix(stream))) {
final PNGPixelRect image = PNGPixelRect.read(stream, null, true /* directBuffer */, 0 /* destMinStrideInBytes */, true /* destIsGLOriented */);
final GLPixelAttributes glpa = new GLPixelAttributes(glp, image.getPixelformat(), false /* pack */);
if ( 0 == pixelFormat ) {
@@ -1159,15 +1156,21 @@ public class TextureIO {
//----------------------------------------------------------------------
// JPEG image provider
- static class JPGTextureProvider extends StreamBasedTextureProvider {
+ static class JPGTextureProvider implements TextureProvider {
+ private static final ImageType[] imageTypes = new ImageType[] { new ImageType(ImageType.T_JPG) };
+ @Override
+ public final ImageType[] getImageTypes() {
+ return imageTypes;
+ }
+
@Override
public TextureData newTextureData(final GLProfile glp, final InputStream stream,
int internalFormat,
int pixelFormat,
final boolean mipmap,
final String fileSuffix) throws IOException {
- if (JPG.equals(fileSuffix) ||
- JPG.equals(ImageIOUtil.getFileSuffix(stream))) {
+ if (ImageType.T_JPG.equals(fileSuffix) ||
+ ImageType.T_JPG.equals(ImageType.Util.getFileSuffix(stream))) {
final JPEGImage image = JPEGImage.read(/*glp, */ stream);
if (pixelFormat == 0) {
pixelFormat = image.getGLFormat();
@@ -1203,7 +1206,7 @@ public class TextureIO {
@Override
public boolean write(final File file,
final TextureData data) throws IOException {
- if (DDS.equals(IOUtil.getFileSuffix(file))) {
+ if (ImageType.T_DDS.equals(IOUtil.getFileSuffix(file))) {
// See whether the DDS writer can handle this TextureData
final GLPixelAttributes pixelAttribs = data.getPixelAttributes();
final int pixelFormat = pixelAttribs.format;
@@ -1256,7 +1259,7 @@ public class TextureIO {
final TextureData data) throws IOException {
final String fileSuffix = IOUtil.getFileSuffix(file);
if (SGI.equals(fileSuffix) ||
- SGI_RGB.equals(fileSuffix)) {
+ ImageType.T_SGI_RGB.equals(fileSuffix)) {
// See whether the SGI writer can handle this TextureData
final GLPixelAttributes pixelAttribs = data.getPixelAttributes();
final int pixelFormat = pixelAttribs.format;
@@ -1300,7 +1303,7 @@ public class TextureIO {
@Override
public boolean write(final File file,
final TextureData data) throws IOException {
- if (TGA.equals(IOUtil.getFileSuffix(file))) {
+ if (ImageType.T_TGA.equals(IOUtil.getFileSuffix(file))) {
// See whether the TGA writer can handle this TextureData
final GLPixelAttributes pixelAttribs = data.getPixelAttributes();
final int pixelFormat = pixelAttribs.format;
@@ -1350,7 +1353,7 @@ public class TextureIO {
static class PNGTextureWriter implements TextureWriter {
@Override
public boolean write(final File file, final TextureData data) throws IOException {
- if (PNG.equals(IOUtil.getFileSuffix(file))) {
+ if (ImageType.T_PNG.equals(IOUtil.getFileSuffix(file))) {
// See whether the PNG writer can handle this TextureData
final GLPixelAttributes pixelAttribs = data.getPixelAttributes();
final int pixelFormat = pixelAttribs.format;
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/DDSImage.java b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/DDSImage.java
index 36c44a409..246676aae 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/DDSImage.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/DDSImage.java
@@ -53,8 +53,7 @@ import java.nio.channels.FileChannel;
import com.jogamp.opengl.GL;
import com.jogamp.common.nio.Buffers;
import com.jogamp.common.util.IOUtil;
-import com.jogamp.opengl.util.GLBuffers;
-import com.jogamp.opengl.util.texture.ImageIOUtil;
+import com.jogamp.opengl.util.texture.ImageType;
/** A reader and writer for DirectDraw Surface (.dds) files, which are
used to describe textures. These files can contain multiple mipmap
@@ -238,38 +237,6 @@ public class DDSImage {
return image;
}
- /** Determines from the magic number whether the given InputStream
- points to a DDS image. The given InputStream must return true
- from markSupported() and support a minimum of four bytes of
- read-ahead.
-
- @param in Stream to check
- @return true if input stream is DDS image or false otherwise
- @throws java.io.IOException if an I/O exception occurred
- @deprecated rather call {@link ImageIOUtil#getFileSuffix(InputStream)}
- */
- @Deprecated
- public static boolean isDDSImage(InputStream in) throws IOException {
- if (!(in instanceof BufferedInputStream)) {
- in = new BufferedInputStream(in);
- }
- if (!in.markSupported()) {
- throw new IOException("Can not test non-destructively whether given InputStream is a DDS image");
- }
- in.mark(4);
- int magic = 0;
- for (int i = 0; i < 4; i++) {
- final int tmp = in.read();
- if (tmp < 0) {
- in.reset();
- return false;
- }
- magic = ((magic >>> 8) | (tmp << 24));
- }
- in.reset();
- return (magic == MAGIC);
- }
-
/**
* Writes this DDSImage to the specified file name.
* @param filename File name to write to
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/SGIImage.java b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/SGIImage.java
index ff8167bb0..47e40e367 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/SGIImage.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/SGIImage.java
@@ -42,7 +42,7 @@ package com.jogamp.opengl.util.texture.spi;
import java.io.*;
import com.jogamp.opengl.*;
-import com.jogamp.opengl.util.texture.ImageIOUtil;
+import com.jogamp.opengl.util.texture.ImageType;
import com.jogamp.common.util.IOUtil;
/** <p> Reads and writes SGI RGB/RGBA images. </p>
@@ -191,28 +191,6 @@ public class SGIImage {
return image;
}
- /**
- * Determines from the magic number whether the given InputStream points to
- * an SGI RGB image. The given InputStream must return true from
- * markSupported() and support a minimum of two bytes of read-ahead.
- *
- * @deprecated rather call {@link ImageIOUtil#getFileSuffix(InputStream)}
- */
- @Deprecated
- public static boolean isSGIImage(InputStream in) throws IOException {
- if (!(in instanceof BufferedInputStream)) {
- in = new BufferedInputStream(in);
- }
- if (!in.markSupported()) {
- throw new IOException("Can not test non-destructively whether given InputStream is an SGI RGB image");
- }
- final DataInputStream dIn = new DataInputStream(in);
- dIn.mark(4);
- final short magic = dIn.readShort();
- dIn.reset();
- return (magic == MAGIC);
- }
-
/** Returns the width of the image. */
public int getWidth() {
return header.xsize;
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/TextureProvider.java b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/TextureProvider.java
index e84f300e2..485a1b82d 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/TextureProvider.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/TextureProvider.java
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2015 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
@@ -39,11 +40,13 @@
package com.jogamp.opengl.util.texture.spi;
-import java.io.*;
-import java.net.*;
+import java.io.IOException;
+import java.io.InputStream;
+
import com.jogamp.opengl.GLProfile;
+import com.jogamp.opengl.util.texture.ImageType;
+import com.jogamp.opengl.util.texture.TextureData;
-import com.jogamp.opengl.util.texture.*;
/** Plug-in interface to TextureIO to support reading OpenGL textures
from new file formats. For all methods, either internalFormat or
@@ -54,43 +57,24 @@ import com.jogamp.opengl.util.texture.*;
public interface TextureProvider {
/**
- * Produces a TextureData object from a file, or returns null if the
- * file format was not supported by this TextureProvider. Does not
- * do any OpenGL-related work. The resulting TextureData can be
- * converted into an OpenGL texture in a later step.
- *
- * @param glp the OpenGL Profile this texture data should be
- * created for.
- * @param file the file from which to read the texture data
- *
- * @param internalFormat the OpenGL internal format to be used for
- * the texture, or 0 if it should be inferred
- * from the file's contents
- *
- * @param pixelFormat the OpenGL pixel format to be used for
- * the texture, or 0 if it should be inferred
- * from the file's contents
- *
- * @param mipmap whether mipmaps should be produced for this
- * texture either by autogenerating them or
- * reading them from the file. Some file formats
- * support multiple mipmaps in a single file in
- * which case those mipmaps will be used rather
- * than generating them.
- *
- * @param fileSuffix the file suffix to be used as a hint to the
- * provider to more quickly decide whether it
- * can handle the file, or null if the
- * provider should infer the type from the
- * file's contents
- *
- * @throws IOException if an error occurred while reading the file
+ * Optional additional interface for {@link TextureProvider} implementation
+ * exposing the supported {@link ImageType}s.
+ * <p>
+ * Use case: Mapping of {@link ImageType}s to {@link TextureProvider}.
+ * </p>
*/
- public TextureData newTextureData(GLProfile glp, File file,
- int internalFormat,
- int pixelFormat,
- boolean mipmap,
- String fileSuffix) throws IOException;
+ public static interface SupportsImageTypes {
+ /** Returns the supported {@link ImageType}s. */
+ ImageType[] getImageTypes();
+ }
+
+ /**
+ * Returns the known supported {@link ImageType}s, or {@code null} if unknown.
+ * <p>
+ * Use case: Mapping of {@link ImageType}s to {@link TextureProvider}.
+ * </p>
+ */
+ ImageType[] getImageTypes();
/**
* Produces a TextureData object from a stream, or returns null if
@@ -130,43 +114,4 @@ public interface TextureProvider {
int pixelFormat,
boolean mipmap,
String fileSuffix) throws IOException;
-
- /**
- * Produces a TextureData object from a URL, or returns null if the
- * file format was not supported by this TextureProvider. Does not
- * do any OpenGL-related work. The resulting TextureData can be
- * converted into an OpenGL texture in a later step.
- *
- * @param glp the OpenGL Profile this texture data should be
- * created for.
- * @param url the URL from which to read the texture data
- *
- * @param internalFormat the OpenGL internal format to be used for
- * the texture, or 0 if it should be inferred
- * from the file's contents
- *
- * @param pixelFormat the OpenGL pixel format to be used for
- * the texture, or 0 if it should be inferred
- * from the file's contents
- *
- * @param mipmap whether mipmaps should be produced for this
- * texture either by autogenerating them or
- * reading them from the file. Some file formats
- * support multiple mipmaps in a single file in
- * which case those mipmaps will be used rather
- * than generating them.
- *
- * @param fileSuffix the file suffix to be used as a hint to the
- * provider to more quickly decide whether it
- * can handle the file, or null if the
- * provider should infer the type from the
- * file's contents
- *
- * @throws IOException if an error occurred while reading the URL
- */
- public TextureData newTextureData(GLProfile glp, URL url,
- int internalFormat,
- int pixelFormat,
- boolean mipmap,
- String fileSuffix) throws IOException;
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/awt/IIOTextureProvider.java b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/awt/IIOTextureProvider.java
index ba762baf3..8ee54899c 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/awt/IIOTextureProvider.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/awt/IIOTextureProvider.java
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2015 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,39 +37,29 @@
* Sun gratefully acknowledges that this software was originally authored
* and developed by Kenneth Bradley Russell and Christopher John Kline.
*/
-
+//
package com.jogamp.opengl.util.texture.spi.awt;
-import java.awt.Graphics;
-import java.awt.image.*;
-import java.io.*;
-import java.net.*;
-import javax.imageio.*;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.imageio.ImageIO;
+
import com.jogamp.opengl.GLProfile;
+import com.jogamp.opengl.util.texture.ImageType;
+import com.jogamp.opengl.util.texture.TextureData;
+import com.jogamp.opengl.util.texture.awt.AWTTextureData;
+import com.jogamp.opengl.util.texture.spi.TextureProvider;
import jogamp.opengl.Debug;
-import com.jogamp.opengl.util.texture.*;
-import com.jogamp.opengl.util.texture.awt.*;
-import com.jogamp.opengl.util.texture.spi.*;
public class IIOTextureProvider implements TextureProvider {
private static final boolean DEBUG = Debug.debug("TextureIO");
@Override
- public TextureData newTextureData(final GLProfile glp, final File file,
- final int internalFormat,
- final int pixelFormat,
- final boolean mipmap,
- final String fileSuffix) throws IOException {
- final BufferedImage img = ImageIO.read(file);
- if (img == null) {
- return null;
- }
- if (DEBUG) {
- System.out.println("TextureIO.newTextureData(): BufferedImage type for " + file + " = " +
- img.getType());
- }
- return new AWTTextureData(glp, internalFormat, pixelFormat, mipmap, img);
+ public final ImageType[] getImageTypes() {
+ return null;
}
@Override
@@ -87,18 +78,4 @@ public class IIOTextureProvider implements TextureProvider {
}
return new AWTTextureData(glp, internalFormat, pixelFormat, mipmap, img);
}
-
- @Override
- public TextureData newTextureData(final GLProfile glp, final URL url,
- final int internalFormat,
- final int pixelFormat,
- final boolean mipmap,
- final String fileSuffix) throws IOException {
- final InputStream stream = url.openStream();
- try {
- return newTextureData(glp, stream, internalFormat, pixelFormat, mipmap, fileSuffix);
- } finally {
- stream.close();
- }
- }
}
diff --git a/src/jogl/classes/jogamp/graph/font/UbuntuFontLoader.java b/src/jogl/classes/jogamp/graph/font/UbuntuFontLoader.java
index e4b0cb2a8..f52292769 100644
--- a/src/jogl/classes/jogamp/graph/font/UbuntuFontLoader.java
+++ b/src/jogl/classes/jogamp/graph/font/UbuntuFontLoader.java
@@ -52,7 +52,6 @@ public class UbuntuFontLoader implements FontSet {
private static final Uri.Encoded jarSubDir = Uri.Encoded.cast("atomic/");
private static final Uri.Encoded jarName = Uri.Encoded.cast("jogl-fonts-p0.jar");
- private static final String relFontPath = "fonts/ubuntu/" ;
private static final String absFontPath = "jogamp/graph/font/fonts/ubuntu/" ;
private static final FontSet fontLoader = new UbuntuFontLoader();
@@ -160,15 +159,14 @@ public class UbuntuFontLoader implements FontSet {
}
}
}
- final String path = useTempJARCache ? absFontPath : relFontPath;
try {
- final Font f = abspathImpl(path+fname, family, style);
+ final Font f = abspathImpl(absFontPath+fname, family, style);
if( null != f ) {
return f;
}
- throw new IOException(String.format("Problem loading font %s, stream %s%s", fname, path, fname));
+ throw new IOException(String.format("Problem loading font %s, stream %s%s", fname, absFontPath, fname));
} catch(final Exception e) {
- throw new IOException(String.format("Problem loading font %s, stream %s%s", fname, path, fname), e);
+ throw new IOException(String.format("Problem loading font %s, stream %s%s", fname, absFontPath, fname), e);
}
}
private Font abspathImpl(final String fname, final int family, final int style) throws IOException {
@@ -190,7 +188,7 @@ public class UbuntuFontLoader implements FontSet {
throw new IOException(privErr[0]);
}
} else {
- final URLConnection urlConn = IOUtil.getResource(UbuntuFontLoader.class, fname);
+ final URLConnection urlConn = IOUtil.getResource(fname, getClass().getClassLoader(), null);
stream = null != urlConn ? urlConn.getInputStream() : null;
}
if(null != stream) {
diff --git a/src/jogl/classes/jogamp/opengl/DesktopGLDynamicLookupHelper.java b/src/jogl/classes/jogamp/opengl/DesktopGLDynamicLookupHelper.java
index 6025b45ff..5eb429774 100644
--- a/src/jogl/classes/jogamp/opengl/DesktopGLDynamicLookupHelper.java
+++ b/src/jogl/classes/jogamp/opengl/DesktopGLDynamicLookupHelper.java
@@ -48,7 +48,7 @@ public class DesktopGLDynamicLookupHelper extends GLDynamicLookupHelper {
gluLibNames.add("libGLU.so"); // unix
gluLibNames.add("GLU32"); // windows
gluLibNames.add("GLU"); // generic
- gluLib = loadFirstAvailable(gluLibNames, null, true);
+ gluLib = loadFirstAvailable(gluLibNames, true, true, null, true);
if(null != gluLib) {
nativeLibraries.add(gluLib);
}
diff --git a/src/jogl/classes/jogamp/opengl/ExtensionAvailabilityCache.java b/src/jogl/classes/jogamp/opengl/ExtensionAvailabilityCache.java
index 331414869..b28b79418 100644
--- a/src/jogl/classes/jogamp/opengl/ExtensionAvailabilityCache.java
+++ b/src/jogl/classes/jogamp/opengl/ExtensionAvailabilityCache.java
@@ -45,7 +45,6 @@ import java.util.StringTokenizer;
import com.jogamp.opengl.GL;
import com.jogamp.opengl.GL2ES3;
-import com.jogamp.opengl.GL2GL3;
import com.jogamp.opengl.GLContext;
import com.jogamp.common.util.VersionNumber;
@@ -138,9 +137,9 @@ final class ExtensionAvailabilityCache {
boolean useGetStringi = false;
- // Use 'glGetStringi' only for ARB GL3 context,
+ // Use 'glGetStringi' only for ARB GL3 and ES3 context,
// on GL2 platforms the function might be available, but not working.
- if ( context.isGL3() ) {
+ if ( context.isGL3() || context.isGLES3() ) {
if ( ! context.isFunctionAvailable("glGetStringi") ) {
if(DEBUG) {
System.err.println("GLContext: GL >= 3.1 usage, but no glGetStringi");
@@ -156,16 +155,16 @@ final class ExtensionAvailabilityCache {
}
if(useGetStringi) {
- final GL2GL3 gl2gl3 = gl.getGL2GL3();
+ final GL2ES3 gl2es3 = (GL2ES3)gl; // validated via context - OK!
final int count;
{
final int[] val = { 0 } ;
- gl2gl3.glGetIntegerv(GL2ES3.GL_NUM_EXTENSIONS, val, 0);
+ gl2es3.glGetIntegerv(GL2ES3.GL_NUM_EXTENSIONS, val, 0);
count = val[0];
}
final StringBuilder sb = new StringBuilder();
for (int i = 0; i < count; i++) {
- final String ext = gl2gl3.glGetStringi(GL.GL_EXTENSIONS, i);
+ final String ext = gl2es3.glGetStringi(GL.GL_EXTENSIONS, i);
if( null == availableExtensionCache.put(ext, ext) ) {
// new one
if( 0 < i ) {
diff --git a/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java b/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java
index 19fd6c7e1..9d1490300 100644
--- a/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java
+++ b/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java
@@ -51,6 +51,7 @@ import com.jogamp.opengl.GLRunnable;
import com.jogamp.opengl.GLSharedContextSetter;
import com.jogamp.common.ExceptionUtils;
+import com.jogamp.common.util.RunnableTask;
import com.jogamp.common.util.locks.RecursiveLock;
import com.jogamp.opengl.GLAutoDrawableDelegate;
import com.jogamp.opengl.GLEventListenerState;
@@ -598,6 +599,44 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, GLStateKeepe
return helper.getExclusiveContextThread();
}
+ /**
+ * Invokes given {@code runnable} on current thread outside of a probable claimed exclusive thread,
+ * i.e. releases the exclusive thread, executes the runnable and reclaims it.
+ * FIXME: Promote to GLAutoDrawable!
+ *
+ * @param runnable the {@link Runnable} to execute on the new thread.
+ * The runnable <b>must exit</b>, i.e. not loop forever.
+ *
+ * @see #setExclusiveContextThread(Thread, GLContext)
+ *
+ * @since 2.3.2
+ */
+ public final void invokeOnCurrentThread(final Runnable runnable) {
+ helper.runOutsideOfExclusiveContextThread(context, runnable);
+ }
+ /**
+ * Invokes given {@code runnable} on current thread outside of a probable claimed exclusive thread,
+ * i.e. releases the exclusive thread, executes the runnable and reclaims it.
+ * FIXME: Promote to GLAutoDrawable!
+ *
+ * @param tg the {@link ThreadGroup} for the new thread, maybe <code>null</code>
+ * @param waitUntilDone if <code>true</code>, waits until <code>runnable</code> execution is completed, otherwise returns immediately.
+ * @param runnable the {@link Runnable} to execute on the new thread.
+ * The runnable <b>must exit</b>, i.e. not loop forever.
+ * @return {@link RunnableTask} instance with execution details
+ *
+ * @see #setExclusiveContextThread(Thread, GLContext)
+ *
+ * @since 2.3.2
+ */
+ public final RunnableTask invokeOnNewThread(final ThreadGroup tg, final boolean waitUntilDone, final Runnable runnable) {
+ return RunnableTask.invokeOnNewThread(tg, null, waitUntilDone,
+ new Runnable() {
+ public final void run() {
+ helper.runOutsideOfExclusiveContextThread(context, runnable);
+ } });
+ }
+
@Override
public final boolean invoke(final boolean wait, final GLRunnable glRunnable) throws IllegalStateException {
return helper.invoke(this, wait, glRunnable);
diff --git a/src/jogl/classes/jogamp/opengl/GLContextImpl.java b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
index 8f4105f98..6866374bc 100644
--- a/src/jogl/classes/jogamp/opengl/GLContextImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
@@ -45,7 +45,10 @@ import java.nio.IntBuffer;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.HashMap;
+import java.util.IdentityHashMap;
+import java.util.Iterator;
import java.util.Map;
+import java.util.Set;
import com.jogamp.common.ExceptionUtils;
import com.jogamp.common.os.DynamicLookupHelper;
@@ -59,12 +62,12 @@ 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 com.jogamp.nativewindow.AbstractGraphicsConfiguration;
import com.jogamp.nativewindow.AbstractGraphicsDevice;
import com.jogamp.nativewindow.NativeSurface;
import com.jogamp.nativewindow.NativeWindowFactory;
import com.jogamp.nativewindow.ProxySurface;
+import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
import com.jogamp.opengl.GL;
import com.jogamp.opengl.GL2ES2;
import com.jogamp.opengl.GL2ES3;
@@ -126,11 +129,13 @@ public abstract class GLContextImpl extends GLContext {
* If GL >= 3.0 (ES or desktop) and not having {@link GLRendererQuirks#NoSurfacelessCtx},
* being evaluated if not surface-handle is null and not yet set at makeCurrent(..).
*/
- private boolean surfacelessOK = false;
+ private boolean isSurfaceless = false;
private boolean pixelDataEvaluated;
private int /* pixelDataInternalFormat, */ pixelDataFormat, pixelDataType;
+ private int currentSwapInterval;
+
protected GL gl;
protected static final Object mappedContextTypeObjectLock;
@@ -207,8 +212,9 @@ public abstract class GLContextImpl extends GLContext {
boundFBOTarget[1] = 0; // read
}
- surfacelessOK = false;
+ isSurfaceless = false;
pixelDataEvaluated = false;
+ currentSwapInterval = 0;
super.resetStates(isInit);
}
@@ -536,7 +542,7 @@ public abstract class GLContextImpl extends GLContext {
//----------------------------------------------------------------------
//
- protected final boolean isSurfacelessOK() { return surfacelessOK; }
+ protected final boolean isSurfaceless() { return isSurfaceless; }
/**
* {@inheritDoc}
@@ -607,7 +613,7 @@ public abstract class GLContextImpl extends GLContext {
if ( drawable.isRealized() ) {
lock.lock();
try {
- if ( 0 == drawable.getHandle() && !surfacelessOK ) {
+ if ( 0 == drawable.getHandle() && !isSurfaceless ) {
if( DEBUG ) {
System.err.println(getThreadName() +": GLContext.makeCurrent: Surfaceless evaluate");
}
@@ -671,7 +677,7 @@ public abstract class GLContextImpl extends GLContext {
}
if ( CONTEXT_NOT_CURRENT != res ) { // still locked!
- if( 0 == drawable.getHandle() && !surfacelessOK ) {
+ if( 0 == drawable.getHandle() && !isSurfaceless ) {
if( hasRendererQuirk(GLRendererQuirks.NoSurfacelessCtx) ) {
throw new GLException(String.format("Surfaceless not supported due to quirk %s: %s",
GLRendererQuirks.toString(GLRendererQuirks.NoSurfacelessCtx), toString()));
@@ -679,15 +685,15 @@ public abstract class GLContextImpl extends GLContext {
if( DEBUG ) {
System.err.println(getThreadName() +": GLContext.makeCurrent: Surfaceless OK - validated");
}
- surfacelessOK = true;
+ isSurfaceless = true;
}
setCurrent(this);
if( CONTEXT_CURRENT_NEW == res ) {
// check if the drawable's and the GL's GLProfile are equal
// throws an GLException if not
- drawable.getGLProfile().verifyEquality(gl.getGLProfile());
+ // FIXME: drawable.getGLProfile().verifyEquality(gl.getGLProfile());
- glDebugHandler.init( isGL2GL3() && isGLDebugEnabled() );
+ glDebugHandler.init( isGLDebugEnabled() );
if(DEBUG_GL) {
setGL( GLPipelineFactory.create("com.jogamp.opengl.Debug", null, gl, null) );
@@ -802,28 +808,28 @@ public abstract class GLContextImpl extends GLContext {
reqProfile = GLContext.CTX_PROFILE_COMPAT;
isCompat = true;
}
- GLContext.mapAvailableGLVersion(device, reqMajor, reqProfile, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions);
+ final MappedGLVersion me = mapAvailableGLVersion(device, reqMajor, reqProfile, ctxVersion, ctxOptions, glRendererQuirks);
// Perform all required profile mappings
if( isCompat ) {
// COMPAT via non ARB
- GLContext.mapAvailableGLVersion(device, reqMajor, GLContext.CTX_PROFILE_CORE, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions);
+ mapAvailableGLVersion(device, reqMajor, GLContext.CTX_PROFILE_CORE, ctxVersion, ctxOptions, glRendererQuirks);
if( reqMajor >= 4 ) {
- GLContext.mapAvailableGLVersion(device, 3, reqProfile, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions);
- GLContext.mapAvailableGLVersion(device, 3, GLContext.CTX_PROFILE_CORE, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions);
+ mapAvailableGLVersion(device, 3, reqProfile, ctxVersion, ctxOptions, glRendererQuirks);
+ mapAvailableGLVersion(device, 3, GLContext.CTX_PROFILE_CORE, ctxVersion, ctxOptions, glRendererQuirks);
}
if( reqMajor >= 3 ) {
- GLContext.mapAvailableGLVersion(device, 2, reqProfile, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions);
+ mapAvailableGLVersion(device, 2, reqProfile, ctxVersion, ctxOptions, glRendererQuirks);
}
} else {
// CORE via non ARB, unlikely, however ..
if( reqMajor >= 4 ) {
- GLContext.mapAvailableGLVersion(device, 3, reqProfile, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions);
+ mapAvailableGLVersion(device, 3, reqProfile, ctxVersion, ctxOptions, glRendererQuirks);
}
}
GLContext.setAvailableGLVersionsSet(device, true);
if (DEBUG) {
- System.err.println(getThreadName() + ": createContextOLD-MapVersionsAvailable HAVE: " + device+" -> "+reqMajor+"."+reqProfile+ " -> "+getGLVersion());
+ System.err.println(getThreadName() + ": createContextOLD-MapGLVersions HAVE: " + me);
}
}
}
@@ -947,13 +953,13 @@ public abstract class GLContextImpl extends GLContext {
{
final AbstractGraphicsConfiguration config = drawable.getNativeSurface().getGraphicsConfiguration();
final AbstractGraphicsDevice device = config.getScreen().getDevice();
- if (DEBUG) {
- System.err.println(getThreadName() + ": createContextARB: mappedVersionsAvailableSet("+device.getConnection()+"): "+
- GLContext.getAvailableGLVersionsSet(device));
- }
final GLCapabilitiesImmutable glCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
final GLProfile glp = glCaps.getGLProfile();
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": createContextARB-MapGLVersions is SET ("+device.getConnection()+"): "+
+ GLContext.getAvailableGLVersionsSet(device));
+ }
if ( !GLContext.getAvailableGLVersionsSet(device) ) {
if( !mapGLVersions(device) ) {
// none of the ARB context creation calls was successful, bail out
@@ -965,7 +971,7 @@ public abstract class GLContextImpl extends GLContext {
GLContext.getRequestMajorAndCompat(glp, reqMajorCTP);
if(DEBUG) {
- System.err.println(getThreadName() + ": createContextARB: Requested "+glp+" -> "+GLContext.getGLVersion(reqMajorCTP[0], 0, reqMajorCTP[1], null));
+ System.err.println(getThreadName() + ": createContextARB-MapGLVersions Requested "+glp+" -> "+GLContext.getGLVersion(reqMajorCTP[0], 0, reqMajorCTP[1], null));
}
final int _major[] = { 0 };
final int _minor[] = { 0 };
@@ -975,7 +981,7 @@ public abstract class GLContextImpl extends GLContext {
_major, _minor, _ctp)) {
_ctp[0] |= additionalCtxCreationFlags;
if(DEBUG) {
- System.err.println(getThreadName() + ": createContextARB: Mapped "+GLContext.getGLVersion(_major[0], _minor[0], _ctp[0], null));
+ System.err.println(getThreadName() + ": createContextARB-MapGLVersions Mapped "+GLContext.getGLVersion(_major[0], _minor[0], _ctp[0], null));
}
_ctx = createContextARBImpl(share, direct, _ctp[0], _major[0], _minor[0]);
if(0!=_ctx) {
@@ -987,8 +993,156 @@ public abstract class GLContextImpl extends GLContext {
return _ctx;
}
+ //----------------------------------------------------------------------
+ //
+
+ public static class MappedGLVersion {
+ public final AbstractGraphicsDevice device;
+ public final int reqMajorVersion;
+ public final int reqProfile;
+ public final VersionNumber ctxVersion;
+ public final int ctxOptions;
+ public final GLRendererQuirks quirks;
+ public final VersionNumber preCtxVersion;
+ public final int preCtxOptions;
+ public MappedGLVersion(final AbstractGraphicsDevice device, final int reqMajorVersion, final int reqProfile,
+ final VersionNumber ctxVersion, final int ctxOptions, final GLRendererQuirks quirks,
+ final VersionNumber preCtxVersion, final int preCtxOptions) {
+ this.device = device;
+ this.reqMajorVersion = reqMajorVersion;
+ this.reqProfile = reqProfile;
+ this.ctxVersion = ctxVersion;
+ this.ctxOptions = ctxOptions;
+ this.quirks = quirks;
+ this.preCtxVersion = preCtxVersion;
+ this.preCtxOptions = preCtxOptions;
+ }
+ public final String toString() {
+ return toString(new StringBuilder(), -1, -1, -1, -1).toString();
+ }
+ public final StringBuilder toString(final StringBuilder sb, final int minMajor, final int minMinor, final int maxMajor, final int maxMinor) {
+ sb.append(device.toString()).append(" ").append(reqMajorVersion).append(" (");
+ GLContext.getGLProfile(sb, reqProfile).append(")");
+ if( minMajor >=0 && minMinor >=0 && maxMajor >= 0 && maxMinor >= 0) {
+ sb.append("[").append(minMajor).append(".").append(minMinor).append(" .. ").append(maxMajor).append(".").append(maxMinor).append("]");
+ }
+ sb.append(": [");
+ if( null != preCtxVersion ) {
+ GLContext.getGLVersion(sb, preCtxVersion, preCtxOptions, null);
+ } else {
+ sb.append("None");
+ }
+ sb.append("] -> [");
+ GLContext.getGLVersion(sb, ctxVersion, ctxOptions, null).append("]");
+ return sb;
+ }
+ }
+ public static interface MappedGLVersionListener {
+ void glVersionMapped(final MappedGLVersion e);
+ }
+ private static MappedGLVersionListener mapGLVersionListener = null;
+ protected static synchronized void setMappedGLVersionListener(final MappedGLVersionListener mvl) {
+ mapGLVersionListener = mvl;
+ }
+
+ /**
+ * Called by {@link jogamp.opengl.GLContextImpl#createContextARBMapVersionsAvailable(int,int)} not intended to be used by
+ * implementations. However, if {@link jogamp.opengl.GLContextImpl#createContextARB(long, boolean)} is not being used within
+ * {@link com.jogamp.opengl.GLDrawableFactory#getOrCreateSharedContext(com.jogamp.nativewindow.AbstractGraphicsDevice)},
+ * GLProfile has to map the available versions.
+ *
+ * @param reqMajor Key Value either 1, 2, 3 or 4
+ * @param profile Key Value either {@link #CTX_PROFILE_COMPAT}, {@link #CTX_PROFILE_CORE} or {@link #CTX_PROFILE_ES}
+ * @param resVersion the resulting version number
+ * @param resCtp the resulting context options
+ * @return the old mapped value
+ *
+ * @see #createContextARBMapVersionsAvailable
+ */
+ protected static MappedGLVersion mapAvailableGLVersion(final AbstractGraphicsDevice device,
+ final int reqMajor, final int profile,
+ final VersionNumber resVersion, final int resCtp,
+ final GLRendererQuirks resQuirks)
+ {
+ final Integer preVal = mapAvailableGLVersion(device, reqMajor, profile, resVersion, resCtp);
+ final int[] preCtp = { 0 };
+ final VersionNumber preVersion = null != preVal ? decomposeBits(preVal.intValue(), preCtp) : null;
+ final MappedGLVersion res = new MappedGLVersion(device, reqMajor, profile, resVersion, resCtp, resQuirks, preVersion, preCtp[0]);
+ if( null != mapGLVersionListener ) {
+ mapGLVersionListener.glVersionMapped(res);
+ }
+ return res;
+ }
+ private static Integer mapAvailableGLVersion(final AbstractGraphicsDevice device,
+ final int reqMajor, final int profile, final VersionNumber resVersion, int resCtp)
+ {
+ validateProfileBits(profile, "profile");
+ validateProfileBits(resCtp, "resCtp");
+
+ if(FORCE_NO_FBO_SUPPORT) {
+ resCtp &= ~CTX_IMPL_FBO ;
+ }
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": createContextARB-MapGLVersions MAP "+device+": "+reqMajor+" ("+GLContext.getGLProfile(new StringBuilder(), profile).toString()+ ") -> "+
+ getGLVersion(resVersion.getMajor(), resVersion.getMinor(), resCtp, null));
+ }
+ final String objectKey = getDeviceVersionAvailableKey(device, reqMajor, profile);
+ final Integer val = Integer.valueOf(composeBits(resVersion.getMajor(), resVersion.getMinor(), resCtp));
+ synchronized(deviceVersionAvailable) {
+ return deviceVersionAvailable.put( objectKey, val );
+ }
+ }
+
+
+ protected static void remapAvailableGLVersions(final AbstractGraphicsDevice fromDevice, final AbstractGraphicsDevice toDevice) {
+ if( fromDevice == toDevice || fromDevice.getUniqueID() == toDevice.getUniqueID() ) {
+ return; // NOP
+ }
+ synchronized(deviceVersionAvailable) {
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": createContextARB-MapGLVersions REMAP "+fromDevice+" -> "+toDevice);
+ }
+ final IdentityHashMap<String, Integer> newDeviceVersionAvailable = new IdentityHashMap<String, Integer>();
+ final Set<String> keys = deviceVersionAvailable.keySet();
+ for(final Iterator<String> keyI = keys.iterator(); keyI.hasNext(); ) {
+ final String origKey = keyI.next();
+ final Integer valI = deviceVersionAvailable.get(origKey);
+ if( null != valI ) {
+ if(DEBUG) {
+ final int[] ctp = { 0 };
+ final VersionNumber version = decomposeBits(valI.intValue(), ctp);
+ System.err.println(" MapGLVersions REMAP OLD "+origKey+" -> "+GLContext.getGLVersion(new StringBuilder(), version, ctp[0], null).toString());
+ }
+ newDeviceVersionAvailable.put(origKey, valI);
+ final int devSepIdx = origKey.lastIndexOf('-');
+ if( 0 >= devSepIdx ) {
+ throw new InternalError("device-separator '-' at "+devSepIdx+" of "+origKey);
+ }
+ final String devUniqueID = origKey.substring(0, devSepIdx);
+ if( fromDevice.getUniqueID().equals(devUniqueID) ) {
+ final String profileReq = origKey.substring(devSepIdx);
+ final String newKey = (toDevice.getUniqueID()+profileReq).intern();
+ if(DEBUG) {
+ System.err.println(" MapGLVersions REMAP NEW "+newKey+" -> (ditto)");
+ }
+ newDeviceVersionAvailable.put(newKey, valI);
+ }
+ }
+ }
+ deviceVersionAvailable.clear();
+ deviceVersionAvailable.putAll(newDeviceVersionAvailable);
+ GLContext.setAvailableGLVersionsSet(toDevice, true);
+ }
+ }
+
private final boolean mapGLVersions(final AbstractGraphicsDevice device) {
synchronized (GLContext.deviceVersionAvailable) {
+ final boolean hasOpenGLESSupport = drawable.getFactory().hasOpenGLESSupport();
+ final boolean hasOpenGLDesktopSupport = drawable.getFactory().hasOpenGLDesktopSupport();
+ final boolean hasMinorVersionSupport = drawable.getFactoryImpl().hasMajorMinorCreateContextARB();
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": createContextARB-MapGLVersions START (GLDesktop "+hasOpenGLDesktopSupport+", GLES "+hasOpenGLESSupport+", minorVersion "+hasMinorVersionSupport+") on "+device);
+ }
final long t0 = ( DEBUG ) ? System.nanoTime() : 0;
boolean success = false;
// Following GLProfile.GL_PROFILE_LIST_ALL order of profile detection { GL4bc, GL3bc, GL2, GL4, GL3, GL2GL3, GLES2, GL2ES2, GLES1, GL2ES1 }
@@ -997,6 +1151,43 @@ public abstract class GLContextImpl extends GLContext {
boolean hasGL2 = false;
boolean hasGL4 = false;
boolean hasGL3 = false;
+ boolean hasES3 = false;
+ boolean hasES2 = false;
+ boolean hasES1 = false;
+
+ if( hasOpenGLESSupport && !GLProfile.disableOpenGLES ) {
+ if( !hasES3) {
+ hasES3 = createContextARBMapVersionsAvailable(device, 3, CTX_PROFILE_ES, hasMinorVersionSupport); // ES3
+ success |= hasES3;
+ if( hasES3 ) {
+ if( 0 == ( CTX_IMPL_ACCEL_SOFT & ctxOptions ) ) {
+ // Map hw-accel ES3 to all lower core profiles: ES2
+ mapAvailableGLVersion(device, 2, CTX_PROFILE_ES, ctxVersion, ctxOptions, glRendererQuirks);
+ if( PROFILE_ALIASING ) {
+ hasES2 = true;
+ }
+ }
+ resetStates(false); // clean context states, since creation was temporary
+ }
+ }
+ if( !hasES2) {
+ hasES2 = createContextARBMapVersionsAvailable(device, 2, CTX_PROFILE_ES, hasMinorVersionSupport); // ES2
+ success |= hasES2;
+ if( hasES2 ) {
+ if( ctxVersion.getMajor() >= 3 && hasRendererQuirk(GLRendererQuirks.GLES3ViaEGLES2Config)) {
+ mapAvailableGLVersion(device, 3, CTX_PROFILE_ES, ctxVersion, ctxOptions, glRendererQuirks);
+ }
+ resetStates(false); // clean context states, since creation was temporary
+ }
+ }
+ if( !hasES1) {
+ hasES1 = createContextARBMapVersionsAvailable(device, 1, CTX_PROFILE_ES, hasMinorVersionSupport); // ES1
+ success |= hasES1;
+ if( hasES1 ) {
+ resetStates(false); // clean context states, since creation was temporary
+ }
+ }
+ }
// Even w/ PROFILE_ALIASING, try to use true core GL profiles
// ensuring proper user behavior across platforms due to different feature sets!
@@ -1006,31 +1197,31 @@ public abstract class GLContextImpl extends GLContext {
/**
* OSX 10.9 GLRendererQuirks.GL4NeedsGL3Request, quirk is added as usual @ setRendererQuirks(..)
*/
- if( !GLProfile.disableOpenGLCore && !hasGL4 && !hasGL3 ) {
- hasGL3 = createContextARBMapVersionsAvailable(3, CTX_PROFILE_CORE); // GL3
+ if( hasOpenGLDesktopSupport && !GLProfile.disableOpenGLDesktop && !GLProfile.disableOpenGLCore && !hasGL4 && !hasGL3 ) {
+ hasGL3 = createContextARBMapVersionsAvailable(device, 3, CTX_PROFILE_CORE, hasMinorVersionSupport); // GL3
success |= hasGL3;
if( hasGL3 ) {
final boolean isHWAccel = 0 == ( CTX_IMPL_ACCEL_SOFT & ctxOptions );
if( isHWAccel && ctxVersion.getMajor() >= 4 ) {
// Gotcha: Creating a '3.2' ctx delivers a >= 4 ctx.
- GLContext.mapAvailableGLVersion(device, 4, CTX_PROFILE_CORE, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions);
+ mapAvailableGLVersion(device, 4, CTX_PROFILE_CORE, ctxVersion, ctxOptions, glRendererQuirks);
hasGL4 = true;
if(DEBUG) {
- System.err.println("Quirk Triggerd: "+GLRendererQuirks.toString(GLRendererQuirks.GL4NeedsGL3Request)+": cause: OS "+Platform.getOSType()+", OS Version "+Platform.getOSVersionNumber());
+ System.err.println(getThreadName() + ": createContextARB-MapGLVersions: Quirk Triggerd: "+GLRendererQuirks.toString(GLRendererQuirks.GL4NeedsGL3Request)+": cause: OS "+Platform.getOSType()+", OS Version "+Platform.getOSVersionNumber());
}
}
resetStates(false); // clean the context states, since creation was temporary
}
}
}
- if( !GLProfile.disableOpenGLCore ) {
+ if( hasOpenGLDesktopSupport && !GLProfile.disableOpenGLDesktop && !GLProfile.disableOpenGLCore ) {
if( !hasGL4 ) {
- hasGL4 = createContextARBMapVersionsAvailable(4, CTX_PROFILE_CORE); // GL4
+ hasGL4 = createContextARBMapVersionsAvailable(device, 4, CTX_PROFILE_CORE, hasMinorVersionSupport); // GL4
success |= hasGL4;
if( hasGL4 ) {
if( 0 == ( CTX_IMPL_ACCEL_SOFT & ctxOptions ) ) {
// Map hw-accel GL4 to all lower core profiles: GL3
- GLContext.mapAvailableGLVersion(device, 3, CTX_PROFILE_CORE, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions);
+ mapAvailableGLVersion(device, 3, CTX_PROFILE_CORE, ctxVersion, ctxOptions, glRendererQuirks);
if( PROFILE_ALIASING ) {
hasGL3 = true;
}
@@ -1039,72 +1230,74 @@ public abstract class GLContextImpl extends GLContext {
}
}
if( !hasGL3 ) {
- hasGL3 = createContextARBMapVersionsAvailable(3, CTX_PROFILE_CORE); // GL3
+ hasGL3 = createContextARBMapVersionsAvailable(device, 3, CTX_PROFILE_CORE, hasMinorVersionSupport); // GL3
success |= hasGL3;
if( hasGL3 ) {
resetStates(false); // clean this context states, since creation was temporary
}
}
}
- if( !hasGL4bc ) {
- hasGL4bc = createContextARBMapVersionsAvailable(4, CTX_PROFILE_COMPAT); // GL4bc
- success |= hasGL4bc;
- if( hasGL4bc ) {
- if( !hasGL4 ) { // last chance .. ignore hw-accel
- GLContext.mapAvailableGLVersion(device, 4, CTX_PROFILE_CORE, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions);
- hasGL4 = true;
- }
- if( !hasGL3 ) { // last chance .. ignore hw-accel
- GLContext.mapAvailableGLVersion(device, 3, CTX_PROFILE_CORE, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions);
- hasGL3 = true;
- }
- if( 0 == ( CTX_IMPL_ACCEL_SOFT & ctxOptions ) ) {
- // Map hw-accel GL4bc to all lower compatible profiles: GL3bc, GL2
- GLContext.mapAvailableGLVersion(device, 3, CTX_PROFILE_COMPAT, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions);
- GLContext.mapAvailableGLVersion(device, 2, CTX_PROFILE_COMPAT, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions);
- if(PROFILE_ALIASING) {
- hasGL3bc = true;
- hasGL2 = true;
+ if( hasOpenGLDesktopSupport && !GLProfile.disableOpenGLDesktop ) {
+ if( !hasGL4bc ) {
+ hasGL4bc = createContextARBMapVersionsAvailable(device, 4, CTX_PROFILE_COMPAT, hasMinorVersionSupport); // GL4bc
+ success |= hasGL4bc;
+ if( hasGL4bc ) {
+ if( !hasGL4 ) { // last chance .. ignore hw-accel
+ mapAvailableGLVersion(device, 4, CTX_PROFILE_CORE, ctxVersion, ctxOptions, glRendererQuirks);
+ hasGL4 = true;
+ }
+ if( !hasGL3 ) { // last chance .. ignore hw-accel
+ mapAvailableGLVersion(device, 3, CTX_PROFILE_CORE, ctxVersion, ctxOptions, glRendererQuirks);
+ hasGL3 = true;
+ }
+ if( 0 == ( CTX_IMPL_ACCEL_SOFT & ctxOptions ) ) {
+ // Map hw-accel GL4bc to all lower compatible profiles: GL3bc, GL2
+ mapAvailableGLVersion(device, 3, CTX_PROFILE_COMPAT, ctxVersion, ctxOptions, glRendererQuirks);
+ mapAvailableGLVersion(device, 2, CTX_PROFILE_COMPAT, ctxVersion, ctxOptions, glRendererQuirks);
+ if(PROFILE_ALIASING) {
+ hasGL3bc = true;
+ hasGL2 = true;
+ }
}
+ resetStates(false); // clean this context states, since creation was temporary
}
- resetStates(false); // clean this context states, since creation was temporary
}
- }
- if( !hasGL3bc ) {
- hasGL3bc = createContextARBMapVersionsAvailable(3, CTX_PROFILE_COMPAT); // GL3bc
- success |= hasGL3bc;
- if( hasGL3bc ) {
- if(!hasGL3) { // last chance .. ignore hw-accel
- GLContext.mapAvailableGLVersion(device, 3, CTX_PROFILE_CORE, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions);
- hasGL3 = true;
- }
- if( 0 == ( CTX_IMPL_ACCEL_SOFT & ctxOptions ) ) {
- // Map hw-accel GL3bc to all lower compatible profiles: GL2
- GLContext.mapAvailableGLVersion(device, 2, CTX_PROFILE_COMPAT, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions);
- if(PROFILE_ALIASING) {
- hasGL2 = true;
+ if( !hasGL3bc ) {
+ hasGL3bc = createContextARBMapVersionsAvailable(device, 3, CTX_PROFILE_COMPAT, hasMinorVersionSupport); // GL3bc
+ success |= hasGL3bc;
+ if( hasGL3bc ) {
+ if(!hasGL3) { // last chance .. ignore hw-accel
+ mapAvailableGLVersion(device, 3, CTX_PROFILE_CORE, ctxVersion, ctxOptions, glRendererQuirks);
+ hasGL3 = true;
}
+ if( 0 == ( CTX_IMPL_ACCEL_SOFT & ctxOptions ) ) {
+ // Map hw-accel GL3bc to all lower compatible profiles: GL2
+ mapAvailableGLVersion(device, 2, CTX_PROFILE_COMPAT, ctxVersion, ctxOptions, glRendererQuirks);
+ if(PROFILE_ALIASING) {
+ hasGL2 = true;
+ }
+ }
+ resetStates(false); // clean this context states, since creation was temporary
}
- resetStates(false); // clean this context states, since creation was temporary
}
- }
- if( !hasGL2 ) {
- hasGL2 = createContextARBMapVersionsAvailable(2, CTX_PROFILE_COMPAT); // GL2
- success |= hasGL2;
- if( hasGL2 ) {
- resetStates(false); // clean this context states, since creation was temporary
+ if( !hasGL2 ) {
+ hasGL2 = createContextARBMapVersionsAvailable(device, 2, CTX_PROFILE_COMPAT, hasMinorVersionSupport); // GL2
+ success |= hasGL2;
+ if( hasGL2 ) {
+ resetStates(false); // clean this context states, since creation was temporary
+ }
}
}
if(success) {
// only claim GL versions set [and hence detected] if ARB context creation was successful
GLContext.setAvailableGLVersionsSet(device, true);
- if(DEBUG) {
- final long t1 = System.nanoTime();
- System.err.println("GLContextImpl.mapGLVersions: "+device+", profileAliasing: "+PROFILE_ALIASING+", total "+(t1-t0)/1e6 +"ms");
+ }
+ if(DEBUG) {
+ final long t1 = System.nanoTime();
+ System.err.println(getThreadName() + ": createContextARB-MapGLVersions END (success "+success+") on "+device+", profileAliasing: "+PROFILE_ALIASING+", total "+(t1-t0)/1e6 +"ms");
+ if( success ) {
System.err.println(GLContext.dumpAvailableGLVersions(null).toString());
}
- } else if (DEBUG) {
- System.err.println(getThreadName() + ": createContextARB-MapVersions NONE for :"+device);
}
return success;
}
@@ -1114,38 +1307,61 @@ public abstract class GLContextImpl extends GLContext {
* Note: Since context creation is temporary, caller need to issue {@link #resetStates(boolean)}, if creation was successful, i.e. returns true.
* This method does not reset the states, allowing the caller to utilize the state variables.
**/
- private final boolean createContextARBMapVersionsAvailable(final int reqMajor, final int reqProfile) {
+ private final boolean createContextARBMapVersionsAvailable(final AbstractGraphicsDevice device, final int reqMajor, final int reqProfile,
+ final boolean hasMinorVersionSupport) {
long _context;
int ctp = CTX_IS_ARB_CREATED | reqProfile;
// To ensure GL profile compatibility within the JOGL application
// we always try to map against the highest GL version,
// so the user can always cast to the highest available one.
- int majorMax, minorMax;
- int majorMin, minorMin;
+ int maxMajor, maxMinor;
+ int minMajor, minMinor;
final int major[] = new int[1];
final int minor[] = new int[1];
- if( CTX_PROFILE_ES == reqProfile ) {
- majorMax=reqMajor; minorMax=GLContext.getMaxMinor(ctp, majorMax);
- majorMin=reqMajor; minorMin=0;
+ if( hasMinorVersionSupport ) {
+ if( CTX_PROFILE_ES == reqProfile ) {
+ // ES3, ES2 or ES1
+ maxMajor=reqMajor; maxMinor=GLContext.getMaxMinor(ctp, maxMajor);
+ minMajor=reqMajor; minMinor=0;
+ } else {
+ if( 4 == reqMajor ) {
+ maxMajor=4; maxMinor=GLContext.getMaxMinor(ctp, maxMajor);
+ minMajor=4; minMinor=0;
+ } else if( 3 == reqMajor ) {
+ maxMajor=3; maxMinor=GLContext.getMaxMinor(ctp, maxMajor);
+ minMajor=3; minMinor=1;
+ } else /* if( glp.isGL2() ) */ {
+ // our minimum desktop OpenGL runtime requirements are 1.1,
+ // nevertheless we restrict ARB context creation to 2.0 to spare us futile attempts
+ maxMajor=3; maxMinor=0;
+ minMajor=2; minMinor=0;
+ }
+ }
} else {
- if( 4 == reqMajor ) {
- majorMax=4; minorMax=GLContext.getMaxMinor(ctp, majorMax);
- majorMin=4; minorMin=0;
- } else if( 3 == reqMajor ) {
- majorMax=3; minorMax=GLContext.getMaxMinor(ctp, majorMax);
- majorMin=3; minorMin=1;
- } else /* if( glp.isGL2() ) */ {
- // our minimum desktop OpenGL runtime requirements are 1.1,
- // nevertheless we restrict ARB context creation to 2.0 to spare us futile attempts
- majorMax=3; minorMax=0;
- majorMin=2; minorMin=0;
+ if( CTX_PROFILE_ES == reqProfile ) {
+ // ES3, ES2 or ES1
+ maxMajor=reqMajor; maxMinor=0;
+ minMajor=reqMajor; minMinor=0;
+ } else {
+ if( 4 == reqMajor ) {
+ maxMajor=4; maxMinor=0;
+ minMajor=4; minMinor=0;
+ } else if( 3 == reqMajor ) {
+ maxMajor=3; maxMinor=1;
+ minMajor=3; minMinor=1;
+ } else /* if( glp.isGL2() ) */ {
+ // our minimum desktop OpenGL runtime requirements are 1.1,
+ // nevertheless we restrict ARB context creation to 2.0 to spare us futile attempts
+ maxMajor=2; maxMinor=0;
+ minMajor=2; minMinor=0;
+ }
}
}
_context = createContextARBVersions(0, true, ctp,
- /* max */ majorMax, minorMax,
- /* min */ majorMin, minorMin,
+ /* max */ maxMajor, maxMinor,
+ /* min */ minMajor, minMinor,
/* res */ major, minor);
if( 0 == _context && CTX_PROFILE_CORE == reqProfile && !PROFILE_ALIASING ) {
@@ -1153,8 +1369,8 @@ public abstract class GLContextImpl extends GLContext {
ctp &= ~CTX_PROFILE_CORE ;
ctp |= CTX_OPTION_FORWARD ;
_context = createContextARBVersions(0, true, ctp,
- /* max */ majorMax, minorMax,
- /* min */ majorMin, minorMin,
+ /* max */ maxMajor, maxMinor,
+ /* min */ minMajor, minMinor,
/* res */ major, minor);
if( 0 == _context ) {
// Try a compatible one .. even though not requested .. last resort
@@ -1162,25 +1378,24 @@ public abstract class GLContextImpl extends GLContext {
ctp &= ~CTX_OPTION_FORWARD ;
ctp |= CTX_PROFILE_COMPAT ;
_context = createContextARBVersions(0, true, ctp,
- /* max */ majorMax, minorMax,
- /* min */ majorMin, minorMin,
+ /* max */ maxMajor, maxMinor,
+ /* min */ minMajor, minMinor,
/* res */ major, minor);
}
}
final boolean res;
if( 0 != _context ) {
- final AbstractGraphicsDevice device = drawable.getNativeSurface().getGraphicsConfiguration().getScreen().getDevice();
// ctxMajorVersion, ctxMinorVersion, ctxOptions is being set by
// createContextARBVersions(..) -> setGLFunctionAvailbility(..) -> setContextVersion(..)
- GLContext.mapAvailableGLVersion(device, reqMajor, reqProfile, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions);
+ final MappedGLVersion me = mapAvailableGLVersion(device, reqMajor, reqProfile, ctxVersion, ctxOptions, glRendererQuirks);
destroyContextARBImpl(_context);
if (DEBUG) {
- System.err.println(getThreadName() + ": createContextARB-MapVersionsAvailable HAVE: " +reqMajor+"."+reqProfile+ " -> "+getGLVersion());
+ System.err.println(getThreadName() + ": createContextARB-MapGLVersions HAVE "+me.toString(new StringBuilder(), minMajor, minMinor, maxMajor, maxMinor).toString());
}
res = true;
} else {
if (DEBUG) {
- System.err.println(getThreadName() + ": createContextARB-MapVersionsAvailable NOPE: "+reqMajor+"."+reqProfile);
+ System.err.println(getThreadName() + ": createContextARB-MapGLVersions NOPE "+device+", "+reqMajor+" ("+GLContext.getGLProfile(new StringBuilder(), reqProfile).toString()+ ") ["+maxMajor+"."+maxMinor+" .. "+minMajor+"."+minMinor+"]");
}
res = false;
}
@@ -1188,11 +1403,11 @@ public abstract class GLContextImpl extends GLContext {
}
private final long createContextARBVersions(final long share, final boolean direct, final int ctxOptionFlags,
- final int majorMax, final int minorMax,
- final int majorMin, final int minorMin,
+ final int maxMajor, final int maxMinor,
+ final int minMajor, final int minMinor,
final int major[], final int minor[]) {
- major[0]=majorMax;
- minor[0]=minorMax;
+ major[0]=maxMajor;
+ minor[0]=maxMinor;
long _context=0;
int i=0;
@@ -1200,7 +1415,7 @@ public abstract class GLContextImpl extends GLContext {
if (DEBUG) {
i++;
System.err.println(getThreadName() + ": createContextARBVersions."+i+": share "+share+", direct "+direct+
- ", version "+major[0]+"."+minor[0]+", major["+majorMin+".."+majorMax+"], minor["+minorMin+".."+minorMax+"]");
+ ", version "+major[0]+"."+minor[0]+" ["+maxMajor+"."+maxMinor+" .. "+minMajor+"."+minMinor+"]");
}
_context = createContextARBImpl(share, direct, ctxOptionFlags, major[0], minor[0]);
@@ -1213,12 +1428,12 @@ public abstract class GLContextImpl extends GLContext {
}
}
- } while ( ( major[0]>majorMin || major[0]==majorMin && minor[0] >minorMin ) && // #1 check whether version is above lower limit
+ } while ( ( major[0]>minMajor || major[0]==minMajor && minor[0] >minMinor ) && // #1 check whether version is above lower limit
GLContext.decrementGLVersion(ctxOptionFlags, major, minor) // #2 decrement version
);
if (DEBUG) {
System.err.println(getThreadName() + ": createContextARBVersions.X: ctx "+toHexString(_context)+", share "+share+", direct "+direct+
- ", version "+major[0]+"."+minor[0]+", major["+majorMin+".."+majorMax+"], minor["+minorMin+".."+minorMax+"]");
+ ", version "+major[0]+"."+minor[0]+" ["+maxMajor+"."+maxMinor+" .. "+minMajor+"."+minMinor+"]");
}
return _context;
}
@@ -1261,11 +1476,19 @@ public abstract class GLContextImpl extends GLContext {
// Helpers for various context implementations
//
- private final Object createInstance(final GLProfile glp, final boolean glObject, final Object[] cstrArgs) {
+ private final boolean verifyInstance(final GLProfile glp, final String suffix, final Object instance) {
+ return ReflectionUtil.instanceOf(instance, glp.getGLImplBaseClassName()+suffix);
+ }
+ private final Object createInstance(final AbstractGraphicsDevice adevice, final int majorVersion, final int minorVersion, final int contextOption,
+ final boolean glObject, final Object[] cstrArgs) {
+ final String profileString = GLContext.getGLProfile(majorVersion, minorVersion, contextOption);
+ final GLProfile glp = GLProfile.get(adevice, profileString) ;
return ReflectionUtil.createInstance(glp.getGLCtor(glObject), cstrArgs);
}
-
- private final boolean verifyInstance(final GLProfile glp, final String suffix, final Object instance) {
+ private final boolean verifyInstance(final AbstractGraphicsDevice adevice, final int majorVersion, final int minorVersion, final int contextOption,
+ final String suffix, final Object instance) {
+ final String profileString = GLContext.getGLProfile(majorVersion, minorVersion, contextOption);
+ final GLProfile glp = GLProfile.get(adevice, profileString) ;
return ReflectionUtil.instanceOf(instance, glp.getGLImplBaseClassName()+suffix);
}
@@ -1273,8 +1496,11 @@ public abstract class GLContextImpl extends GLContext {
* Create the GL instance for this context,
* requires valid {@link #getGLProcAddressTable()} result!
*/
- private final GL createGL(final GLProfile glp) {
- final GL gl = (GL) createInstance(glp, true, new Object[] { glp, this } );
+ private final GL createGL(final AbstractGraphicsDevice adevice, final int majorVersion, final int minorVersion, final int contextOption) {
+ final String profileString = GLContext.getGLProfile(majorVersion, minorVersion, contextOption);
+ final GLProfile glp = GLProfile.get(adevice, profileString);
+ final GL gl = (GL) ReflectionUtil.createInstance(glp.getGLCtor(true), new Object[] { glp, this });
+ //nal GL gl = (GL) createInstance(glp, true, new Object[] { glp, this } );
/* FIXME: refactor dependence on Java 2D / JOGL bridge
if (tracker != null) {
@@ -1348,34 +1574,53 @@ public abstract class GLContextImpl extends GLContext {
}
protected abstract Map<String, String> getExtensionNameMap() ;
+ /**
+ * Returns the DynamicLookupHelper
+ */
+ public final GLDynamicLookupHelper getGLDynamicLookupHelper() {
+ return drawable.getFactoryImpl().getGLDynamicLookupHelper( ctxVersion.getMajor(), ctxOptions );
+ }
+ public final GLDynamicLookupHelper getGLDynamicLookupHelper(final int majorVersion, final int contextOptions) {
+ return drawable.getFactoryImpl().getGLDynamicLookupHelper( majorVersion, contextOptions );
+ }
+
/** Helper routine which resets a ProcAddressTable generated by the
- GLEmitter by looking up anew all of its function pointers. */
- protected final void resetProcAddressTable(final ProcAddressTable table) {
+ GLEmitter by looking up anew all of its function pointers
+ using the given {@link GLDynamicLookupHelper}. */
+ protected final void resetProcAddressTable(final ProcAddressTable table, final GLDynamicLookupHelper dlh) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
- table.reset(getDrawableImpl().getGLDynamicLookupHelper() );
+ table.reset( dlh );
return null;
}
} );
}
- private final PrivilegedAction<Object> privInitGLGetPtrAction = new PrivilegedAction<Object>() {
- @Override
- public Object run() {
- final GLDynamicLookupHelper glDynLookupHelper = getDrawableImpl().getGLDynamicLookupHelper();
- glDynLookupHelper.claimAllLinkPermission();
- try {
- glGetStringPtr = glDynLookupHelper.dynamicLookupFunction("glGetString");
- glGetIntegervPtr = glDynLookupHelper.dynamicLookupFunction("glGetIntegerv");
- } finally {
- glDynLookupHelper.releaseAllLinkPermission();
- }
- return null;
- } };
- private final boolean initGLRendererAndGLVersionStrings() {
+ /**
+ * Updates the platform's 'GLX' function cache
+ * @param contextFQN provides a fully qualified key of the context including device and GL profile
+ * @param dlh {@link GLDynamicLookupHelper} used to {@link #resetProcAddressTable(ProcAddressTable, GLDynamicLookupHelper)} instance.
+ */
+ protected abstract void updateGLXProcAddressTable(final String contextFQN, final GLDynamicLookupHelper dlh);
+
+ private final boolean initGLRendererAndGLVersionStrings(final int majorVersion, final int contextOptions) {
if( !glGetPtrInit ) {
- AccessController.doPrivileged(privInitGLGetPtrAction);
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ @Override
+ public Object run() {
+ final GLDynamicLookupHelper glDynLookupHelper = getGLDynamicLookupHelper(majorVersion, contextOptions);
+ if( null != glDynLookupHelper ) {
+ glDynLookupHelper.claimAllLinkPermission();
+ try {
+ glGetStringPtr = glDynLookupHelper.dynamicLookupFunction("glGetString");
+ glGetIntegervPtr = glDynLookupHelper.dynamicLookupFunction("glGetIntegerv");
+ } finally {
+ glDynLookupHelper.releaseAllLinkPermission();
+ }
+ }
+ return null;
+ } } );
glGetPtrInit = true;
}
if( 0 == glGetStringPtr || 0 == glGetIntegervPtr ) {
@@ -1521,7 +1766,7 @@ public abstract class GLContextImpl extends GLContext {
final VersionNumber reqGLVersion = new VersionNumber(major, minor, 0);
final VersionNumber hasGLVersionByString;
{
- final boolean initGLRendererAndGLVersionStringsOK = initGLRendererAndGLVersionStrings();
+ final boolean initGLRendererAndGLVersionStringsOK = initGLRendererAndGLVersionStrings(major, ctxProfileBits);
if( !initGLRendererAndGLVersionStringsOK ) {
final String errMsg = "Intialization of GL renderer strings failed. "+adevice+" - "+GLContext.getGLVersion(major, minor, ctxProfileBits, null);
if( strictMatch ) {
@@ -1557,50 +1802,51 @@ public abstract class GLContextImpl extends GLContext {
{
// Validate the requested version w/ the GL-version from an integer query,
// as supported by GL [ES] >= 3.0 implementation.
- final VersionNumber hasGLVersionByInt;
- {
- final int[] glIntMajor = new int[] { 0 }, glIntMinor = new int[] { 0 };
- getGLIntVersion(glIntMajor, glIntMinor);
- hasGLVersionByInt = new VersionNumber(glIntMajor[0], glIntMinor[0], 0);
- }
- if (DEBUG) {
- System.err.println(getThreadName() + ": GLContext.setGLFuncAvail: Version verification (Int): String "+glVersion+", Number(Int) "+hasGLVersionByInt);
- }
-
+ //
// Only validate integer based version if:
// - ctx >= 3.0 is requested _or_ string-version >= 3.0
// - _and_ a valid int version was fetched,
// otherwise cont. w/ version-string method -> 3.0 > Version || Version > MAX!
//
- if ( ( major >= 3 || hasGLVersionByString.compareTo(Version3_0) >= 0 ) &&
- GLContext.isValidGLVersion(ctxProfileBits, hasGLVersionByInt.getMajor(), hasGLVersionByInt.getMinor()) ) {
- // Strict Match (GLVersionMapping):
- // Relaxed match for versions ( !isES && major < 3 ) requests, last resort!
- // Otherwise:
- // - fail if hasVersion < reqVersion (desktop and ES)
- // - fail if ES major-version mismatch:
- // - request 1, >= 3 must be equal
- // - request 2 must be [2..3]
- //
- final int hasMajor = hasGLVersionByInt.getMajor();
- if( strictMatch &&
- ( ( ( isES || major >= 3 ) && hasGLVersionByInt.compareTo(reqGLVersion) < 0 ) ||
- ( isES &&
- (
- ( 2 == major && ( 2 > hasMajor || hasMajor > 3 ) ) || // 2 -> [2..3]
- ( ( 1 == major || 3 <= major ) && major != hasMajor ) // 1,3,.. -> equal
- )
- )
- ) ) {
- if(DEBUG) {
- System.err.println(getThreadName() + ": GLContext.setGLFuncAvail.X: FAIL, GL version mismatch (Int): "+GLContext.getGLVersion(major, minor, ctxProfileBits, null)+" -> "+glVersion+", "+hasGLVersionByInt);
+ final VersionNumber hasGLVersionByInt;
+ if ( major >= 3 || hasGLVersionByString.compareTo(Version3_0) >= 0 ) {
+ final int[] glIntMajor = new int[] { 0 }, glIntMinor = new int[] { 0 };
+ getGLIntVersion(glIntMajor, glIntMinor);
+ hasGLVersionByInt = new VersionNumber(glIntMajor[0], glIntMinor[0], 0);
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": GLContext.setGLFuncAvail: Version verification (Int): String "+glVersion+", Number(Int) "+hasGLVersionByInt);
+ }
+ if ( GLContext.isValidGLVersion(ctxProfileBits, hasGLVersionByInt.getMajor(), hasGLVersionByInt.getMinor()) ) {
+ // Strict Match (GLVersionMapping):
+ // Relaxed match for versions ( !isES && major < 3 ) requests, last resort!
+ // Otherwise:
+ // - fail if hasVersion < reqVersion (desktop and ES)
+ // - fail if ES major-version mismatch:
+ // - request 1, >= 3 must be equal
+ // - request 2 must be [2..3]
+ //
+ final int hasMajor = hasGLVersionByInt.getMajor();
+ if( strictMatch &&
+ ( ( ( isES || major >= 3 ) && hasGLVersionByInt.compareTo(reqGLVersion) < 0 ) ||
+ ( isES &&
+ (
+ ( 2 == major && ( 2 > hasMajor || hasMajor > 3 ) ) || // 2 -> [2..3]
+ ( ( 1 == major || 3 <= major ) && major != hasMajor ) // 1,3,.. -> equal
+ )
+ )
+ ) ) {
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": GLContext.setGLFuncAvail.X: FAIL, GL version mismatch (Int): "+GLContext.getGLVersion(major, minor, ctxProfileBits, null)+" -> "+glVersion+", "+hasGLVersionByInt);
+ }
+ return false;
}
- return false;
+ // Use returned GL version!
+ major = hasGLVersionByInt.getMajor();
+ minor = hasGLVersionByInt.getMinor();
+ versionGL3IntOK = true;
+ } else {
+ versionGL3IntOK = false;
}
- // Use returned GL version!
- major = hasGLVersionByInt.getMajor();
- minor = hasGLVersionByInt.getMinor();
- versionGL3IntOK = true;
} else {
versionGL3IntOK = false;
}
@@ -1668,7 +1914,8 @@ public abstract class GLContextImpl extends GLContext {
}
if( major < 2 ) { // there is no ES2/3-compat for a profile w/ major < 2
- ctxProfileBits &= ~ ( GLContext.CTX_IMPL_ES2_COMPAT | GLContext.CTX_IMPL_ES3_COMPAT | GLContext.CTX_IMPL_ES31_COMPAT ) ;
+ ctxProfileBits &= ~ ( GLContext.CTX_IMPL_ES2_COMPAT | GLContext.CTX_IMPL_ES3_COMPAT |
+ GLContext.CTX_IMPL_ES31_COMPAT | GLContext.CTX_IMPL_ES32_COMPAT ) ;
}
if(!isCurrentContextHardwareRasterizer()) {
@@ -1692,43 +1939,72 @@ public abstract class GLContextImpl extends GLContext {
if (DEBUG) {
System.err.println(getThreadName() + ": GLContext.setGLFuncAvail.0 validated FQN: "+contextFQN+" - "+GLContext.getGLVersion(major, minor, ctxProfileBits, glVersion));
}
-
- updateGLXProcAddressTable();
+ final GLDynamicLookupHelper dynamicLookup = getGLDynamicLookupHelper(major, ctxProfileBits);
+ if( null == dynamicLookup ) {
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": GLContext.setGLFuncAvail.X: FAIL, No GLDynamicLookupHelper for request: "+GLContext.getGLVersion(major, minor, ctxProfileBits, null));
+ }
+ return false;
+ }
+ updateGLXProcAddressTable(contextFQN, dynamicLookup);
//
// UpdateGLProcAddressTable functionality
// _and_ setup GL instance, which ctor requires valid getGLProcAddressTable() result!
//
{
- final GLProfile glp = drawable.getGLProfile();
+ final GLProfile glp = drawable.getGLProfile(); // !withinGLVersionsMapping
ProcAddressTable table = null;
synchronized(mappedContextTypeObjectLock) {
table = mappedGLProcAddress.get( contextFQN );
- if(null != table && !verifyInstance(glp, "ProcAddressTable", table)) {
- throw new GLException("GLContext GL ProcAddressTable mapped key("+contextFQN+" - " + GLContext.getGLVersion(major, minor, ctxProfileBits, null)+
- ") -> "+ table.getClass().getName()+" not matching "+glp.getGLImplBaseClassName());
+ if(null != table) {
+ if( !verifyInstance(adevice, major, minor, ctxProfileBits, "ProcAddressTable", table) ) {
+ throw new GLException("GLContext GL ProcAddressTable mapped key("+contextFQN+" - " + GLContext.getGLVersion(major, minor, ctxProfileBits, null)+
+ ") -> "+ toHexString(table.hashCode()) +" not matching "+table.getClass().getName());
+ }
+ if( !withinGLVersionsMapping && !verifyInstance(glp, "ProcAddressTable", table) ) {
+ throw new GLException("GLContext GL ProcAddressTable mapped key("+contextFQN+" - " + GLContext.getGLVersion(major, minor, ctxProfileBits, null)+
+ ") -> "+ toHexString(table.hashCode()) +": "+table.getClass().getName()+" not matching "+glp.getGLImplBaseClassName()+"/"+glp);
+ }
}
}
if(null != table) {
glProcAddressTable = table;
if(DEBUG) {
- System.err.println(getThreadName() + ": GLContext GL ProcAddressTable reusing key("+contextFQN+") -> "+toHexString(table.hashCode()));
+ if( withinGLVersionsMapping ) {
+ System.err.println(getThreadName() + ": GLContext GL ProcAddressTable reusing key("+contextFQN+" - " + GLContext.getGLVersion(major, minor, ctxProfileBits, null)+
+ ") -> "+ toHexString(table.hashCode()) +": "+table.getClass().getName());
+ } else {
+ System.err.println(getThreadName() + ": GLContext GL ProcAddressTable reusing key("+contextFQN+" - " + GLContext.getGLVersion(major, minor, ctxProfileBits, null)+
+ ") -> "+ toHexString(table.hashCode()) +": "+table.getClass().getName()+" -> "+glp.getGLImplBaseClassName());
+ }
}
} else {
- glProcAddressTable = (ProcAddressTable) createInstance(glp, false,
+ glProcAddressTable = (ProcAddressTable) createInstance(adevice, major, minor, ctxProfileBits, false,
new Object[] { new GLProcAddressResolver() } );
- resetProcAddressTable( glProcAddressTable );
+ resetProcAddressTable(glProcAddressTable, dynamicLookup);
+
synchronized(mappedContextTypeObjectLock) {
mappedGLProcAddress.put(contextFQN, glProcAddressTable);
if(DEBUG) {
- System.err.println(getThreadName() + ": GLContext GL ProcAddressTable mapping key("+contextFQN+") -> "+toHexString(glProcAddressTable.hashCode()));
+ if( withinGLVersionsMapping ) {
+ System.err.println(getThreadName() + ": GLContext GL ProcAddressTable mapping key("+contextFQN+" - " + GLContext.getGLVersion(major, minor, ctxProfileBits, null)+
+ ") -> "+toHexString(glProcAddressTable.hashCode()) +": "+glProcAddressTable.getClass().getName());
+ } else {
+ System.err.println(getThreadName() + ": GLContext GL ProcAddressTable mapping key("+contextFQN+" - " + GLContext.getGLVersion(major, minor, ctxProfileBits, null)+
+ ") -> "+toHexString(glProcAddressTable.hashCode()) +": "+glProcAddressTable.getClass().getName()+" -> "+glp.getGLImplBaseClassName());
+ }
}
}
}
- if( null == this.gl || !verifyInstance(glp, "Impl", this.gl) ) {
- setGL( createGL( glp ) );
+ if( null == this.gl || !verifyInstance(adevice, major, minor, ctxProfileBits, "Impl", this.gl) ) {
+ setGL( createGL( adevice, major, minor, ctxProfileBits ) );
+ }
+ if( !withinGLVersionsMapping && !verifyInstance(glp, "Impl", this.gl) ) {
+ throw new GLException("GLContext GL Object mismatch: "+GLContext.getGLVersion(major, minor, ctxProfileBits, null)+
+ ") -> "+": "+this.gl.getClass().getName()+" not matching "+glp.getGLImplBaseClassName()+"/"+glp);
}
}
@@ -1762,7 +2038,9 @@ public abstract class GLContextImpl extends GLContext {
if( major >= 3 ) {
ctxProfileBits |= CTX_IMPL_ES3_COMPAT | CTX_IMPL_ES2_COMPAT ;
ctxProfileBits |= CTX_IMPL_FBO;
- if( minor >= 1 ) {
+ if( minor >= 2 ) {
+ ctxProfileBits |= CTX_IMPL_ES32_COMPAT | CTX_IMPL_ES31_COMPAT;
+ } else if( minor >= 1 ) {
ctxProfileBits |= CTX_IMPL_ES31_COMPAT;
}
} else if( major >= 2 ) {
@@ -1770,10 +2048,15 @@ public abstract class GLContextImpl extends GLContext {
ctxProfileBits |= CTX_IMPL_FBO;
}
} else if( ( major > 4 || major == 4 && minor >= 5 ) ||
- ( ( major > 3 || major == 3 && minor >= 1 ) && isExtensionAvailable( GLExtensions.ARB_ES3_1_compatibility ) ) ) {
- // See GLContext.isGLES31CompatibleAvailable(..)/isGLES31Compatible()
- // Includes [ GL &ge; 4.5, GL &ge; 3.1 w/ GL_ARB_ES3_1_compatibility and GLES &ge; 3.1 ]
- ctxProfileBits |= CTX_IMPL_ES31_COMPAT | CTX_IMPL_ES3_COMPAT | CTX_IMPL_ES2_COMPAT ;
+ ( major > 3 || major == 3 && minor >= 1 ) ) {
+ // See GLContext.isGLES31CompatibleAvailable(..)/isGLES3[12]Compatible()
+ // Includes [ GL &ge; 4.5, GL &ge; 3.1 w/ GL_ARB_ES3_[12]_compatibility and GLES &ge; 3.[12] ]
+ if( isExtensionAvailable( GLExtensions.ARB_ES3_2_compatibility ) ) {
+ ctxProfileBits |= CTX_IMPL_ES32_COMPAT | CTX_IMPL_ES31_COMPAT;
+ } else if( isExtensionAvailable( GLExtensions.ARB_ES3_1_compatibility ) ) {
+ ctxProfileBits |= CTX_IMPL_ES31_COMPAT;
+ }
+ ctxProfileBits |= CTX_IMPL_ES3_COMPAT | CTX_IMPL_ES2_COMPAT;
ctxProfileBits |= CTX_IMPL_FBO;
} else if( ( major > 4 || major == 4 && minor >= 3 ) ||
( ( major > 3 || major == 3 && minor >= 1 ) && isExtensionAvailable( GLExtensions.ARB_ES3_compatibility ) ) ) {
@@ -1813,6 +2096,31 @@ public abstract class GLContextImpl extends GLContext {
return true;
}
+ private static final void addStickyQuirkAlways(final AbstractGraphicsDevice adevice,
+ final GLRendererQuirks quirks,
+ final int quirk,
+ final boolean withinGLVersionsMapping) {
+ quirks.addQuirk( quirk );
+ if( withinGLVersionsMapping ) {
+ // Thread safe due to single threaded initialization!
+ GLRendererQuirks.addStickyDeviceQuirk(adevice, quirk);
+ } else {
+ // FIXME: Remove when moving EGL/ES to ARB ctx creation
+ synchronized(GLContextImpl.class) {
+ GLRendererQuirks.addStickyDeviceQuirk(adevice, quirk);
+ }
+ }
+ }
+ private static final void addStickyQuirkAtMapping(final AbstractGraphicsDevice adevice,
+ final GLRendererQuirks quirks,
+ final int quirk,
+ final boolean withinGLVersionsMapping) {
+ quirks.addQuirk( quirk );
+ if( withinGLVersionsMapping ) {
+ // Thread safe due to single threaded initialization!
+ GLRendererQuirks.addStickyDeviceQuirk(adevice, quirk);
+ }
+ }
private final void setRendererQuirks(final AbstractGraphicsDevice adevice, final GLDrawableFactoryImpl factory,
final int reqMajor, final int reqMinor, final int reqCTP,
final int major, final int minor, final int ctp, final VersionNumberString vendorVersion,
@@ -1822,10 +2130,10 @@ public abstract class GLContextImpl extends GLContext {
final String MesaRendererIntelsp = "Intel(R)";
final boolean hwAccel = 0 == ( ctp & GLContext.CTX_IMPL_ACCEL_SOFT );
final boolean compatCtx = 0 != ( ctp & GLContext.CTX_PROFILE_COMPAT );
- final boolean esCtx = 0 != ( ctp & GLContext.CTX_PROFILE_ES );
+ final boolean isES = 0 != ( ctp & GLContext.CTX_PROFILE_ES );
final boolean isX11 = NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(true);
final boolean isWindows = Platform.getOSType() == Platform.OSType.WINDOWS;
- final boolean isDriverMesa = glRenderer.contains(MesaSP) || glRenderer.contains("Gallium ");
+ final boolean isDriverMesa = glRenderer.contains(MesaSP) || glRenderer.contains("Gallium ") || glVersion.contains(MesaSP);
final boolean isDriverATICatalyst;
final boolean isDriverNVIDIAGeForce;
@@ -1845,22 +2153,13 @@ public abstract class GLContextImpl extends GLContext {
//
// General Quirks
//
- if( esCtx ) {
+ if( isES ) {
if( 2 == reqMajor && 2 < major ) {
final int quirk = GLRendererQuirks.GLES3ViaEGLES2Config;
if(DEBUG) {
System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: ES req "+reqMajor+" and 2 < "+major);
}
- quirks.addQuirk( quirk );
- if( withinGLVersionsMapping ) {
- // Thread safe due to single threaded initialization!
- GLRendererQuirks.addStickyDeviceQuirk(adevice, quirk);
- } else {
- // FIXME: Remove when moving EGL/ES to ARB ctx creation
- synchronized(GLContextImpl.class) {
- GLRendererQuirks.addStickyDeviceQuirk(adevice, quirk);
- }
- }
+ addStickyQuirkAlways(adevice, quirks, quirk, withinGLVersionsMapping);
}
}
if( GLProfile.disableSurfacelessContext ) {
@@ -1868,32 +2167,14 @@ public abstract class GLContextImpl extends GLContext {
if(DEBUG) {
System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: disabled");
}
- quirks.addQuirk( quirk );
- if( withinGLVersionsMapping ) {
- // Thread safe due to single threaded initialization!
- GLRendererQuirks.addStickyDeviceQuirk(adevice, quirk);
- } else {
- // FIXME: Remove when moving EGL/ES to ARB ctx creation
- synchronized(GLContextImpl.class) {
- GLRendererQuirks.addStickyDeviceQuirk(adevice, quirk);
- }
- }
+ addStickyQuirkAlways(adevice, quirks, quirk, withinGLVersionsMapping);
}
if( GLProfile.disableOpenGLARBContext ) {
final int quirk = GLRendererQuirks.NoARBCreateContext;
if(DEBUG) {
System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: disabled");
}
- quirks.addQuirk( quirk );
- if( withinGLVersionsMapping ) {
- // Thread safe due to single threaded initialization!
- GLRendererQuirks.addStickyDeviceQuirk(adevice, quirk);
- } else {
- // FIXME: Remove when moving EGL/ES to ARB ctx creation
- synchronized(GLContextImpl.class) {
- GLRendererQuirks.addStickyDeviceQuirk(adevice, quirk);
- }
- }
+ addStickyQuirkAlways(adevice, quirks, quirk, withinGLVersionsMapping);
}
//
@@ -1922,11 +2203,7 @@ public abstract class GLContextImpl extends GLContext {
if(DEBUG) {
System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: OS "+Platform.getOSType()+", OS Version "+Platform.getOSVersionNumber()+", req "+reqMajor+"."+reqMinor);
}
- quirks.addQuirk( quirk );
- if( withinGLVersionsMapping ) {
- // Thread safe due to single threaded initialization!
- GLRendererQuirks.addStickyDeviceQuirk(adevice, quirk);
- }
+ addStickyQuirkAtMapping(adevice, quirks, quirk, withinGLVersionsMapping);
}
if( isDriverNVIDIAGeForce ) {
final VersionNumber osxVersionNVFlushClean = new VersionNumber(10,7,3); // < OSX 10.7.3 w/ NV needs glFlush
@@ -1984,11 +2261,7 @@ public abstract class GLContextImpl extends GLContext {
if(DEBUG) {
System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: OS "+Platform.getOSType()+", [Vendor "+glVendor+", Renderer "+glRenderer+" and Version "+glVersion+"]");
}
- quirks.addQuirk( quirk );
- if( withinGLVersionsMapping ) {
- // Thread safe due to single threaded initialization!
- GLRendererQuirks.addStickyDeviceQuirk(adevice, quirk);
- }
+ addStickyQuirkAtMapping(adevice, quirks, quirk, withinGLVersionsMapping);
}
}
} else if( isDriverIntel && glRenderer.equals("Intel Bear Lake B") ) {
@@ -2054,6 +2327,17 @@ public abstract class GLContextImpl extends GLContext {
}
}
}
+ if( isDriverNVIDIAGeForce ) {
+ // Bug 1200: Crash on GNU/Linux x86_64 'NVidia beta driver 355.06' @ probeSurfacelessCtx
+ // final VersionNumber nvSafeVersion = new VersionNumber(356, 0, 0); // FIXME: Add safe version!
+ if( !isES && !(adevice instanceof EGLGraphicsDevice) /* && vendorVersion.compareTo(nvSafeVersion) < 0 */ ) {
+ final int quirk = GLRendererQuirks.NoSurfacelessCtx;
+ if(DEBUG) {
+ System.err.print("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: !ES, !EGL, Vendor " + glVendor +", X11 Renderer " + glRenderer+", Version=[vendor " + vendorVersion + ", GL " + glVersion+"]");
+ }
+ addStickyQuirkAtMapping(adevice, quirks, quirk, withinGLVersionsMapping);
+ }
+ }
}
@@ -2063,8 +2347,10 @@ public abstract class GLContextImpl extends GLContext {
if( isDriverMesa ) {
final VersionNumber mesaSafeFBOVersion = new VersionNumber(8, 0, 0);
final VersionNumber mesaIntelBuggySharedCtx921 = new VersionNumber(9, 2, 1);
+ final VersionNumber mesaSafeDoubleBufferedPBuffer = new VersionNumber(18, 2, 2); // Mesa 18.2.2
+ final VersionNumber mesaSafeSetSwapIntervalPostRetarget = mesaSafeDoubleBufferedPBuffer; // Mesa 18.2.2
- {
+ if( vendorVersion.compareTo(mesaSafeSetSwapIntervalPostRetarget) < 0 ) {
final int quirk = GLRendererQuirks.NoSetSwapIntervalPostRetarget;
if(DEBUG) {
System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: Renderer " + glRenderer);
@@ -2073,11 +2359,13 @@ public abstract class GLContextImpl extends GLContext {
}
if( hwAccel ) {
// hardware-acceleration
- final int quirk = GLRendererQuirks.NoDoubleBufferedPBuffer;
- if(DEBUG) {
- System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: Renderer " + glRenderer);
+ if( vendorVersion.compareTo(mesaSafeDoubleBufferedPBuffer) < 0 ) {
+ final int quirk = GLRendererQuirks.NoDoubleBufferedPBuffer;
+ if(DEBUG) {
+ System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: Renderer " + glRenderer);
+ }
+ quirks.addQuirk( quirk );
}
- quirks.addQuirk( quirk );
} else {
// software
if( vendorVersion.compareTo(mesaSafeFBOVersion) < 0 ) { // FIXME: Is it fixed in >= 8.0.0 ?
@@ -2111,11 +2399,7 @@ public abstract class GLContextImpl extends GLContext {
if(DEBUG) {
System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: X11 / Renderer " + glRenderer + " / Vendor "+glVendor);
}
- quirks.addQuirk( quirk );
- if( withinGLVersionsMapping ) {
- // Thread safe due to single threaded initialization!
- GLRendererQuirks.addStickyDeviceQuirk(adevice, quirk);
- }
+ addStickyQuirkAtMapping(adevice, quirks, quirk, withinGLVersionsMapping);
}
if( isWindows && glRenderer.contains("SVGA3D") && vendorVersion.compareTo(mesaSafeFBOVersion) < 0 ) {
final int quirk = GLRendererQuirks.NoFullFBOSupport;
@@ -2157,7 +2441,7 @@ public abstract class GLContextImpl extends GLContext {
if( !GLRendererQuirks.areSameStickyDevice(factoryDefaultDevice, adevice) ) {
GLRendererQuirks.pushStickyDeviceQuirks(factoryDefaultDevice, quirks);
}
- if( esCtx ) {
+ if( isES ) {
final AbstractGraphicsDevice eglFactoryDefaultDevice = GLDrawableFactory.getEGLFactory().getDefaultDevice();
if( !GLRendererQuirks.areSameStickyDevice(eglFactoryDefaultDevice, adevice) &&
!GLRendererQuirks.areSameStickyDevice(eglFactoryDefaultDevice, factoryDefaultDevice) ) {
@@ -2233,11 +2517,6 @@ public abstract class GLContextImpl extends GLContext {
return isHardwareRasterizer;
}
- /**
- * Updates the platform's 'GLX' function cache
- */
- protected abstract void updateGLXProcAddressTable();
-
protected abstract StringBuilder getPlatformExtensionsStringImpl();
@Override
@@ -2262,7 +2541,10 @@ public abstract class GLContextImpl extends GLContext {
}
// dynamic function lookup at last incl name aliasing (not cached)
- final DynamicLookupHelper dynLookup = getDrawableImpl().getGLDynamicLookupHelper();
+ final DynamicLookupHelper dynLookup = getGLDynamicLookupHelper(ctxVersion.getMajor(), ctxOptions);
+ if( null == dynLookup ) {
+ throw new GLException("No GLDynamicLookupHelper for "+this);
+ }
final String tmpBase = GLNameResolver.normalizeVEN(GLNameResolver.normalizeARB(glFunctionName, true), true);
return AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
@Override
@@ -2378,6 +2660,40 @@ public abstract class GLContextImpl extends GLContext {
}
//----------------------------------------------------------------------
+ // SwapBuffer
+
+ @Override
+ public final boolean setSwapInterval(final int interval) throws GLException {
+ validateCurrent();
+ return setSwapIntervalNC(interval);
+ }
+ protected final boolean setSwapIntervalNC(final int interval) throws GLException {
+ if( !drawableRetargeted ||
+ !hasRendererQuirk(GLRendererQuirks.NoSetSwapIntervalPostRetarget)
+ )
+ {
+ final Integer usedInterval = setSwapIntervalImpl2(interval);
+ if( null != usedInterval ) {
+ currentSwapInterval = usedInterval.intValue();
+ return true;
+ }
+ }
+ return false;
+ }
+ protected abstract Integer setSwapIntervalImpl2(final int interval);
+
+ @Override
+ public final int getSwapInterval() {
+ return currentSwapInterval;
+ }
+ @Override
+ protected final void setDefaultSwapInterval() {
+ currentSwapInterval = 0;
+ setSwapIntervalNC(1);
+ }
+
+
+ //----------------------------------------------------------------------
// Helpers for buffer object optimizations
public final GLBufferObjectTracker getBufferObjectTracker() {
@@ -2536,8 +2852,8 @@ public abstract class GLContextImpl extends GLContext {
@Override
public final void glDebugMessageControl(final int source, final int type, final int severity, final int count, final IntBuffer ids, final boolean enabled) {
- if(glDebugHandler.isExtensionARB()) {
- gl.getGL2GL3().glDebugMessageControl(source, type, severity, count, ids, enabled);
+ if(glDebugHandler.isExtensionKHRARB()) {
+ gl.getGL2ES2().glDebugMessageControl(source, type, severity, count, ids, enabled);
} else if(glDebugHandler.isExtensionAMD()) {
gl.getGL2GL3().glDebugMessageEnableAMD(GLDebugMessage.translateARB2AMDCategory(source, type), severity, count, ids, enabled);
}
@@ -2545,8 +2861,8 @@ public abstract class GLContextImpl extends GLContext {
@Override
public final void glDebugMessageControl(final int source, final int type, final int severity, final int count, final int[] ids, final int ids_offset, final boolean enabled) {
- if(glDebugHandler.isExtensionARB()) {
- gl.getGL2GL3().glDebugMessageControl(source, type, severity, count, ids, ids_offset, enabled);
+ if(glDebugHandler.isExtensionKHRARB()) {
+ gl.getGL2ES2().glDebugMessageControl(source, type, severity, count, ids, ids_offset, enabled);
} else if(glDebugHandler.isExtensionAMD()) {
gl.getGL2GL3().glDebugMessageEnableAMD(GLDebugMessage.translateARB2AMDCategory(source, type), severity, count, ids, ids_offset, enabled);
}
@@ -2555,8 +2871,8 @@ public abstract class GLContextImpl extends GLContext {
@Override
public final void glDebugMessageInsert(final int source, final int type, final int id, final int severity, final String buf) {
final int len = (null != buf) ? buf.length() : 0;
- if(glDebugHandler.isExtensionARB()) {
- gl.getGL2GL3().glDebugMessageInsert(source, type, id, severity, len, buf);
+ if(glDebugHandler.isExtensionKHRARB()) {
+ gl.getGL2ES2().glDebugMessageInsert(source, type, id, severity, len, buf);
} else if(glDebugHandler.isExtensionAMD()) {
gl.getGL2GL3().glDebugMessageInsertAMD(GLDebugMessage.translateARB2AMDCategory(source, type), severity, id, len, buf);
}
diff --git a/src/jogl/classes/jogamp/opengl/GLDebugMessageHandler.java b/src/jogl/classes/jogamp/opengl/GLDebugMessageHandler.java
index cd31d02fd..fb4529da4 100644
--- a/src/jogl/classes/jogamp/opengl/GLDebugMessageHandler.java
+++ b/src/jogl/classes/jogamp/opengl/GLDebugMessageHandler.java
@@ -61,8 +61,9 @@ import com.jogamp.opengl.GLExtensions;
public class GLDebugMessageHandler {
private static final boolean DEBUG = Debug.debug("GLDebugMessageHandler");
- private static final int EXT_ARB = 1;
- private static final int EXT_AMD = 2;
+ private static final int EXT_KHR = 1;
+ private static final int EXT_ARB = 2;
+ private static final int EXT_AMD = 3;
static {
if ( !initIDs0() ) {
@@ -75,6 +76,7 @@ public class GLDebugMessageHandler {
// licefycle: init - EOL
private String extName;
+ private String extSuffix;
private int extType;
private long glDebugMessageCallbackProcAddress;
private boolean extAvailable;
@@ -92,6 +94,7 @@ public class GLDebugMessageHandler {
this.listenerImpl = new ListenerSyncedImplStub<GLDebugListener>();
this.glDebugMessageCallbackProcAddress = 0;
this.extName = null;
+ this.extSuffix = null;
this.extType = 0;
this.extAvailable = false;
this.handle = 0;
@@ -143,43 +146,68 @@ public class GLDebugMessageHandler {
}
return;
}
- if( ctx.isExtensionAvailable(GLExtensions.ARB_debug_output) ) {
+ if( ctx.isExtensionAvailable(GLExtensions.GL_KHR_debug) ) {
+ extName = GLExtensions.GL_KHR_debug;
+ extSuffix = ctx.isGLES() ? "KHR" : ""; // See SPEC!
+ extType = EXT_KHR;
+ } else if( ctx.isExtensionAvailable(GLExtensions.ARB_debug_output) ) {
extName = GLExtensions.ARB_debug_output;
+ extSuffix = "ARB";
extType = EXT_ARB;
} else if( ctx.isExtensionAvailable(GLExtensions.AMD_debug_output) ) {
extName = GLExtensions.AMD_debug_output;
+ extSuffix = "AMD";
extType = EXT_AMD;
}
- if(DEBUG) {
- System.err.println("GLDebugMessageHandler: Using extension: <"+extName+">");
+
+ // Validate GL Profile, just to be sure
+ switch(extType) {
+ case EXT_KHR:
+ if( !ctx.isGL2ES2() ) {
+ if(DEBUG) {
+ System.err.println("Non GL2ES2 context not supported, has "+ctx.getGLVersion());
+ }
+ extType = 0;
+ }
+ break;
+ case EXT_ARB:
+ // fall through intended
+ case EXT_AMD:
+ if( !ctx.isGL2GL3() ) {
+ if(DEBUG) {
+ System.err.println("Non GL2GL3 context not supported, has "+ctx.getGLVersion());
+ }
+ extType = 0;
+ }
+ break;
}
if(0 == extType) {
+ extName = null;
+ extSuffix = null;
if(DEBUG) {
System.err.println("GLDebugMessageHandler: No extension available! "+ctx.getGLVersion());
System.err.println("GL_EXTENSIONS "+ctx.getGLExtensionCount());
System.err.println(ctx.getGLExtensionsString());
}
return;
+ } else if(DEBUG) {
+ System.err.println("GLDebugMessageHandler: Using extension: <"+extName+"> with suffix <"+extSuffix+">");
}
final ProcAddressTable procAddressTable = ctx.getGLProcAddressTable();
- if( !ctx.isGLES1() && !ctx.isGLES2() ) {
- switch(extType) {
- case EXT_ARB:
- glDebugMessageCallbackProcAddress = getAddressFor(procAddressTable, "glDebugMessageCallbackARB");
- break;
- case EXT_AMD:
- glDebugMessageCallbackProcAddress = getAddressFor(procAddressTable, "glDebugMessageCallbackAMD");
- break;
- }
- } else {
- glDebugMessageCallbackProcAddress = 0;
- if(DEBUG) {
- System.err.println("Non desktop context not supported");
- }
+ switch(extType) {
+ case EXT_KHR:
+ glDebugMessageCallbackProcAddress = getAddressFor(procAddressTable, "glDebugMessageCallback"+extSuffix);
+ break;
+ case EXT_ARB:
+ glDebugMessageCallbackProcAddress = getAddressFor(procAddressTable, "glDebugMessageCallback"+extSuffix);
+ break;
+ case EXT_AMD:
+ glDebugMessageCallbackProcAddress = getAddressFor(procAddressTable, "glDebugMessageCallback"+extSuffix);
+ break;
}
- extAvailable = 0 < extType && null != extName && 0 != glDebugMessageCallbackProcAddress;
+ extAvailable = 0 < extType && null != extName && null != extSuffix && 0 != glDebugMessageCallbackProcAddress;
if(DEBUG) {
System.err.println("GLDebugMessageHandler: extAvailable: "+extAvailable+", glDebugMessageCallback* : 0x"+Long.toHexString(glDebugMessageCallbackProcAddress));
@@ -203,12 +231,20 @@ public class GLDebugMessageHandler {
return extName;
}
+ public final boolean isExtensionKHRARB() {
+ return EXT_KHR == extType || EXT_ARB == extType;
+ }
+
+ public final boolean isExtensionKHR() {
+ return EXT_KHR == extType;
+ }
+
public final boolean isExtensionARB() {
- return extName == GLExtensions.ARB_debug_output;
+ return EXT_ARB == extType;
}
public final boolean isExtensionAMD() {
- return extName == GLExtensions.AMD_debug_output;
+ return EXT_AMD == extType;
}
/**
@@ -226,7 +262,7 @@ public class GLDebugMessageHandler {
}
}
private final void setSynchronousImpl() {
- if(isExtensionARB()) {
+ if(isExtensionKHRARB()) {
if(synchronous) {
ctx.getGL().glEnable(GL2ES2.GL_DEBUG_OUTPUT_SYNCHRONOUS);
} else {
diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java b/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
index b7f861e13..dfe6bdd9f 100644
--- a/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
@@ -230,6 +230,15 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
}
/**
+ * Method returns {@code true} if underlying {@link #createContextARBImpl(long, boolean, int, int, int) <i>ARB context creation</i>}
+ * supports {@code major} and {@code minor} version number.
+ * <p>
+ * Otherwise only the {@code major} version number is supported for context creation.
+ * </p>
+ */
+ public abstract boolean hasMajorMinorCreateContextARB();
+
+ /**
* Returns the shared device mapped to the <code>device</code> {@link AbstractGraphicsDevice#getConnection()},
* either a preexisting or newly created, or <code>null</code> if creation failed or not supported.<br>
* Creation of the shared context is tried only once.
@@ -245,12 +254,11 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
}
/**
- * Returns the GLDynamicLookupHelper
- * @param profileName if EGL/ES, profile <code>1</code> refers to ES1 and <code>2</code> to ES2,
- * otherwise the profile is ignored.
- * @throws GLException if no DynamicLookupHelper is installed
+ * Returns the GLDynamicLookupHelper if installed, otherwise {@code null}.
+ * @param majorVersion the major OpenGL profile version
+ * @param contextOptions the context profile options
*/
- public abstract GLDynamicLookupHelper getGLDynamicLookupHelper(final String profileName) throws GLException;
+ public abstract GLDynamicLookupHelper getGLDynamicLookupHelper(final int majorVersion, final int contextOptions);
//---------------------------------------------------------------------------
// Dispatching GLDrawable construction in respect to the NativeSurface Capabilities
diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java b/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java
index e9ee46a51..e4b5eae5c 100644
--- a/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java
+++ b/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java
@@ -61,6 +61,7 @@ import com.jogamp.opengl.GLFBODrawable;
import com.jogamp.opengl.GLRunnable;
import com.jogamp.common.ExceptionUtils;
+import com.jogamp.common.util.InterruptedRuntimeException;
import com.jogamp.common.util.PropertyAccess;
/** Encapsulates the implementation of most of the GLAutoDrawable's
@@ -75,6 +76,8 @@ public class GLDrawableHelper {
}
protected static final boolean DEBUG = GLDrawableImpl.DEBUG;
+ private static final boolean DEBUG_SETCLEAR = GLContext.DEBUG_GL || DEBUG;
+
private final Object listenersLock = new Object();
private final ArrayList<GLEventListener> listeners = new ArrayList<GLEventListener>();
private final HashSet<GLEventListener> listenersToBeInit = new HashSet<GLEventListener>();
@@ -637,10 +640,10 @@ public class GLDrawableHelper {
}
}
- private final void init(final GLEventListener l, final GLAutoDrawable drawable, final boolean sendReshape, final boolean setViewport) {
+ private final void init(final GLEventListener l, final GLAutoDrawable drawable, final boolean sendReshape) {
l.init(drawable);
if(sendReshape) {
- reshape(l, drawable, 0, 0, drawable.getSurfaceWidth(), drawable.getSurfaceHeight(), setViewport, false /* checkInit */);
+ l.reshape(drawable, 0, 0, drawable.getSurfaceWidth(), drawable.getSurfaceHeight());
}
}
@@ -649,6 +652,7 @@ public class GLDrawableHelper {
* @param sendReshape set to true if the subsequent display call won't reshape, otherwise false to avoid double reshape.
**/
public final void init(final GLAutoDrawable drawable, final boolean sendReshape) {
+ setViewportAndClear(drawable, 0, 0, drawable.getSurfaceWidth(), drawable.getSurfaceHeight());
synchronized(listenersLock) {
final ArrayList<GLEventListener> _listeners = listeners;
final int listenerCount = _listeners.size();
@@ -660,11 +664,8 @@ public class GLDrawableHelper {
// This may happen not just for initial setup, but for ctx recreation due to resource change (drawable/window),
// hence it must be called unconditional, always.
listenersToBeInit.remove(listener); // remove if exist, avoiding dbl init
- init( listener, drawable, sendReshape, 0==i /* setViewport */);
+ init(listener, drawable, sendReshape);
}
- } else {
- // Expose same GL initialization if not using any GLEventListener
- drawable.getGL().glViewport(0, 0, drawable.getSurfaceWidth(), drawable.getSurfaceHeight());
}
}
}
@@ -686,7 +687,7 @@ public class GLDrawableHelper {
// GLEventListener may need to be init,
// in case this one is added after the realization of the GLAutoDrawable
if( listenersToBeInit.remove(listener) ) {
- init( listener, drawable, true /* sendReshape */, listenersToBeInit.size() + 1 == listenerCount /* setViewport if 1st init */ );
+ init( listener, drawable, true /* sendReshape */ );
}
listener.display(drawable);
}
@@ -711,41 +712,43 @@ public class GLDrawableHelper {
// GLEventListener may need to be init,
// in case this one is added after the realization of the GLAutoDrawable
if( listenersToBeInit.remove(listener) ) {
- init( listener, drawable, true /* sendReshape */, listenersToBeInit.size() + 1 == listenerCount /* setViewport if 1st init */ );
+ init( listener, drawable, true /* sendReshape */ );
}
action.run(drawable, listener);
}
}
}
- private final void reshape(final GLEventListener listener, final GLAutoDrawable drawable,
- final int x, final int y, final int width, final int height, final boolean setViewport, final boolean checkInit) {
- if(checkInit) {
- // GLEventListener may need to be init,
- // in case this one is added after the realization of the GLAutoDrawable
- synchronized(listenersLock) {
- if( listenersToBeInit.remove(listener) ) {
- listener.init(drawable);
- }
- }
- }
- if(setViewport) {
- if( GLContext.DEBUG_GL || DEBUG ) {
- final int glerr0 = drawable.getGL().glGetError();
- if( GL.GL_NO_ERROR != glerr0 ) {
- System.err.println("Info: GLDrawableHelper.reshape: pre-exisiting GL error 0x"+Integer.toHexString(glerr0));
- ExceptionUtils.dumpStack(System.err);
- }
- }
- drawable.getGL().glViewport(x, y, width, height);
- }
- listener.reshape(drawable, x, y, width, height);
+ /**
+ * Bug 1206: Security: Clear exposed framebuffer after creation and before visibility
+ * - Clear framebuffer after setting viewport
+ * - Since we only attempt to help against leaking un-initialized framebuffer content
+ * not against user-app faults, we do not clear a 2nd-buffer (double-buffering).
+ */
+ private final void setViewportAndClear(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height) {
+ final GL gl = drawable.getGL();
+ if( DEBUG_SETCLEAR ) {
+ final int glerr0 = gl.glGetError();
+ if( GL.GL_NO_ERROR != glerr0 ) {
+ System.err.println("Info: GLDrawableHelper.reshape: pre-exisiting GL error 0x"+Integer.toHexString(glerr0));
+ ExceptionUtils.dumpStack(System.err);
+ }
+ }
+ gl.glViewport(x, y, width, height);
+ gl.glClear(GL.GL_COLOR_BUFFER_BIT);
}
public final void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height) {
+ setViewportAndClear(drawable, x, y, width, height);
synchronized(listenersLock) {
for (int i=0; i < listeners.size(); i++) {
- reshape(listeners.get(i), drawable, x, y, width, height, 0==i /* setViewport */, true /* checkInit */);
+ final GLEventListener l = listeners.get(i);
+ // GLEventListener may need to be init,
+ // in case this one is added after the realization of the GLAutoDrawable
+ if( listenersToBeInit.remove(l) ) {
+ l.init(drawable);
+ }
+ l.reshape(drawable, x, y, width, height);
}
}
}
@@ -874,9 +877,8 @@ public class GLDrawableHelper {
return false;
}
- GLRunnableTask rTask = null;
+ final GLRunnableTask rTask;
final Object rTaskLock = new Object();
- Throwable throwable = null;
synchronized(rTaskLock) {
boolean deferredHere;
synchronized(glRunnablesLock) {
@@ -910,13 +912,13 @@ public class GLDrawableHelper {
drawable.display();
} else if( wait ) {
try {
- rTaskLock.wait(); // free lock, allow execution of rTask
+ while( rTask.isInQueue() ) {
+ rTaskLock.wait(); // free lock, allow execution of rTask
+ }
} catch (final InterruptedException ie) {
- throwable = ie;
- }
- if(null==throwable) {
- throwable = rTask.getThrowable();
+ throw new InterruptedRuntimeException(ie);
}
+ final Throwable throwable = rTask.getThrowable();
if(null!=throwable) {
throw new RuntimeException(throwable);
}
@@ -941,9 +943,8 @@ public class GLDrawableHelper {
}
final int count = newGLRunnables.size();
- GLRunnableTask rTask = null;
+ final GLRunnableTask rTask;
final Object rTaskLock = new Object();
- Throwable throwable = null;
synchronized(rTaskLock) {
boolean deferredHere;
synchronized(glRunnablesLock) {
@@ -981,13 +982,13 @@ public class GLDrawableHelper {
drawable.display();
} else if( wait ) {
try {
- rTaskLock.wait(); // free lock, allow execution of rTask
+ while( rTask.isInQueue() ) {
+ rTaskLock.wait(); // free lock, allow execution of rTask
+ }
} catch (final InterruptedException ie) {
- throwable = ie;
- }
- if(null==throwable) {
- throwable = rTask.getThrowable();
+ throw new InterruptedRuntimeException(ie);
}
+ final Throwable throwable = rTask.getThrowable();
if(null!=throwable) {
throw new RuntimeException(throwable);
}
@@ -1082,6 +1083,21 @@ public class GLDrawableHelper {
return exclusiveContextThread;
}
+ /**
+ * Runs given {@code runnable} outside of a probable claimed exclusive thread,
+ * i.e. releases the exclusive thread, executes the runnable and reclaims it.
+ * @see #setExclusiveContextThread(Thread, GLContext)
+ * @since 2.3.2
+ */
+ public final void runOutsideOfExclusiveContextThread(final GLContext context, final Runnable runnable) {
+ final Thread t = setExclusiveContextThread(null, context);
+ try {
+ runnable.run();
+ } finally {
+ setExclusiveContextThread(t, context);
+ }
+ }
+
private static final ThreadLocal<WeakReference<Runnable>> perThreadInitAction = new ThreadLocal<WeakReference<Runnable>>();
private static final Runnable getLastInitAction() {
final WeakReference<Runnable> lastInitActionWR = perThreadInitAction.get();
diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java b/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java
index 849a08623..98a0a0948 100644
--- a/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java
@@ -67,14 +67,6 @@ public abstract class GLDrawableImpl implements GLDrawable {
this.requestedCapabilities = requestedCapabilities;
}
- /**
- * Returns the DynamicLookupHelper
- * @throws GLException if no DynamicLookupHelper is installed
- */
- public final GLDynamicLookupHelper getGLDynamicLookupHelper() throws GLException {
- return getFactoryImpl().getGLDynamicLookupHelper( getGLProfile().getImplName() );
- }
-
public final GLDrawableFactoryImpl getFactoryImpl() {
return (GLDrawableFactoryImpl) getFactory();
}
diff --git a/src/jogl/classes/jogamp/opengl/GLDynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/GLDynamicLibraryBundleInfo.java
index 39de3200d..7c75b0615 100644
--- a/src/jogl/classes/jogamp/opengl/GLDynamicLibraryBundleInfo.java
+++ b/src/jogl/classes/jogamp/opengl/GLDynamicLibraryBundleInfo.java
@@ -59,6 +59,16 @@ public abstract class GLDynamicLibraryBundleInfo implements DynamicLibraryBundle
public boolean shallLookupGlobal() { return false; }
@Override
+ public final boolean searchToolLibInSystemPath() {
+ return true;
+ }
+
+ @Override
+ public final boolean searchToolLibSystemPathFirst() {
+ return true;
+ }
+
+ @Override
public final RunnableExecutor getLibLoaderExecutor() {
return DynamicLibraryBundle.getDefaultRunnableExecutor();
}
diff --git a/src/jogl/classes/jogamp/opengl/GLRunnableTask.java b/src/jogl/classes/jogamp/opengl/GLRunnableTask.java
index 1a6024bfa..cfe3df95d 100644
--- a/src/jogl/classes/jogamp/opengl/GLRunnableTask.java
+++ b/src/jogl/classes/jogamp/opengl/GLRunnableTask.java
@@ -29,6 +29,7 @@
package jogamp.opengl;
import com.jogamp.opengl.GLRunnable;
+import com.jogamp.common.ExceptionUtils;
import com.jogamp.opengl.GLAutoDrawable;
/**
@@ -61,7 +62,7 @@ public class GLRunnableTask implements GLRunnable {
} catch (final Throwable t) {
runnableException = t;
if(catchExceptions) {
- runnableException.printStackTrace();
+ ExceptionUtils.dumpThrowable("", runnableException);
} else {
throw new RuntimeException(runnableException);
}
@@ -75,7 +76,7 @@ public class GLRunnableTask implements GLRunnable {
} catch (final Throwable t) {
runnableException = t;
if(catchExceptions) {
- runnableException.printStackTrace();
+ ExceptionUtils.dumpThrowable("", runnableException);
} else {
throw new RuntimeException(runnableException);
}
diff --git a/src/jogl/classes/jogamp/opengl/GLWorkerThread.java b/src/jogl/classes/jogamp/opengl/GLWorkerThread.java
index c03cdea02..3d0adfc9c 100644
--- a/src/jogl/classes/jogamp/opengl/GLWorkerThread.java
+++ b/src/jogl/classes/jogamp/opengl/GLWorkerThread.java
@@ -43,6 +43,9 @@ import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
+import com.jogamp.common.ExceptionUtils;
+import com.jogamp.common.util.InterruptSource;
+import com.jogamp.common.util.InterruptedRuntimeException;
import com.jogamp.opengl.GLContext;
/** Singleton thread upon which all OpenGL work is performed by
@@ -78,15 +81,18 @@ public class GLWorkerThread {
synchronized (GLWorkerThread.class) {
if (!started) {
lock = new Object();
- thread = new Thread(new WorkerRunnable(),
- "JOGL-GLWorkerThread-");
+ final WorkerRunnable worker = new WorkerRunnable();
+ thread = new InterruptSource.Thread(null, worker, "JOGL-GLWorkerThread-");
thread.setDaemon(true);
started = true;
synchronized (lock) {
thread.start();
try {
- lock.wait();
+ while(!worker.isRunning) {
+ lock.wait();
+ }
} catch (final InterruptedException e) {
+ throw new InterruptedRuntimeException(e);
}
}
@@ -119,7 +125,7 @@ public class GLWorkerThread {
// less cooperatively
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
- Runtime.getRuntime().addShutdownHook(new Thread() {
+ Runtime.getRuntime().addShutdownHook(new InterruptSource.Thread() {
public void run() {
Object lockTemp = lock;
if (lockTemp == null) {
@@ -177,7 +183,9 @@ public class GLWorkerThread {
work = runnable;
lockTemp.notifyAll();
- lockTemp.wait();
+ while( null != work ) {
+ lockTemp.wait();
+ }
if (exception != null) {
final Throwable localException = exception;
exception = null;
@@ -222,10 +230,13 @@ public class GLWorkerThread {
protected static String getThreadName() { return Thread.currentThread().getName(); }
static class WorkerRunnable implements Runnable {
+ volatile boolean isRunning = false;
+
@Override
public void run() {
// Notify starting thread that we're ready
synchronized (lock) {
+ isRunning = true;
lock.notifyAll();
}
@@ -238,6 +249,7 @@ public class GLWorkerThread {
// Avoid race conditions with wanting to release contexts on this thread
lock.wait(1000);
} catch (final InterruptedException e) {
+ throw new InterruptedRuntimeException(e);
}
if (GLContext.getCurrent() != null) {
@@ -269,8 +281,7 @@ public class GLWorkerThread {
final Runnable curAsync = queue.remove(0);
curAsync.run();
} catch (final Throwable t) {
- System.err.println(getThreadName()+": Exception occurred on JOGL OpenGL worker thread:");
- t.printStackTrace();
+ ExceptionUtils.dumpThrowable("suppressed", t); // Noncancelable
}
}
@@ -285,6 +296,7 @@ public class GLWorkerThread {
}
}
}
+ isRunning = false;
}
}
}
diff --git a/src/jogl/classes/jogamp/opengl/GLXExtensions.java b/src/jogl/classes/jogamp/opengl/GLXExtensions.java
index 9325c6f68..db4757e4d 100644
--- a/src/jogl/classes/jogamp/opengl/GLXExtensions.java
+++ b/src/jogl/classes/jogamp/opengl/GLXExtensions.java
@@ -34,4 +34,10 @@ 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";
+
+ public static final String GLX_EXT_swap_control = "GLX_EXT_swap_control";
+ public static final String GLX_EXT_swap_control_tear = "GLX_EXT_swap_control_tear";
+
+ public static final String WGL_EXT_swap_control = "WGL_EXT_swap_control";
+ public static final String WGL_EXT_swap_control_tear = "WGL_EXT_swap_control_tear";
}
diff --git a/src/jogl/classes/jogamp/opengl/SharedResourceRunner.java b/src/jogl/classes/jogamp/opengl/SharedResourceRunner.java
index 9b9093a87..0f6c1f875 100644
--- a/src/jogl/classes/jogamp/opengl/SharedResourceRunner.java
+++ b/src/jogl/classes/jogamp/opengl/SharedResourceRunner.java
@@ -28,14 +28,19 @@
package jogamp.opengl;
import java.util.Collection;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.Map;
import com.jogamp.nativewindow.AbstractGraphicsDevice;
import com.jogamp.nativewindow.AbstractGraphicsScreen;
import com.jogamp.opengl.GLProfile;
import com.jogamp.common.ExceptionUtils;
+import com.jogamp.common.util.InterruptSource;
+import com.jogamp.common.util.InterruptedRuntimeException;
+import com.jogamp.common.util.SourcedInterruptedException;
import com.jogamp.opengl.GLRendererQuirks;
public class SharedResourceRunner implements Runnable {
@@ -81,6 +86,29 @@ public class SharedResourceRunner implements Runnable {
/** Called within synchronized block. */
Collection<Resource> mapValues();
}
+ public static abstract class AImplementation implements Implementation {
+ private final HashMap<String /* uniqueId */, SharedResourceRunner.Resource> sharedMap = new HashMap<String, SharedResourceRunner.Resource>();
+ /** Called within synchronized block. Use w/ care! */
+ public Map<String /* uniqueId */, SharedResourceRunner.Resource> getSharedMap() {
+ return sharedMap;
+ }
+ @Override
+ public final void clear() {
+ sharedMap.clear();
+ }
+ @Override
+ public final SharedResourceRunner.Resource mapPut(final AbstractGraphicsDevice device, final SharedResourceRunner.Resource resource) {
+ return sharedMap.put(device.getUniqueID(), resource);
+ }
+ @Override
+ public final SharedResourceRunner.Resource mapGet(final AbstractGraphicsDevice device) {
+ return sharedMap.get(device.getUniqueID());
+ }
+ @Override
+ public final Collection<SharedResourceRunner.Resource> mapValues() {
+ return sharedMap.values();
+ }
+ }
final HashSet<String> devicesTried = new HashSet<String>();
final Implementation impl;
@@ -93,13 +121,13 @@ public class SharedResourceRunner implements Runnable {
AbstractGraphicsDevice releaseDevice;
private boolean getDeviceTried(final AbstractGraphicsDevice device) { // synchronized call
- return devicesTried.contains(device.getConnection());
+ return devicesTried.contains(device.getUniqueID());
}
private void addDeviceTried(final AbstractGraphicsDevice device) { // synchronized call
- devicesTried.add(device.getConnection());
+ devicesTried.add(device.getUniqueID());
}
private void removeDeviceTried(final AbstractGraphicsDevice device) { // synchronized call
- devicesTried.remove(device.getConnection());
+ devicesTried.remove(device.getUniqueID());
}
public SharedResourceRunner(final Implementation impl) {
@@ -141,13 +169,18 @@ public class SharedResourceRunner implements Runnable {
System.err.println("SharedResourceRunner.start() - start new Thread - "+getThreadName());
}
resetState();
- thread = new Thread(this, getThreadName()+"-SharedResourceRunner");
+ thread = new InterruptSource.Thread(null, this, getThreadName()+"-SharedResourceRunner");
thread.setDaemon(true); // Allow JVM to exit, even if this one is running
thread.start();
- while (!running) {
- try {
+ try {
+ while (!running) {
this.wait();
- } catch (final InterruptedException ex) { }
+ }
+ } catch (final InterruptedException ex) {
+ // Cleanup
+ shouldRelease = true;
+ this.notifyAll();
+ throw new InterruptedRuntimeException(ex);
}
}
}
@@ -163,11 +196,12 @@ public class SharedResourceRunner implements Runnable {
synchronized (this) {
shouldRelease = true;
this.notifyAll();
-
- while (running) {
- try {
+ try {
+ while (running) {
this.wait();
- } catch (final InterruptedException ex) { }
+ }
+ } catch (final InterruptedException ex) {
+ throw new InterruptedRuntimeException(ex);
}
}
}
@@ -188,7 +222,11 @@ public class SharedResourceRunner implements Runnable {
ExceptionUtils.dumpStack(System.err);
}
if ( impl.isDeviceSupported(device) ) {
- doAndWait(device, null);
+ try {
+ doAndWait(device, null);
+ } catch (final InterruptedException ex) {
+ throw new InterruptedRuntimeException(ex);
+ }
sr = impl.mapGet(device);
}
if (DEBUG) {
@@ -211,7 +249,11 @@ public class SharedResourceRunner implements Runnable {
if (DEBUG) {
System.err.println("SharedResourceRunner.releaseShared() " + device + ": trying - "+getThreadName());
}
- doAndWait(null, device);
+ try {
+ doAndWait(null, device);
+ } catch (final InterruptedException ex) {
+ throw new InterruptedRuntimeException(ex);
+ }
if (DEBUG) {
System.err.println("SharedResourceRunner.releaseShared() " + device + ": done - "+getThreadName());
}
@@ -221,7 +263,7 @@ public class SharedResourceRunner implements Runnable {
return sr;
}
- private final void doAndWait(final AbstractGraphicsDevice initDevice, final AbstractGraphicsDevice releaseDevice) {
+ private final void doAndWait(final AbstractGraphicsDevice initDevice, final AbstractGraphicsDevice releaseDevice) throws InterruptedException {
synchronized (this) {
// wait until thread becomes ready to init new device,
// pass the device and release the sync
@@ -229,26 +271,41 @@ public class SharedResourceRunner implements Runnable {
if (DEBUG) {
System.err.println("SharedResourceRunner.doAndWait() START init: " + initDevice + ", release: "+releaseDevice+" - "+threadName);
}
- while (!ready && running) {
- try {
+ try {
+ while (!ready && running) {
this.wait();
- } catch (final InterruptedException ex) { }
- }
- if (DEBUG) {
- System.err.println("SharedResourceRunner.doAndWait() set command: " + initDevice + ", release: "+releaseDevice+" - "+threadName);
- }
- this.initDevice = initDevice;
- this.releaseDevice = releaseDevice;
- this.notifyAll();
+ }
+ if (DEBUG) {
+ System.err.println("SharedResourceRunner.doAndWait() set command: " + initDevice + ", release: "+releaseDevice+" - "+threadName);
+ }
+ this.initDevice = initDevice;
+ this.releaseDevice = releaseDevice;
+ this.notifyAll();
- // wait until thread has init/released the device
- while ( running && ( !ready || null != this.initDevice || null != this.releaseDevice ) ) {
- try {
+ // wait until thread has init/released the device
+ while ( running && ( !ready || null != this.initDevice || null != this.releaseDevice ) ) {
this.wait();
- } catch (final InterruptedException ex) { }
+ }
+ } catch (final InterruptedException ex) {
+ final InterruptedException ex2 = SourcedInterruptedException.wrap(ex);
+ if (DEBUG) {
+ System.err.println("SharedResourceRunner.doAndWait() INTERRUPT init: " + initDevice + ", release: "+releaseDevice+" - "+threadName);
+ ExceptionUtils.dumpThrowable("", ex2);
+ }
+ // Cleanup initDevice due to exception!
+ final AbstractGraphicsDevice _initDevice = this.initDevice;
+ if( null != _initDevice ) {
+ if (DEBUG) {
+ System.err.println("SharedResourceRunner.doAndWait() Cleanup init: " + _initDevice + " -> release: "+this.releaseDevice+" - "+threadName);
+ }
+ this.releaseDevice = _initDevice;
+ this.initDevice = null;
+ this.notifyAll();
+ }
+ throw ex2;
}
if (DEBUG) {
- System.err.println("SharedResourceRunner.initializeAndWait END init: " + initDevice + ", release: "+releaseDevice+" - "+threadName);
+ System.err.println("SharedResourceRunner.doAndWait() END init: " + initDevice + ", release: "+releaseDevice+" - "+threadName);
}
}
// done
@@ -267,19 +324,18 @@ public class SharedResourceRunner implements Runnable {
while (!shouldRelease) {
try {
- // wait for stop or init
+ // wait until call-thread issues stop or init/released a device
ready = true;
if (DEBUG) {
System.err.println("SharedResourceRunner.run(): READY - " + threadName);
}
notifyAll();
- this.wait();
+ while ( !shouldRelease && null == initDevice && null == releaseDevice ) {
+ this.wait();
+ }
} catch (final InterruptedException ex) {
shouldRelease = true;
- if(DEBUG) {
- System.err.println("SharedResourceRunner.run(): INTERRUPTED - "+threadName);
- ex.printStackTrace();
- }
+ ExceptionUtils.dumpThrowable("handled", SourcedInterruptedException.wrap(ex)); // cancelable
}
ready = false;
@@ -296,7 +352,7 @@ public class SharedResourceRunner implements Runnable {
try {
sr = impl.createSharedResource(initDevice);
} catch (final Exception e) {
- e.printStackTrace();
+ ExceptionUtils.dumpThrowable("handled", e);
}
if (null != sr) {
impl.mapPut(initDevice, sr);
@@ -310,9 +366,10 @@ public class SharedResourceRunner implements Runnable {
if (null != sr) {
try {
impl.releaseSharedResource(sr);
- impl.mapPut(releaseDevice, null);
} catch (final Exception e) {
- e.printStackTrace();
+ ExceptionUtils.dumpThrowable("handled", e);
+ } finally {
+ impl.mapPut(releaseDevice, null);
}
}
}
@@ -345,8 +402,7 @@ public class SharedResourceRunner implements Runnable {
try {
impl.releaseSharedResource(iter.next());
} catch (final Throwable t) {
- System.err.println("Caught exception on thread "+getThreadName());
- t.printStackTrace();
+ ExceptionUtils.dumpThrowable("", t);
}
}
impl.clear();
diff --git a/src/jogl/classes/jogamp/opengl/android/av/AndroidGLMediaPlayerAPI14.java b/src/jogl/classes/jogamp/opengl/android/av/AndroidGLMediaPlayerAPI14.java
index da81922a4..09d2dfda0 100644
--- a/src/jogl/classes/jogamp/opengl/android/av/AndroidGLMediaPlayerAPI14.java
+++ b/src/jogl/classes/jogamp/opengl/android/av/AndroidGLMediaPlayerAPI14.java
@@ -33,7 +33,6 @@ import java.util.List;
import com.jogamp.opengl.GL;
import com.jogamp.opengl.GLES2;
import com.jogamp.opengl.GLException;
-
import com.jogamp.common.os.AndroidVersion;
import com.jogamp.common.os.Platform;
import com.jogamp.opengl.util.TimeFrameI;
@@ -364,7 +363,7 @@ public class AndroidGLMediaPlayerAPI14 extends GLMediaPlayerImpl {
}
@Override
- protected final int getNextTextureImpl(final GL gl, final TextureFrame nextFrame) {
+ protected final int getNextTextureImpl(final GL gl, final TextureFrame nextFrame) throws InterruptedException {
int pts = TimeFrameI.INVALID_PTS;
if(null != mp || null != cam) {
final SurfaceTextureFrame sTexFrame = null != nextFrame ? (SurfaceTextureFrame) nextFrame : singleSTexFrame;
@@ -398,12 +397,8 @@ public class AndroidGLMediaPlayerAPI14 extends GLMediaPlayerImpl {
boolean update = updateSurface;
if( !update ) {
synchronized(updateSurfaceLock) {
- if(!updateSurface) { // volatile OK.
- try {
- updateSurfaceLock.wait();
- } catch (final InterruptedException e) {
- e.printStackTrace();
- }
+ while(!updateSurface) { // volatile OK.
+ updateSurfaceLock.wait(); // propagates InterruptedException
}
update = updateSurface;
updateSurface = false;
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
index b6a05aeeb..28448d537 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
@@ -49,9 +49,9 @@ import com.jogamp.opengl.GLProfile;
import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLDrawableImpl;
+import jogamp.opengl.GLDynamicLookupHelper;
import jogamp.opengl.egl.EGLExtImpl;
import jogamp.opengl.egl.EGLExtProcAddressTable;
-import jogamp.opengl.windows.wgl.WindowsWGLContext;
import com.jogamp.common.ExceptionUtils;
import com.jogamp.common.nio.Buffers;
@@ -168,19 +168,17 @@ public class EGLContext extends GLContextImpl {
final long eglConfig = config.getNativeConfig();
final EGLDrawableFactory factory = (EGLDrawableFactory) drawable.getFactoryImpl();
- final boolean hasOpenGLAPISupport = factory.hasOpenGLAPISupport();
+ final boolean hasFullOpenGLAPISupport = factory.hasOpenGLDesktopSupport();
final boolean useKHRCreateContext = factory.hasDefaultDeviceKHRCreateContext();
- final boolean allowOpenGLAPI = hasOpenGLAPISupport && useKHRCreateContext;
- final boolean ctDesktopGL = 0 == ( GLContext.CTX_PROFILE_ES & ctp );
+ final boolean ctDesktopGL = 0 == ( CTX_PROFILE_ES & ctp );
final boolean ctBwdCompat = 0 != ( CTX_PROFILE_COMPAT & ctp ) ;
final boolean ctFwdCompat = 0 != ( CTX_OPTION_FORWARD & ctp ) ;
final boolean ctDebug = 0 != ( CTX_OPTION_DEBUG & ctp ) ;
if(DEBUG) {
System.err.println(getThreadName() + ": EGLContext.createContextARBImpl: Start "+getGLVersion(reqMajor, reqMinor, ctp, "@creation")
- + ", hasOpenGLAPISupport "+hasOpenGLAPISupport
+ ", useKHRCreateContext "+useKHRCreateContext
- + ", allowOpenGLAPI "+allowOpenGLAPI
+ + ", OpenGL API Support "+hasFullOpenGLAPISupport
+ ", device "+device);
}
if ( 0 == eglDisplay ) {
@@ -203,8 +201,7 @@ public class EGLContext extends GLContextImpl {
* hence it must be switched before makeCurrent w/ different APIs, see:
* eglWaitClient();
*/
- if( ctDesktopGL && !allowOpenGLAPI ) {
- // if( ctDesktopGL && !hasOpenGLAPISupport ) {
+ if( ctDesktopGL && !hasFullOpenGLAPISupport ) {
if(DEBUG) {
System.err.println(getThreadName() + ": EGLContext.createContextARBImpl: DesktopGL not avail "+getGLVersion(reqMajor, reqMinor, ctp, "@creation"));
}
@@ -212,7 +209,7 @@ public class EGLContext extends GLContextImpl {
}
try {
- if( allowOpenGLAPI && device.getEGLVersion().compareTo(Version1_2) >= 0 ) {
+ if( hasFullOpenGLAPISupport && device.getEGLVersion().compareTo(Version1_2) >= 0 ) {
EGL.eglWaitClient(); // EGL >= 1.2
}
if( !EGL.eglBindAPI( ctDesktopGL ? EGL.EGL_OPENGL_API : EGL.EGL_OPENGL_ES_API) ) {
@@ -238,11 +235,11 @@ public class EGLContext extends GLContextImpl {
int index = ctx_attribs_idx_major + 2;
- /** if( ctDesktopGL && reqMinor >= 0 ) { // FIXME: No minor version probing for ES currently!
+ if( reqMinor >= 0 ) {
attribs.put(index + 0, EGLExt.EGL_CONTEXT_MINOR_VERSION_KHR);
attribs.put(index + 1, reqMinor);
index += 2;
- } */
+ }
if( ctDesktopGL && ( useMajor > 3 || useMajor == 3 && reqMinor >= 2 ) ) {
attribs.put(index + 0, EGLExt.EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR);
@@ -364,14 +361,17 @@ public class EGLContext extends GLContextImpl {
}
@Override
- protected final void updateGLXProcAddressTable() {
+ protected final void updateGLXProcAddressTable(final String contextFQN, final GLDynamicLookupHelper dlh) {
+ if( null == dlh ) {
+ throw new GLException("No GLDynamicLookupHelper for "+this);
+ }
final AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration();
final AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice();
final String key = "EGL-"+adevice.getUniqueID();
+ // final String key = contextFQN;
if (DEBUG) {
System.err.println(getThreadName() + ": Initializing EGLextension address table: "+key);
}
-
ProcAddressTable table = null;
synchronized(mappedContextTypeObjectLock) {
table = mappedGLXProcAddress.get( key );
@@ -386,7 +386,7 @@ public class EGLContext extends GLContextImpl {
}
} else {
eglExtProcAddressTable = new EGLExtProcAddressTable(new GLProcAddressResolver());
- resetProcAddressTable(eglExtProcAddressTable);
+ resetProcAddressTable(eglExtProcAddressTable, dlh);
synchronized(mappedContextTypeObjectLock) {
mappedGLXProcAddress.put(key, eglExtProcAddressTable);
if(DEBUG) {
@@ -432,11 +432,21 @@ public class EGLContext extends GLContextImpl {
}
@Override
- protected boolean setSwapIntervalImpl(final int interval) {
- if( hasRendererQuirk(GLRendererQuirks.NoSetSwapInterval) ) {
- return false;
+ protected final Integer setSwapIntervalImpl2(final int interval) {
+ if( !drawable.getChosenGLCapabilities().isOnscreen() ||
+ hasRendererQuirk(GLRendererQuirks.NoSetSwapInterval) ) {
+ return null;
+ }
+ final int useInterval;
+ if( 0 > interval ) {
+ useInterval = Math.abs(interval);
+ } else {
+ useInterval = interval;
}
- return EGL.eglSwapInterval(drawable.getNativeSurface().getDisplayHandle(), interval);
+ if( EGL.eglSwapInterval(drawable.getNativeSurface().getDisplayHandle(), useInterval) ) {
+ return Integer.valueOf(useInterval);
+ }
+ return null;
}
static long eglGetProcAddress(final long eglGetProcAddressHandle, final String procname)
@@ -453,52 +463,32 @@ public class EGLContext extends GLContextImpl {
// Accessible ..
//
- /* pp */ void mapCurrentAvailableGLESVersion(final AbstractGraphicsDevice device) {
- mapStaticGLESVersion(device, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions);
+ /* pp */ static final boolean isGLES1(final int majorVersion, final int ctxOptions) {
+ return 0 != ( ctxOptions & GLContext.CTX_PROFILE_ES ) && majorVersion == 1 ;
}
- /* pp */ int getContextOptions() { return ctxOptions; }
- /* pp */ static void mapStaticGLESVersion(final AbstractGraphicsDevice device, final GLCapabilitiesImmutable caps) {
- final GLProfile glp = caps.getGLProfile();
- final int[] reqMajorCTP = new int[2];
- GLContext.getRequestMajorAndCompat(glp, reqMajorCTP);
- if( glp.isGLES() ) {
- if( reqMajorCTP[0] >= 3 ) {
- reqMajorCTP[1] |= GLContext.CTX_IMPL_ES3_COMPAT | GLContext.CTX_IMPL_ES2_COMPAT | GLContext.CTX_IMPL_FBO ;
- } else if( reqMajorCTP[0] >= 2 ) {
- reqMajorCTP[1] |= GLContext.CTX_IMPL_ES2_COMPAT | GLContext.CTX_IMPL_FBO ;
- }
- }
- if( !caps.getHardwareAccelerated() ) {
- reqMajorCTP[1] |= GLContext.CTX_IMPL_ACCEL_SOFT;
+ /* pp */ static final boolean isGLES2ES3(final int majorVersion, final int ctxOptions) {
+ if( 0 != ( ctxOptions & CTX_PROFILE_ES ) ) {
+ return 2 == majorVersion || 3 == majorVersion;
+ } else {
+ return false;
}
- mapStaticGLESVersion(device, reqMajorCTP[0], 0, reqMajorCTP[1]);
}
- /* pp */ static void mapStaticGLESVersion(final AbstractGraphicsDevice device, final int major, final int minor, final int ctp) {
- if( 0 != ( ctp & GLContext.CTX_PROFILE_ES) ) {
- // ES1, ES2, ES3, ..
- mapStaticGLESVersion(device, major /* reqMajor */, major, minor, ctp);
- if( 3 == major ) {
- // map ES2 -> ES3
- mapStaticGLESVersion(device, 2 /* reqMajor */, major, minor, ctp);
- }
- }
+ /* pp */ static final boolean isGLDesktop(final int ctxOptions) {
+ return 0 != (ctxOptions & (CTX_PROFILE_COMPAT|CTX_PROFILE_CORE));
}
- private static void mapStaticGLESVersion(final AbstractGraphicsDevice device, final int reqMajor, final int major, final int minor, final int ctp) {
- GLContext.mapAvailableGLVersion(device, reqMajor, GLContext.CTX_PROFILE_ES, 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, GLContext.CTX_PROFILE_ES, major, minor, ctp);
- }
+ protected static StringBuilder getGLProfile(final StringBuilder sb, final int ctp) {
+ return GLContext.getGLProfile(sb, ctp);
}
- protected static String getGLVersion(final int major, final int minor, final int ctp, final String gl_version) {
- return GLContext.getGLVersion(major, minor, ctp, gl_version);
+ /* pp */ int getContextOptions() { return ctxOptions; }
+ protected static void remapAvailableGLVersions(final AbstractGraphicsDevice fromDevice, final AbstractGraphicsDevice toDevice) {
+ GLContextImpl.remapAvailableGLVersions(fromDevice, toDevice);
}
-
- protected static boolean getAvailableGLVersionsSet(final AbstractGraphicsDevice device) {
- return GLContext.getAvailableGLVersionsSet(device);
+ protected static synchronized void setMappedGLVersionListener(final MappedGLVersionListener mvl) {
+ GLContextImpl.setMappedGLVersionListener(mvl);
}
- protected static void setAvailableGLVersionsSet(final AbstractGraphicsDevice device, final boolean set) {
- GLContext.setAvailableGLVersionsSet(device, set);
+
+ protected static String getGLVersion(final int major, final int minor, final int ctp, final String gl_version) {
+ return GLContext.getGLVersion(major, minor, ctp, gl_version);
}
protected static String toHexString(final int hex) {
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java b/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java
index 3d2d03403..fcd4f54eb 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java
@@ -80,10 +80,17 @@ public class EGLDisplayUtil {
static EGLDisplayRef getOrCreateOpened(final long eglDisplay, final IntBuffer major, final IntBuffer minor) {
final EGLDisplayRef o = (EGLDisplayRef) openEGLDisplays.get(eglDisplay);
if( null == o ) {
- if( EGL.eglInitialize(eglDisplay, major, minor) ) {
+ final boolean ok = EGL.eglInitialize(eglDisplay, major, minor);
+ if( DEBUG ) {
+ System.err.println("EGLDisplayUtil.EGL.eglInitialize 0x"+Long.toHexString(eglDisplay)+" -> "+ok);
+ }
+ if( ok ) {
final EGLDisplayRef n = new EGLDisplayRef(eglDisplay);
openEGLDisplays.put(eglDisplay, n);
n.initRefCount++;
+ if( DEBUG ) {
+ System.err.println("EGLDisplayUtil.EGL.eglInitialize "+n);
+ }
if( null == singletonEGLDisplay ) {
singletonEGLDisplay = n;
}
@@ -113,7 +120,12 @@ public class EGLDisplayUtil {
if( 0 < o.initRefCount ) { // no negative refCount
o.initRefCount--;
if( 0 == o.initRefCount ) {
- res[0] = EGL.eglTerminate(eglDisplay);
+ final boolean ok = EGL.eglTerminate(eglDisplay);
+ if( DEBUG ) {
+ System.err.println("EGLDisplayUtil.EGL.eglTerminate 0x"+Long.toHexString(eglDisplay)+" -> "+ok);
+ System.err.println("EGLDisplayUtil.EGL.eglTerminate "+o);
+ }
+ res[0] = ok;
if( o == singletonEGLDisplay ) {
singletonEGLDisplay = null;
}
@@ -340,6 +352,22 @@ public class EGLDisplayUtil {
* <p>
* Using the default {@link ToolkitLock}, via {@link NativeWindowFactory#getDefaultToolkitLock(String, long)}.
* </p>
+ * @param adevice
+ * @return an uninitialized {@link EGLGraphicsDevice}
+ */
+ public static EGLGraphicsDevice eglCreateEGLGraphicsDevice(final AbstractGraphicsDevice aDevice) {
+ return new EGLGraphicsDevice(aDevice, EGL.EGL_NO_DISPLAY, eglLifecycleCallback);
+ }
+
+ /**
+ * Returns an uninitialized {@link EGLGraphicsDevice}. User needs to issue {@link EGLGraphicsDevice#open()} before usage.
+ * <p>
+ * Using {@link #eglGetDisplayAndInitialize(long[])} for the {@link EGLGraphicsDevice#open()} implementation
+ * and {@link #eglTerminate(long)} for {@link EGLGraphicsDevice#close()}.
+ * </p>
+ * <p>
+ * Using the default {@link ToolkitLock}, via {@link NativeWindowFactory#getDefaultToolkitLock(String, long)}.
+ * </p>
* @param surface
* @return an uninitialized EGLGraphicsDevice
*/
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java
index e63a63634..ef3c96aeb 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java
@@ -36,6 +36,7 @@
package jogamp.opengl.egl;
+import com.jogamp.common.ExceptionUtils;
import com.jogamp.nativewindow.ProxySurface;
import com.jogamp.opengl.GLContext;
import com.jogamp.opengl.GLException;
@@ -82,7 +83,10 @@ public class EGLDrawable extends GLDrawableImpl {
final EGLSurface eglSurf = (EGLSurface) surface;
final long eglSurfHandle = eglSurf.getSurfaceHandle();
if(DEBUG) {
- System.err.println(getThreadName() + ": destroyHandle of "+eglSurf);
+ System.err.println(getThreadName() + ": EGLDrawable: destroyHandle of "+toHexString(eglSurfHandle));
+ ProxySurfaceImpl.dumpHierarchy(System.err, eglSurf);
+ System.err.println(getThreadName() + ": EGLSurface : "+eglSurf);
+ ExceptionUtils.dumpStack(System.err);
}
if( !eglSurf.containsUpstreamOptionBits( ProxySurface.OPT_UPSTREAM_SURFACELESS ) &&
EGL.EGL_NO_SURFACE == eglSurfHandle ) {
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
index 4fecafdfc..fed02f34e 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
@@ -38,10 +38,9 @@ package jogamp.opengl.egl;
import java.nio.IntBuffer;
import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import com.jogamp.nativewindow.AbstractGraphicsConfiguration;
@@ -67,6 +66,7 @@ import com.jogamp.opengl.GLProfile;
import jogamp.common.os.PlatformPropsImpl;
import jogamp.opengl.Debug;
import jogamp.opengl.GLContextImpl;
+import jogamp.opengl.GLContextImpl.MappedGLVersion;
import jogamp.opengl.GLDrawableFactoryImpl;
import jogamp.opengl.GLDrawableImpl;
import jogamp.opengl.GLDynamicLookupHelper;
@@ -78,7 +78,6 @@ import com.jogamp.common.nio.Buffers;
import com.jogamp.common.nio.PointerBuffer;
import com.jogamp.common.os.DynamicLookupHelper;
import com.jogamp.common.os.Platform;
-import com.jogamp.common.util.PropertyAccess;
import com.jogamp.common.util.ReflectionUtil;
import com.jogamp.common.util.VersionNumber;
import com.jogamp.nativewindow.GenericUpstreamSurfacelessHook;
@@ -90,17 +89,20 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
protected static final boolean DEBUG = GLDrawableFactoryImpl.DEBUG; // allow package access
private static final boolean DEBUG_SHAREDCTX = DEBUG || GLContext.DEBUG;
- /* package */ static final boolean QUERY_EGL_ES_NATIVE_TK;
-
static {
Debug.initSingleton();
- QUERY_EGL_ES_NATIVE_TK = PropertyAccess.isPropertyDefined("jogl.debug.EGLDrawableFactory.QueryNativeTK", true);
}
private static boolean eglDynamicLookupHelperInit = false;
private static GLDynamicLookupHelper eglES1DynamicLookupHelper = null;
private static GLDynamicLookupHelper eglES2DynamicLookupHelper = null;
private static GLDynamicLookupHelper eglGLnDynamicLookupHelper = null;
+ private static boolean isANGLE = false;
+ private static boolean hasX11 = false;
+ private static String defaultConnection = null;
+ private static EGLGraphicsDevice defaultDevice = null;
+ private static EGLFeatures defaultDeviceEGLFeatures = null;
+ private static SharedResource defaultSharedResource = null;
private static final boolean isANGLE(final GLDynamicLookupHelper dl) {
if(Platform.OSType.WINDOWS == PlatformPropsImpl.OS_TYPE) {
@@ -128,7 +130,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
public EGLFeatures(final EGLGraphicsDevice device) {
final long eglDisplay = device.getHandle();
vendor = EGL.eglQueryString(eglDisplay, EGL.EGL_VENDOR);
- if(DEBUG) {
+ if(DEBUG_SHAREDCTX) {
System.err.println("EGLFeatures on device "+device+", vendor "+vendor);
}
version = device.getEGLVersion();
@@ -139,13 +141,13 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
final String eglClientAPIStr = EGL.eglQueryString(eglDisplay, EGL.EGL_CLIENT_APIS);
if( hasEGL_1_4 ) {
final String[] eglClientAPIs = eglClientAPIStr.split("\\s");
- for(int i=eglClientAPIs.length-1; i>=0; i--) {
+ for(int i=eglClientAPIs.length-1; !_hasGLAPI && i>=0; i--) {
_hasGLAPI = eglClientAPIs[i].equals("OpenGL");
}
}
hasGLAPI = _hasGLAPI;
- if(DEBUG) {
- System.err.println(" Client APIs: "+eglClientAPIStr+"; has EGL 1.4 "+hasEGL_1_4+" -> has OpenGL "+hasGLAPI);
+ if(DEBUG_SHAREDCTX) {
+ System.err.println(" Client APIs: '"+eglClientAPIStr+"'; has EGL 1.4 "+hasEGL_1_4+" -> has OpenGL "+hasGLAPI);
}
}
{
@@ -163,7 +165,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
}
hasKHRSurfaceless = extensions.contains("EGL_KHR_surfaceless_context");
}
- if(DEBUG) {
+ if(DEBUG_SHAREDCTX) {
System.err.println(" Extensions: "+extensions);
System.err.println(" KHR_create_context: "+hasKHRCreateContext);
System.err.println(" KHR_surfaceless_context: "+hasKHRSurfaceless);
@@ -193,12 +195,16 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
eglDynamicLookupHelperInit = true;
// Check for other underlying stuff ..
- if(NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(true)) {
+ final String nwt = NativeWindowFactory.getNativeWindowType(true);
+ if(NativeWindowFactory.TYPE_X11 == nwt) {
hasX11 = true;
try {
ReflectionUtil.createInstance("jogamp.opengl.x11.glx.X11GLXGraphicsConfigurationFactory", EGLDrawableFactory.class.getClassLoader());
} catch (final Exception jre) { /* n/a .. */ }
+ } else {
+ hasX11 = false;
}
+ defaultConnection = NativeWindowFactory.getDefaultDisplayConnection(nwt);
/**
* FIXME: Probably need to move EGL from a static model
@@ -337,14 +343,14 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
// The act of constructing them causes them to be registered
EGLGraphicsConfigurationFactory.registerFactory();
- sharedMap = new HashMap<String, SharedResourceRunner.Resource>();
-
- // FIXME: defaultDevice.open() triggers eglInitialize(..) which crashed on Windows w/ Chrome/ANGLE, FF/ANGLE!
- defaultDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(EGL.EGL_DEFAULT_DISPLAY, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
+ // Note: defaultDevice.open() triggers eglInitialize(..) which crashed on Windows w/ Chrome/ANGLE, FF/ANGLE!
+ // Hence opening will happen later, eventually
+ defaultDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(EGL.EGL_DEFAULT_DISPLAY, defaultConnection, AbstractGraphicsDevice.DEFAULT_UNIT);
// Init shared resources off thread
// Will be released via ShutdownHook
- sharedResourceRunner = new SharedResourceRunner(new SharedResourceImplementation());
+ sharedResourceImplementation = new SharedResourceImplementation();
+ sharedResourceRunner = new SharedResourceRunner(sharedResourceImplementation);
sharedResourceRunner.start();
}
}
@@ -353,7 +359,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
@Override
protected final boolean isComplete() {
- return null != sharedMap; // null != eglES2DynamicLookupHelper || null != eglES1DynamicLookupHelper;
+ return null != sharedResourceImplementation; // null != eglES2DynamicLookupHelper || null != eglES1DynamicLookupHelper || ..;
}
@@ -366,9 +372,9 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
sharedResourceRunner.stop();
sharedResourceRunner = null;
}
- if(null != sharedMap) {
- sharedMap.clear();
- sharedMap = null;
+ if(null != sharedResourceImplementation) {
+ sharedResourceImplementation.clear();
+ sharedResourceImplementation = null;
}
if(null != defaultDevice) {
@@ -395,57 +401,63 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
}
private void dumpMap() {
- synchronized(sharedMap) {
- System.err.println("EGLDrawableFactory.map "+sharedMap.size());
+ synchronized(sharedResourceImplementation) {
+ final Map<String /* uniqueId */, SharedResourceRunner.Resource> sharedMap = sharedResourceImplementation.getSharedMap();
+ System.err.println("EGLDrawableFactory.MapGLVersion.map "+sharedMap.size());
int i=0;
final Set<String> keys = sharedMap.keySet();
for(final Iterator<String> keyI = keys.iterator(); keyI.hasNext(); i++) {
final String key = keyI.next();
final SharedResource sr = (SharedResource) sharedMap.get(key);
- System.err.println("EGLDrawableFactory.map["+i+"] "+key+" -> "+sr.getDevice()+", avail "+sr.isAvailable+
- "gln [quirks "+sr.rendererQuirksGLn+", ctp "+EGLContext.getGLVersion(3, 0, sr.ctpGLn, null)+"], "+
- "es1 [quirks "+sr.rendererQuirksES1+", ctp "+EGLContext.getGLVersion(1, 0, sr.ctpES1, null)+"], "+
- "es2/3 [quirks "+sr.rendererQuirksES3ES2+", ctp "+EGLContext.getGLVersion(2, 0, sr.ctpES3ES2, null)+"]");
+ System.err.println("EGLDrawableFactory.MapGLVersion.map["+i+"] "+key+" -> "+sr.getDevice()+", avail "+sr.isAvailable+", "+
+ "es1 [avail "+sr.isAvailableES1+", quirks "+sr.rendererQuirksES1+", ctp "+EGLContext.getGLVersion(1, 0, sr.ctpES1, null)+"], "+
+ "es2 [avail "+sr.isAvailableES2+", quirks "+sr.rendererQuirksES2+", ctp "+EGLContext.getGLVersion(2, 0, sr.ctpES2, null)+"], "+
+ "es3 [avail "+sr.isAvailableES3+", quirks "+sr.rendererQuirksES3+", ctp "+EGLContext.getGLVersion(2, 0, sr.ctpES3, null)+"], "+
+ "gln [avail "+sr.isAvailableGLn+", quirks "+sr.rendererQuirksGLn+", ctp "+EGLContext.getGLVersion(3, 0, sr.ctpGLn, null)+"]");
}
;
}
}
- private boolean isANGLE = false;
- private boolean hasX11 = false;
- private EGLGraphicsDevice defaultDevice = null;
- private EGLFeatures defaultDeviceEGLFeatures;
+ private SharedResourceImplementation sharedResourceImplementation;
private SharedResourceRunner sharedResourceRunner;
- private HashMap<String /* uniqueKey */, SharedResourceRunner.Resource> sharedMap;
static class SharedResource implements SharedResourceRunner.Resource {
private EGLGraphicsDevice device;
- // private final EGLContext contextES1;
- // private final EGLContext contextES2;
- // private final EGLContext contextES3;
final boolean isAvailable;
- final GLRendererQuirks rendererQuirksGLn;
+ final boolean isAvailableES1;
+ final boolean isAvailableES2;
+ final boolean isAvailableES3;
+ final boolean isAvailableGLn;
final GLRendererQuirks rendererQuirksES1;
- final GLRendererQuirks rendererQuirksES3ES2;
- final int ctpGLn;
+ final GLRendererQuirks rendererQuirksES2;
+ final GLRendererQuirks rendererQuirksES3;
+ final GLRendererQuirks rendererQuirksGLn;
final int ctpES1;
- final int ctpES3ES2;
+ final int ctpES2;
+ final int ctpES3;
+ final int ctpGLn;
- SharedResource(final EGLGraphicsDevice dev, final boolean isAvailable,
- final GLRendererQuirks rendererQuirksGLn, final int ctpGLn,
- final GLRendererQuirks rendererQuirksES1, final int ctpES1,
- final GLRendererQuirks rendererQuirksES3ES2, final int ctpES3ES2) {
+ SharedResource(final EGLGraphicsDevice dev,
+ final boolean isAvailableES1, final GLRendererQuirks rendererQuirksES1, final int ctpES1,
+ final boolean isAvailableES2, final GLRendererQuirks rendererQuirksES2, final int ctpES2,
+ final boolean isAvailableES3, final GLRendererQuirks rendererQuirksES3, final int ctpES3,
+ final boolean isAvailableGLn, final GLRendererQuirks rendererQuirksGLn, final int ctpGLn) {
this.device = dev;
- this.isAvailable = isAvailable;
-
- this.rendererQuirksGLn = rendererQuirksGLn;
- this.ctpGLn = ctpGLn;
+ this.isAvailable = isAvailableES1 || isAvailableES2 || isAvailableES3 || isAvailableGLn;
+ this.isAvailableES1 = isAvailableES1;
this.rendererQuirksES1 = rendererQuirksES1;
this.ctpES1 = ctpES1;
-
- this.rendererQuirksES3ES2 = rendererQuirksES3ES2;
- this.ctpES3ES2 = ctpES3ES2;
+ this.isAvailableES2 = isAvailableES2;
+ this.rendererQuirksES2 = rendererQuirksES2;
+ this.ctpES2 = ctpES2;
+ this.isAvailableES3 = isAvailableES3;
+ this.rendererQuirksES3 = rendererQuirksES3;
+ this.ctpES3 = ctpES3;
+ this.isAvailableGLn = isAvailableGLn;
+ this.rendererQuirksGLn = rendererQuirksGLn;
+ this.ctpGLn = ctpGLn;
}
@Override
@@ -470,8 +482,10 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
@Override
public GLRendererQuirks getRendererQuirks(final GLProfile glp) {
if( null == glp ) {
- if( null != rendererQuirksES3ES2 ) {
- return rendererQuirksES3ES2;
+ if( null != rendererQuirksES3 ) {
+ return rendererQuirksES3;
+ } else if( null != rendererQuirksES2 ) {
+ return rendererQuirksES2;
} else if( null != rendererQuirksES1 ) {
return rendererQuirksES1;
} else {
@@ -481,33 +495,18 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
return rendererQuirksGLn;
} else if( glp.isGLES1() ) {
return rendererQuirksES1;
- } else {
- return rendererQuirksES3ES2;
+ } else if( glp.isGLES2() ) {
+ return rendererQuirksES2;
+ } else /* if( glp.isGLES3() ) */ {
+ return rendererQuirksES3;
}
}
}
- class SharedResourceImplementation implements SharedResourceRunner.Implementation {
- @Override
- public void clear() {
- sharedMap.clear();
- }
- @Override
- public SharedResourceRunner.Resource mapPut(final AbstractGraphicsDevice device, final SharedResourceRunner.Resource resource) {
- return sharedMap.put(device.getConnection(), resource);
- }
- @Override
- public SharedResourceRunner.Resource mapGet(final AbstractGraphicsDevice device) {
- return sharedMap.get(device.getConnection());
- }
- @Override
- public Collection<SharedResourceRunner.Resource> mapValues() {
- return sharedMap.values();
- }
-
+ class SharedResourceImplementation extends SharedResourceRunner.AImplementation {
@Override
public boolean isDeviceSupported(final AbstractGraphicsDevice device) {
- return null != sharedMap; // null != eglES2DynamicLookupHelper || null != eglES1DynamicLookupHelper
+ return null != sharedResourceImplementation; // null != eglES2DynamicLookupHelper || null != eglES1DynamicLookupHelper || ..
}
@Override
@@ -523,78 +522,128 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
}
private SharedResource createEGLSharedResourceImpl(final AbstractGraphicsDevice adevice) {
- final GLRendererQuirks[] rendererQuirksES1 = new GLRendererQuirks[] { null };
- final GLRendererQuirks[] rendererQuirksES3ES2 = new GLRendererQuirks[] { null };
- final GLRendererQuirks[] rendererQuirksGLn = new GLRendererQuirks[] { null };
- final int[] ctpES1 = new int[] { EGLContext.CTX_PROFILE_ES };
- final int[] ctpES3ES2 = new int[] { EGLContext.CTX_PROFILE_ES };
- final int[] ctpGLn = new int[] { EGLContext.CTX_PROFILE_CORE };
-
if ( DEBUG_SHAREDCTX ) {
- System.err.println("EGLDrawableFactory.createShared(): device "+adevice);
+ System.err.println("EGLDrawableFactory.MapGLVersions: device "+adevice);
}
- boolean madeCurrentES1 = false;
- boolean madeCurrentES2 = false;
- boolean madeCurrentES3 = false;
- boolean madeCurrentGLn = false;
-
- if( null != eglGLnDynamicLookupHelper ) {
- // OpenGL 3.1 core -> GL3, will utilize normal desktop profile mapping
- final int[] major = { 3 };
- final int[] minor = { 1 }; // FIXME: No minor version probing for ES currently!
- madeCurrentGLn = mapAvailableEGLESConfig(adevice, major, minor,
- ctpGLn, rendererQuirksGLn) && 0 != major[0];
+ final boolean initDefaultDevice;
+ if( 0 == defaultDevice.getHandle() ) { // Note: GLProfile always triggers EGL device initialization first!
+ initDefaultDevice = true;
+ defaultDevice.open();
+ defaultDeviceEGLFeatures = new EGLFeatures(defaultDevice);
+ if ( DEBUG_SHAREDCTX ) {
+ System.err.println("EGLDrawableFactory.MapGLVersions: defaultDevice "+defaultDevice);
+ System.err.println("EGLDrawableFactory.MapGLVersions: defaultDevice EGLFeatures "+defaultDeviceEGLFeatures);
+ }
+ // Probe for GLRendererQuirks.SingletonEGLDisplayOnly
+ final boolean singletonEGLDisplayOnlyVendor, singletonEGLDisplayOnlyProbe;
+ if( defaultDeviceEGLFeatures.vendor.contains("NVIDIA") ) { // OpenGL ES 3.1 NVIDIA 355.06 unstable
+ singletonEGLDisplayOnlyVendor=true;
+ singletonEGLDisplayOnlyProbe=false;
+ } else {
+ singletonEGLDisplayOnlyVendor=false;
+ final long secondEGLDisplay = EGL.eglGetDisplay(EGL.EGL_DEFAULT_DISPLAY);
+ singletonEGLDisplayOnlyProbe = EGL.EGL_NO_DISPLAY == secondEGLDisplay;
+ }
+ if( singletonEGLDisplayOnlyVendor || singletonEGLDisplayOnlyProbe ) {
+ final int quirk = GLRendererQuirks.SingletonEGLDisplayOnly;
+ GLRendererQuirks.addStickyDeviceQuirk(adevice, quirk);
+ EGLDisplayUtil.setSingletonEGLDisplayOnly(true);
+ if ( DEBUG_SHAREDCTX ) {
+ if( singletonEGLDisplayOnlyVendor ) {
+ System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: Vendor: "+defaultDeviceEGLFeatures);
+ } else if( singletonEGLDisplayOnlyProbe ) {
+ System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: Second eglGetDisplay(EGL_DEFAULT_DISPLAY) failed");
+ }
+ }
+ }
} else {
- madeCurrentGLn = false;
+ initDefaultDevice = false;
+ if( null == defaultSharedResource ) {
+ throw new InternalError("XXX: defaultDevice "+defaultDevice+", adevice "+adevice);
+ }
}
- EGLContext.setAvailableGLVersionsSet(adevice, true);
- if( null != eglES1DynamicLookupHelper ) {
- final int[] major = { 1 };
- final int[] minor = { 0 };
- madeCurrentES1 = mapAvailableEGLESConfig(adevice, major, minor,
- ctpES1, rendererQuirksES1) && 1 == major[0];
- } else {
- madeCurrentES1 = false;
- }
- if( null != eglES2DynamicLookupHelper ) {
- // ES3 Query
- final int[] major = { 3 };
- final int[] minor = { 0 };
- madeCurrentES3 = mapAvailableEGLESConfig(adevice, major, minor,
- ctpES3ES2, rendererQuirksES3ES2) && 3 == major[0];
- if( !madeCurrentES3 ) {
- // ES2 Query, may result in ES3
- major[0] = 2;
- if( mapAvailableEGLESConfig(adevice, major, minor,
- ctpES3ES2, rendererQuirksES3ES2) )
- {
- switch( major[0] ) {
- case 2: madeCurrentES2 = true; break;
- case 3: madeCurrentES3 = true; break;
- default: throw new InternalError("XXXX Got "+major[0]);
+ final boolean[] mappedToDefaultDevice = { false };
+ final GLRendererQuirks[] rendererQuirksES1 = new GLRendererQuirks[] { null };
+ final GLRendererQuirks[] rendererQuirksES2 = new GLRendererQuirks[] { null };
+ final GLRendererQuirks[] rendererQuirksES3 = new GLRendererQuirks[] { null };
+ final GLRendererQuirks[] rendererQuirksGLn = new GLRendererQuirks[] { null };
+ final int[] ctpES1 = new int[] { 0 };
+ final int[] ctpES2 = new int[] { 0 };
+ final int[] ctpES3 = new int[] { 0 };
+ final int[] ctpGLn = new int[] { 0 };
+ final boolean[] madeCurrentES1 = { false };
+ final boolean[] madeCurrentES2 = { false };
+ final boolean[] madeCurrentES3 = { false };
+ final boolean[] madeCurrentGLn = { false };
+
+ final GLContextImpl.MappedGLVersionListener mvl = new GLContextImpl.MappedGLVersionListener() {
+ @Override
+ public void glVersionMapped(final MappedGLVersion e) {
+ if ( DEBUG_SHAREDCTX ) {
+ System.err.println("EGLDrawableFactory.MapGLVersions: Mapped: "+e);
+ }
+ if ( EGLContext.isGLES2ES3(e.ctxVersion.getMajor(), e.ctxOptions) ) {
+ if( e.ctxVersion.getMajor() == 3 ) {
+ madeCurrentES3[0] = true;
+ rendererQuirksES3[0] = e.quirks;
+ ctpES3[0] = e.ctxOptions;
}
+ madeCurrentES2[0] = true;
+ rendererQuirksES2[0] = e.quirks;
+ ctpES2[0] = e.ctxOptions;
+ } else if ( EGLContext.isGLES1(e.ctxVersion.getMajor(), e.ctxOptions) ) {
+ madeCurrentES1[0] = true;
+ rendererQuirksES1[0] = e.quirks;
+ ctpES1[0] = e.ctxOptions;
+ } else if( EGLContext.isGLDesktop(e.ctxOptions) ) {
+ madeCurrentGLn[0] = true;
+ rendererQuirksGLn[0] = e.quirks;
+ ctpGLn[0] = e.ctxOptions;
}
}
+ };
+ final SharedResource sr;
+ final EGLGraphicsDevice[] eglDevice = { null };
+ final boolean mapSuccess;
+ EGLContext.setMappedGLVersionListener(mvl);
+ try {
+ // Query triggers profile mapping!
+ mapSuccess = mapAvailableEGLESConfig(adevice, mappedToDefaultDevice, eglDevice);
+ } finally {
+ EGLContext.setMappedGLVersionListener(null);
}
- if( hasX11 ) {
- handleDontCloseX11DisplayQuirk(rendererQuirksES1[0]);
- handleDontCloseX11DisplayQuirk(rendererQuirksES3ES2[0]);
+ if( mappedToDefaultDevice[0] ) {
+ EGLContext.remapAvailableGLVersions(defaultDevice, adevice);
+ sr = defaultSharedResource;
+ } else {
+ if( hasX11 ) {
+ handleDontCloseX11DisplayQuirk(rendererQuirksES1[0]);
+ handleDontCloseX11DisplayQuirk(rendererQuirksGLn[0]);
+ handleDontCloseX11DisplayQuirk(rendererQuirksES3[0]);
+ handleDontCloseX11DisplayQuirk(rendererQuirksES2[0]);
+ }
+ sr = new SharedResource(eglDevice[0],
+ madeCurrentES1[0], rendererQuirksES1[0], ctpES1[0],
+ madeCurrentES2[0], rendererQuirksES2[0], ctpES2[0],
+ madeCurrentES3[0], rendererQuirksES3[0], ctpES3[0],
+ madeCurrentGLn[0], rendererQuirksGLn[0], ctpGLn[0]);
+ if( initDefaultDevice ) {
+ defaultSharedResource = sr;
+ }
}
- final SharedResource sr = new SharedResource(defaultDevice,
- madeCurrentGLn || madeCurrentES1 || madeCurrentES2 || madeCurrentES3,
- rendererQuirksGLn[0], ctpGLn[0],
- rendererQuirksES1[0], ctpES1[0],
- rendererQuirksES3ES2[0], ctpES3ES2[0]);
if ( DEBUG_SHAREDCTX ) {
- System.err.println("EGLDrawableFactory.createShared: devices: queried nativeTK "+QUERY_EGL_ES_NATIVE_TK+", adevice " + adevice + ", defaultDevice " + defaultDevice);
- System.err.println("EGLDrawableFactory.createShared: context GLn: " + madeCurrentGLn + ", quirks "+rendererQuirksGLn[0]);
- System.err.println("EGLDrawableFactory.createShared: context ES1: " + madeCurrentES1 + ", quirks "+rendererQuirksES1[0]);
- System.err.println("EGLDrawableFactory.createShared: context ES2: " + madeCurrentES2 + ", quirks "+rendererQuirksES3ES2[0]);
- System.err.println("EGLDrawableFactory.createShared: context ES3: " + madeCurrentES3 + ", quirks "+rendererQuirksES3ES2[0]);
+ System.err.println("EGLDrawableFactory.MapGLVersions: mapSuccess "+mapSuccess+", mappedToDefaultDevice "+mappedToDefaultDevice[0]);
+ System.err.println("EGLDrawableFactory.MapGLVersions: defDevice : " + defaultDevice);
+ System.err.println("EGLDrawableFactory.MapGLVersions: adevice : " + adevice);
+ System.err.println("EGLDrawableFactory.MapGLVersions: eglDevice : " + sr.device);
+ System.err.println("EGLDrawableFactory.MapGLVersions: context ES1: " + sr.isAvailableES1 + ", quirks "+sr.rendererQuirksES1);
+ System.err.println("EGLDrawableFactory.MapGLVersions: context ES2: " + sr.isAvailableES2 + ", quirks "+sr.rendererQuirksES2);
+ System.err.println("EGLDrawableFactory.MapGLVersions: context ES3: " + sr.isAvailableES3 + ", quirks "+sr.rendererQuirksES3);
+ System.err.println("EGLDrawableFactory.MapGLVersions: context GLn: " + sr.isAvailableGLn + ", quirks "+sr.rendererQuirksGLn);
dumpMap();
}
return sr;
@@ -607,200 +656,218 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
}
private boolean mapAvailableEGLESConfig(final AbstractGraphicsDevice adevice,
- final int[] majorVersion, final int[] minorVersion,
- final int[] ctxProfile, final GLRendererQuirks[] rendererQuirks) {
- final String profileString = EGLContext.getGLProfile(majorVersion[0], minorVersion[0], ctxProfile[0]);
+ final boolean[] mapsADeviceToDefaultDevice,
+ final EGLGraphicsDevice[] resEGLDevice) {
+ final int majorVersion = 2;
+ final int minorVersion = 0;
+ final int ctxProfile = EGLContext.CTX_PROFILE_ES;
+ final String profileString = EGLContext.getGLProfile(majorVersion, minorVersion, ctxProfile);
if ( !GLProfile.isAvailable(adevice, profileString) ) {
if ( DEBUG_SHAREDCTX ) {
- System.err.println("EGLDrawableFactory.mapAvailableEGLESConfig: "+profileString+" n/a on "+adevice);
+ System.err.println("EGLDrawableFactory.MapGLVersions: "+profileString+" n/a on "+adevice);
}
return false;
}
final GLProfile glp = GLProfile.get(adevice, profileString) ;
final GLDrawableFactoryImpl desktopFactory = (GLDrawableFactoryImpl) GLDrawableFactory.getDesktopFactory();
- final boolean initDefaultDevice = 0 == defaultDevice.getHandle(); // Note: GLProfile always triggers EGL device initialization first!
- final boolean mapsADeviceToDefaultDevice = !QUERY_EGL_ES_NATIVE_TK || initDefaultDevice ||
- null == desktopFactory;
- // FIXME || adevice instanceof EGLGraphicsDevice ;
+
+ final GLCapabilities reqCapsAny = new GLCapabilities(glp);
+ reqCapsAny.setRedBits(5); reqCapsAny.setGreenBits(5); reqCapsAny.setBlueBits(5); reqCapsAny.setAlphaBits(0);
+ reqCapsAny.setDoubleBuffered(false);
+ final GLCapabilitiesImmutable reqCapsPBuffer = GLGraphicsConfigurationUtil.fixGLPBufferGLCapabilities(reqCapsAny);
+ final List<GLCapabilitiesImmutable> defaultDevicePBufferCapsL = getAvailableEGLConfigs(defaultDevice, reqCapsPBuffer);
+ final boolean defaultDeviceHasPBuffer = defaultDevicePBufferCapsL.size() > 0;
+
+ final boolean useDefaultDevice = adevice == defaultDevice;
+
+ mapsADeviceToDefaultDevice[0] = !useDefaultDevice &&
+ null != defaultSharedResource && defaultSharedResource.isAvailable &&
+ defaultConnection.equals(adevice.getConnection());
+
if ( DEBUG_SHAREDCTX ) {
- System.err.println("EGLDrawableFactory.mapAvailableEGLESConfig: "+profileString+" ( "+majorVersion[0]+" ), "+
- "mapsADeviceToDefaultDevice "+mapsADeviceToDefaultDevice+
- " (QUERY_EGL_ES_NATIVE_TK "+QUERY_EGL_ES_NATIVE_TK+", initDefaultDevice "+initDefaultDevice+", hasDesktopFactory "+(null != desktopFactory)+
+ System.err.println("EGLDrawableFactory.MapGLVersions: "+profileString+" ( "+majorVersion+" ), "+
+ "mapsADeviceToDefaultDevice "+mapsADeviceToDefaultDevice[0]+
+ " (useDefaultDevice "+useDefaultDevice+", defaultDeviceHasPBuffer "+defaultDeviceHasPBuffer+", hasDesktopFactory "+(null != desktopFactory)+
", isEGLGraphicsDevice "+(adevice instanceof EGLGraphicsDevice)+")");
}
- boolean hasPBuffer;
- EGLGraphicsDevice eglDevice = null;
- EGLFeatures eglFeatures = null;
- NativeSurface surface = null;
- ProxySurface upstreamSurface = null; // X11, GLX, ..
- ProxySurface downstreamSurface = null; // EGL
+ if( mapsADeviceToDefaultDevice[0] ) {
+ return true;
+ }
+
+ final boolean defaultNoSurfacelessCtx = GLRendererQuirks.existStickyDeviceQuirk(defaultDevice, GLRendererQuirks.NoSurfacelessCtx);
boolean success = false;
- try {
- 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.
- if( initDefaultDevice ) {
- defaultDevice.open();
- defaultDeviceEGLFeatures = new EGLFeatures(defaultDevice);
-
- // Probe for GLRendererQuirks.SingletonEGLDisplayOnly
- final long secondEGLDisplay = EGL.eglGetDisplay(EGL.EGL_DEFAULT_DISPLAY);
- if ( EGL.EGL_NO_DISPLAY == secondEGLDisplay ) {
- final int quirk = GLRendererQuirks.SingletonEGLDisplayOnly;
- GLRendererQuirks.addStickyDeviceQuirk(adevice, quirk);
- EGLDisplayUtil.setSingletonEGLDisplayOnly(true);
+ final boolean hasKHRSurfacelessTried;
+ if( defaultDeviceEGLFeatures.hasKHRSurfaceless && !defaultNoSurfacelessCtx ) {
+ hasKHRSurfacelessTried = true;
+ final AbstractGraphicsDevice zdevice = useDefaultDevice ? defaultDevice : adevice; // reuse
+ final EGLSurface zeroSurface = createSurfacelessImpl(zdevice, false, reqCapsAny, reqCapsAny, null, 64, 64);
+ resEGLDevice[0] = (EGLGraphicsDevice) zeroSurface.getGraphicsConfiguration().getScreen().getDevice();
+ if ( DEBUG_SHAREDCTX ) {
+ System.err.println("EGLDrawableFactory-MapGLVersions.0: "+resEGLDevice[0]);
+ }
+ EGLDrawable zeroDrawable = null;
+ EGLContext context = null;
+ boolean hasException = false;
+ try {
+ zeroDrawable = (EGLDrawable) createOnscreenDrawableImpl ( zeroSurface );
+ zeroDrawable.setRealized(true);
+
+ context = (EGLContext) zeroDrawable.createContext(null);
+ if (null == context) {
+ throw new GLException("Couldn't create shared context for drawable: "+zeroDrawable);
+ }
+ // Triggers initial mapping, if not done yet
+ if( GLContext.CONTEXT_NOT_CURRENT != context.makeCurrent() ) { // could cause exception
+ // context.isCurrent() !
+ final GL gl = context.getGL();
+ final String glVersionString = gl.glGetString(GL.GL_VERSION);
+ if(null != glVersionString) {
+ success = true;
+ } else {
+ setNoSurfacelessCtxQuirk(context);
+ }
+ } else if ( DEBUG_SHAREDCTX ) {
+ System.err.println("EGLDrawableFactory-MapGLVersions.0: NOT_CURRENT: "+resEGLDevice[0]+", "+context);
+ }
+ } catch (final Throwable t) {
+ hasException = true;
+ if ( DEBUG_SHAREDCTX ) {
+ System.err.println("EGLDrawableFactory-MapGLVersions.0: INFO: context create/makeCurrent failed");
+ t.printStackTrace();
+ }
+ } finally {
+ if( null != context ) {
+ try {
+ context.destroy();
+ } catch (final GLException gle) {
if ( DEBUG_SHAREDCTX ) {
- System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: Second eglGetDisplay(EGL_DEFAULT_DISPLAY) failed");
+ System.err.println("EGLDrawableFactory-MapGLVersions.0: INFO: destroy caught exception:");
+ gle.printStackTrace();
}
}
}
- eglDevice = defaultDevice; // reuse
+ if( null != zeroDrawable ) {
+ zeroDrawable.setRealized(false);
+ }
+ if( null != zeroSurface ) {
+ zeroSurface.destroyNotify();
+ }
+ if( success || hasException ) { // cont. using device if !success
+ if( defaultDevice != resEGLDevice[0] ) { // don't close default device
+ if(null != resEGLDevice[0]) {
+ resEGLDevice[0].close();
+ }
+ }
+ }
+ }
+ if( success ) {
+ return true;
+ }
+ } else { // hasKHRSurfaceless
+ hasKHRSurfacelessTried = false;
+ }
+ EGLFeatures eglFeatures = null;
+ NativeSurface surface = null;
+ EGLDrawable drawable = null;
+ GLDrawable zeroDrawable = null;
+ EGLContext context = null;
+ ProxySurface upstreamSurface = null; // X11, GLX, ..
+ ProxySurface downstreamSurface = null; // EGL
+ try {
+ if( useDefaultDevice && defaultDeviceHasPBuffer ) {
+ // Map any non EGL device to EGL default shared resources (default behavior), using a pbuffer surface
+ resEGLDevice[0] = defaultDevice; // reuse
eglFeatures = defaultDeviceEGLFeatures;
if ( DEBUG_SHAREDCTX ) {
- System.err.println("EGLDrawableFactory.mapAvailableEGLESConfig.0: "+eglFeatures);
+ System.err.println("EGLDrawableFactory-MapGLVersions.1: "+resEGLDevice[0]);
+ System.err.println("EGLDrawableFactory-MapGLVersions.1: "+eglFeatures);
}
- if( !glp.isGLES() && !eglFeatures.hasGLAPI ) {
- if ( DEBUG_SHAREDCTX ) {
- System.err.println("EGLDrawableFactory.mapAvailableEGLESConfig() OpenGL API not supported (1)");
- }
- } else {
- final GLCapabilitiesImmutable reqCapsPBuffer = GLGraphicsConfigurationUtil.fixGLPBufferGLCapabilities(reqCapsAny);
- final List<GLCapabilitiesImmutable> availablePBufferCapsL = getAvailableEGLConfigs(eglDevice, reqCapsPBuffer);
- hasPBuffer = availablePBufferCapsL.size() > 0;
-
- // attempt to created the default shared resources ..
- if( hasPBuffer ) {
- // 2nd case create defaultDevice shared resource using pbuffer surface
- downstreamSurface = createDummySurfaceImpl(eglDevice, false, reqCapsPBuffer, reqCapsPBuffer, null, 64, 64); // egl pbuffer offscreen
- if( null != downstreamSurface ) {
- downstreamSurface.createNotify();
- surface = downstreamSurface;
- }
- } 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_SHAREDCTX ) {
- System.err.println("EGLDrawableFactory.mapAvailableEGLESConfig() no pbuffer config available, detected !pbuffer config: "+success);
- EGLGraphicsConfigurationFactory.printCaps("!PBufferCaps", capsAnyL, System.err);
- }
- }
+ downstreamSurface = createDummySurfaceImpl(resEGLDevice[0], false, reqCapsPBuffer, reqCapsPBuffer, null, 64, 64);
+ if( null != downstreamSurface ) {
+ downstreamSurface.createNotify();
+ surface = downstreamSurface;
}
- } else {
- // 4th case always creates a true mapping of given device to EGL
+ } else if( adevice != defaultDevice ) {
+ // Create a true mapping of given device to EGL
upstreamSurface = desktopFactory.createDummySurface(adevice, reqCapsAny, null, 64, 64); // X11, WGL, .. dummy window
if(null != upstreamSurface) {
upstreamSurface.createNotify();
- eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(upstreamSurface);
- eglDevice.open();
- eglFeatures = new EGLFeatures(eglDevice);
+ resEGLDevice[0] = EGLDisplayUtil.eglCreateEGLGraphicsDevice(upstreamSurface);
+ resEGLDevice[0].open();
+ eglFeatures = new EGLFeatures(resEGLDevice[0]);
if ( DEBUG_SHAREDCTX ) {
- System.err.println("EGLDrawableFactory.mapAvailableEGLESConfig.1: "+eglFeatures);
- }
- if( !glp.isGLES() && !eglFeatures.hasGLAPI ) {
- if ( DEBUG_SHAREDCTX ) {
- System.err.println("EGLDrawableFactory.mapAvailableEGLESConfig() OpenGL API not supported (2)");
- }
- // disposed at finalized: eglDevice, upstreamSurface
- } else {
- hasPBuffer = true;
- surface = upstreamSurface;
+ System.err.println("EGLDrawableFactory-MapGLVersions.2: "+resEGLDevice[0]);
+ System.err.println("EGLDrawableFactory-MapGLVersions.2: "+eglFeatures);
}
+ surface = upstreamSurface;
}
}
if(null != surface) {
- EGLDrawable drawable = null;
- GLDrawable zeroDrawable = null;
- EGLContext context = null;
- try {
- drawable = (EGLDrawable) createOnscreenDrawableImpl ( surface );
- drawable.setRealized(true);
-
- context = (EGLContext) drawable.createContext(null);
- if (null == context) {
- throw new GLException("Couldn't create shared context for drawable: "+drawable);
- }
+ drawable = (EGLDrawable) createOnscreenDrawableImpl ( surface );
+ drawable.setRealized(true);
- if( GLContext.CONTEXT_NOT_CURRENT != context.makeCurrent() ) { // could cause exception
- // context.isCurrent() !
- final String glVersionString = context.getGL().glGetString(GL.GL_VERSION);
- if(null != glVersionString) {
- context.mapCurrentAvailableGLESVersion(eglDevice);
- if(eglDevice != adevice) {
- context.mapCurrentAvailableGLESVersion(adevice);
- }
+ context = (EGLContext) drawable.createContext(null);
+ if (null == context) {
+ throw new GLException("Couldn't create shared context for drawable: "+drawable);
+ }
- if( eglFeatures.hasKHRSurfaceless &&
- ( context.isGLES() || context.getGLVersionNumber().compareTo(GLContext.Version3_0) >= 0 )
- )
- {
- if( probeSurfacelessCtx(context, false /* restoreDrawable */) ) {
- zeroDrawable = context.getGLDrawable();
- }
- } else {
- setNoSurfacelessCtxQuirk(context);
+ // Triggers initial mapping, if not done yet
+ if( GLContext.CONTEXT_NOT_CURRENT != context.makeCurrent() ) { // could cause exception
+ // context.isCurrent() !
+ final GL gl = context.getGL();
+ final String glVersionString = gl.glGetString(GL.GL_VERSION);
+ if(null != glVersionString) {
+ success = true;
+ if( !hasKHRSurfacelessTried && eglFeatures.hasKHRSurfaceless &&
+ ( context.isGLES() || context.getGLVersionNumber().compareTo(GLContext.Version3_0) >= 0 )
+ )
+ {
+ if( probeSurfacelessCtx(context, false /* restoreDrawable */) ) {
+ zeroDrawable = context.getGLDrawable();
}
- rendererQuirks[0] = context.getRendererQuirks();
- ctxProfile[0] = context.getContextOptions();
- majorVersion[0] = context.getGLVersionNumber().getMajor();
- minorVersion[0] = context.getGLVersionNumber().getMinor();
- success = true;
} else {
- // Oops .. something is wrong
- if ( DEBUG_SHAREDCTX ) {
- System.err.println("EGLDrawableFactory.mapAvailableEGLESConfig: "+eglDevice+", "+context.getGLVersion()+" - VERSION is null, dropping availability!");
- }
+ setNoSurfacelessCtxQuirk(context);
}
+ } else if ( DEBUG_SHAREDCTX ) {
+ System.err.println("EGLDrawableFactory-MapGLVersions.12: NULL VERSION: "+resEGLDevice[0]+", "+context.getGLVersion());
}
- } catch (final Throwable t) {
- if ( DEBUG_SHAREDCTX ) {
- System.err.println("EGLDrawableFactory.mapAvailableEGLESConfig: INFO: context create/makeCurrent failed");
- t.printStackTrace();
- }
- } finally {
- if( null != context ) {
- try {
- context.destroy();
- } catch (final GLException gle) {
- if ( DEBUG_SHAREDCTX ) {
- System.err.println("EGLDrawableFactory.mapAvailableEGLESConfig: INFO: destroy caught exception:");
- gle.printStackTrace();
- }
- }
- }
- if( null != zeroDrawable ) {
- zeroDrawable.setRealized(false);
- }
- if( null != drawable ) {
- drawable.setRealized(false);
- }
+ } else if ( DEBUG_SHAREDCTX ) {
+ System.err.println("EGLDrawableFactory-MapGLVersions.12: NOT_CURRENT: "+resEGLDevice[0]+", "+context);
}
}
} catch (final Throwable t) {
if ( DEBUG_SHAREDCTX ) {
- System.err.println("Caught exception on thread "+getThreadName());
+ System.err.println("EGLDrawableFactory-MapGLVersions.12: INFO: context create/makeCurrent failed");
t.printStackTrace();
}
success = false;
} finally {
- if(null != downstreamSurface) {
+ if( null != context ) {
+ try {
+ context.destroy();
+ } catch (final GLException gle) {
+ if ( DEBUG_SHAREDCTX ) {
+ System.err.println("EGLDrawableFactory-MapGLVersions.12: INFO: destroy caught exception:");
+ gle.printStackTrace();
+ }
+ }
+ }
+ if( null != zeroDrawable ) {
+ zeroDrawable.setRealized(false);
+ }
+ if( null != drawable ) {
+ drawable.setRealized(false);
+ }
+ if( null != downstreamSurface ) {
downstreamSurface.destroyNotify();
}
- if( defaultDevice != eglDevice ) { // don't close default device
- if(null != eglDevice) {
- eglDevice.close();
+ if( defaultDevice != resEGLDevice[0] ) { // don't close default device
+ if(null != resEGLDevice[0]) {
+ resEGLDevice[0].close();
}
}
if(null != upstreamSurface) {
@@ -831,8 +898,44 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
public final boolean hasDefaultDeviceKHRCreateContext() {
return defaultDeviceEGLFeatures.hasKHRCreateContext;
}
- public final boolean hasOpenGLAPISupport() {
- return defaultDeviceEGLFeatures.hasGLAPI;
+ /**
+ * {@inheritDoc}
+ * <p>
+ * This factory may support native desktop OpenGL if {@link EGL#EGL_CLIENT_APIS} contains {@code OpenGL}
+ * <i>and</i> if {@code EGL_KHR_create_context} extension is supported.
+ * </p>
+ */
+ @Override
+ public final boolean hasOpenGLDesktopSupport() {
+ /**
+ * It has been experienced w/ Mesa 10.3.2 (EGL 1.4/Gallium)
+ * that even though initial OpenGL context can be created w/o 'EGL_KHR_create_context',
+ * switching the API via 'eglBindAPI(EGL_OpenGL_API)' the latter 'eglCreateContext(..)' fails w/ EGL_BAD_ACCESS.
+ * Hence we require both: OpenGL API support _and_ 'EGL_KHR_create_context'.
+ */
+ return null != eglGLnDynamicLookupHelper &&
+ defaultDeviceEGLFeatures.hasGLAPI && defaultDeviceEGLFeatures.hasKHRCreateContext;
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * This factory always supports native GLES profiles.
+ * </p>
+ */
+ @Override
+ public final boolean hasOpenGLESSupport() { return true; }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Return true if {@code EGL_KHR_create_context} extension is supported,
+ * see {@link #hasDefaultDeviceKHRCreateContext()}.
+ * </p>
+ */
+ @Override
+ public final boolean hasMajorMinorCreateContextARB() {
+ return hasDefaultDeviceKHRCreateContext();
}
@Override
@@ -843,7 +946,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
@Override
public final boolean getIsDeviceCompatible(final AbstractGraphicsDevice device) {
// via mappings (X11/WGL/.. -> EGL) we shall be able to handle all types.
- return null != sharedMap ; // null!=eglES2DynamicLookupHelper || null!=eglES1DynamicLookupHelper;
+ return null != sharedResourceImplementation ; // null!=eglES2DynamicLookupHelper || null!=eglES1DynamicLookupHelper || ..;
}
private static List<GLCapabilitiesImmutable> getAvailableEGLConfigs(final EGLGraphicsDevice eglDisplay, final GLCapabilitiesImmutable caps) {
@@ -885,24 +988,28 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
}
@Override
- public GLDynamicLookupHelper getGLDynamicLookupHelper(final String esProfile) {
+ public final GLDynamicLookupHelper getGLDynamicLookupHelper(final int majorVersion, final int contextOptions) {
final GLDynamicLookupHelper res;
- if ( GLProfile.GLES2 == esProfile || GLProfile.GLES3 == esProfile ) {
+ if ( EGLContext.isGLES2ES3(majorVersion, contextOptions) ) {
res = eglES2DynamicLookupHelper;
- } else if ( GLProfile.GLES1 == esProfile ) {
+ } else if ( EGLContext.isGLES1(majorVersion, contextOptions) ) {
res = eglES1DynamicLookupHelper;
- } else {
+ } else if( EGLContext.isGLDesktop(contextOptions) ) {
res = eglGLnDynamicLookupHelper;
+ } else {
+ throw new IllegalArgumentException("neither GLES1, GLES2, GLES3 nor desktop GL has been specified: "+majorVersion+" ("+EGLContext.getGLProfile(new StringBuilder(), contextOptions).toString());
}
- if( null == res ) {
- throw new GLException("No lookup for esProfile "+esProfile);
+ if( DEBUG_SHAREDCTX ) {
+ if( null == res ) {
+ System.err.println("EGLDrawableFactory.getGLDynamicLookupHelper: NULL for profile "+majorVersion+" ("+EGLContext.getGLProfile(new StringBuilder(), contextOptions).toString());
+ }
}
return res;
}
@Override
protected List<GLCapabilitiesImmutable> getAvailableCapabilitiesImpl(final AbstractGraphicsDevice device) {
- if(null == sharedMap) { // null == eglES1DynamicLookupHelper && null == eglES2DynamicLookupHelper
+ if(null == sharedResourceImplementation) { // null == eglES1DynamicLookupHelper && null == eglES2DynamicLookupHelper || ..
return new ArrayList<GLCapabilitiesImmutable>(); // null
}
return EGLGraphicsConfigurationFactory.getAvailableCapabilities(this, device);
@@ -942,9 +1049,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
final GLCapabilitiesChooser chooser) {
final EGLGraphicsDevice device;
if( createNewDevice || ! (deviceReq instanceof EGLGraphicsDevice) ) {
- final long nativeDisplayID = ( deviceReq instanceof EGLGraphicsDevice) ?
- ( (EGLGraphicsDevice) deviceReq ).getNativeDisplayID() : deviceReq.getHandle() ;
- device = EGLDisplayUtil.eglCreateEGLGraphicsDevice(nativeDisplayID, deviceReq.getConnection(), deviceReq.getUnitID());
+ device = EGLDisplayUtil.eglCreateEGLGraphicsDevice(deviceReq);
device.open();
ownDevice[0] = true;
} else {
@@ -960,7 +1065,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
}
@Override
- protected final ProxySurface createMutableSurfaceImpl(final AbstractGraphicsDevice deviceReq, final boolean createNewDevice,
+ protected final EGLSurface createMutableSurfaceImpl(final AbstractGraphicsDevice deviceReq, final boolean createNewDevice,
final GLCapabilitiesImmutable capsChosen, final GLCapabilitiesImmutable capsRequested,
final GLCapabilitiesChooser chooser, final UpstreamSurfaceHook upstreamHook) {
final boolean[] ownDevice = { false };
@@ -969,14 +1074,14 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
}
@Override
- public final ProxySurface createDummySurfaceImpl(final AbstractGraphicsDevice deviceReq, final boolean createNewDevice,
+ public final EGLSurface createDummySurfaceImpl(final AbstractGraphicsDevice deviceReq, final boolean createNewDevice,
GLCapabilitiesImmutable chosenCaps, final GLCapabilitiesImmutable requestedCaps, final GLCapabilitiesChooser chooser, final int width, final int height) {
chosenCaps = GLGraphicsConfigurationUtil.fixGLPBufferGLCapabilities(chosenCaps); // complete validation in EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(..) above
return createMutableSurfaceImpl(deviceReq, createNewDevice, chosenCaps, requestedCaps, chooser, new EGLDummyUpstreamSurfaceHook(width, height));
}
@Override
- public final ProxySurface createSurfacelessImpl(final AbstractGraphicsDevice deviceReq, final boolean createNewDevice,
+ public final EGLSurface createSurfacelessImpl(final AbstractGraphicsDevice deviceReq, final boolean createNewDevice,
GLCapabilitiesImmutable chosenCaps, final GLCapabilitiesImmutable requestedCaps, final GLCapabilitiesChooser chooser, final int width, final int height) {
chosenCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(chosenCaps);
final boolean[] ownDevice = { false };
@@ -1019,11 +1124,10 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
}
@Override
- protected ProxySurface createProxySurfaceImpl(final AbstractGraphicsDevice deviceReq, final int screenIdx, final long windowHandle,
+ protected EGLSurface createProxySurfaceImpl(final AbstractGraphicsDevice deviceReq, final int screenIdx, final long windowHandle,
final GLCapabilitiesImmutable capsRequested, final GLCapabilitiesChooser chooser,
final UpstreamSurfaceHook upstream) {
- final EGLGraphicsDevice eglDeviceReq = (EGLGraphicsDevice) deviceReq;
- final EGLGraphicsDevice device = EGLDisplayUtil.eglCreateEGLGraphicsDevice(eglDeviceReq.getNativeDisplayID(), deviceReq.getConnection(), deviceReq.getUnitID());
+ final EGLGraphicsDevice device = EGLDisplayUtil.eglCreateEGLGraphicsDevice(deviceReq);
device.open();
final DefaultGraphicsScreen screen = new DefaultGraphicsScreen(device, screenIdx);
final EGLGraphicsConfiguration cfg = EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsRequested, capsRequested, chooser, screen, VisualIDHolder.VID_UNDEFINED, false);
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDummyUpstreamSurfaceHook.java b/src/jogl/classes/jogamp/opengl/egl/EGLDummyUpstreamSurfaceHook.java
index 6c11b3bdc..890dab8f7 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDummyUpstreamSurfaceHook.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDummyUpstreamSurfaceHook.java
@@ -1,5 +1,6 @@
package jogamp.opengl.egl;
+import com.jogamp.common.ExceptionUtils;
import com.jogamp.nativewindow.NativeSurface;
import com.jogamp.nativewindow.ProxySurface;
import com.jogamp.nativewindow.UpstreamSurfaceHook;
@@ -8,6 +9,8 @@ import com.jogamp.nativewindow.UpstreamSurfaceHookMutableSize;
import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
import com.jogamp.opengl.egl.EGL;
+import jogamp.nativewindow.ProxySurfaceImpl;
+
/** Uses a PBuffer offscreen surface */
public class EGLDummyUpstreamSurfaceHook extends UpstreamSurfaceHookMutableSize {
/**
@@ -50,6 +53,11 @@ public class EGLDummyUpstreamSurfaceHook extends UpstreamSurfaceHookMutableSize
}
eglDevice.lock();
try {
+ if( EGLDrawable.DEBUG ) {
+ System.err.println(EGLSurface.getThreadName()+": EGLDummyUpstreamSurfaceHook: EGL.eglDestroySurface: 0x"+Long.toHexString(s.getSurfaceHandle()));
+ ProxySurfaceImpl.dumpHierarchy(System.err, s);
+ ExceptionUtils.dumpStack(System.err);
+ }
EGL.eglDestroySurface(eglDevice.getHandle(), s.getSurfaceHandle());
s.setSurfaceHandle(EGL.EGL_NO_SURFACE);
s.clearUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLES2DynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/egl/EGLES2DynamicLibraryBundleInfo.java
index d37efc455..038194d58 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLES2DynamicLibraryBundleInfo.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLES2DynamicLibraryBundleInfo.java
@@ -31,6 +31,8 @@ package jogamp.opengl.egl;
import java.util.ArrayList;
import java.util.List;
+import jogamp.nativewindow.BcmVCArtifacts;
+
/**
* <p>
* Covering ES3 and ES2.
@@ -41,12 +43,20 @@ public final class EGLES2DynamicLibraryBundleInfo extends EGLDynamicLibraryBundl
super();
}
+
@Override
public final List<List<String>> getToolLibNames() {
+
final List<List<String>> libsList = new ArrayList<List<String>>();
{
final List<String> libsGL = new ArrayList<String>();
+ /**
+ * Prefer libGLESv2.so over libGLESv2.so.2 for proprietary
+ * Broadcom graphics when the VC4 DRM Xorg driver isn't present
+ */
+ final boolean bcm_vc_iv_quirk = BcmVCArtifacts.guessVCIVUsed();
+
// ES3: This is the default lib name, according to the spec
libsGL.add("libGLESv3.so.3");
@@ -63,12 +73,18 @@ public final class EGLES2DynamicLibraryBundleInfo extends EGLDynamicLibraryBundl
libsGL.add("libGLES30");
// ES2: This is the default lib name, according to the spec
- libsGL.add("libGLESv2.so.2");
+ if (!bcm_vc_iv_quirk) {
+ libsGL.add("libGLESv2.so.2");
+ }
// ES2: Try these as well, if spec fails
libsGL.add("libGLESv2.so");
libsGL.add("GLESv2");
+ if (bcm_vc_iv_quirk) {
+ libsGL.add("libGLESv2.so.2");
+ }
+
// ES2: Alternative names
libsGL.add("GLES20");
libsGL.add("GLESv2_CM");
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java
index d10263f22..5505fed52 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java
@@ -242,7 +242,7 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
}
ownEGLDisplay = false;
} else {
- eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(absDevice.getHandle(), absDevice.getConnection(), absDevice.getUnitID());
+ eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(absDevice);
eglDevice.open();
ownEGLDisplay = true;
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLSurface.java b/src/jogl/classes/jogamp/opengl/egl/EGLSurface.java
index e4e692fb2..8956bcbd9 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLSurface.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLSurface.java
@@ -35,7 +35,7 @@ import com.jogamp.nativewindow.ProxySurface;
import com.jogamp.nativewindow.UpstreamSurfaceHook;
import com.jogamp.opengl.GLCapabilitiesImmutable;
import com.jogamp.opengl.GLException;
-
+import com.jogamp.common.ExceptionUtils;
import com.jogamp.common.nio.Buffers;
import com.jogamp.nativewindow.GenericUpstreamSurfacelessHook;
import com.jogamp.opengl.egl.EGL;
@@ -101,16 +101,22 @@ public class EGLSurface extends WrappedSurface {
final boolean isPBuffer = ((GLCapabilitiesImmutable) config.getChosenCapabilities()).isPBuffer();
long eglSurface = createEGLSurfaceHandle(isPBuffer, true /* useSurfaceHandle */, config, nativeSurface);
+ if( DEBUG ) {
+ System.err.println(getThreadName() + ": EGLSurface: EGL.eglCreateSurface.0: 0x"+Long.toHexString(eglSurface));
+ ProxySurfaceImpl.dumpHierarchy(System.err, this);
+ }
+
if ( EGL.EGL_NO_SURFACE == eglSurface ) {
final int eglError0 = EGL.eglGetError();
if( EGL.EGL_BAD_NATIVE_WINDOW == eglError0 && !isPBuffer ) {
// Try window handle if available and differs (Windows HDC / HWND).
// ANGLE impl. required HWND on Windows.
if( hasUniqueNativeWindowHandle(nativeSurface) ) {
- if(DEBUG) {
+ eglSurface = createEGLSurfaceHandle(isPBuffer, false /* useSurfaceHandle */, config, nativeSurface);
+ if( DEBUG ) {
System.err.println(getThreadName() + ": Info: Creation of window surface w/ surface handle failed: "+config+", error "+GLDrawableImpl.toHexString(eglError0)+", retry w/ windowHandle");
+ System.err.println(getThreadName() + ": EGLSurface: EGL.eglCreateSurface.1: 0x"+Long.toHexString(eglSurface));
}
- eglSurface = createEGLSurfaceHandle(isPBuffer, false /* useSurfaceHandle */, config, nativeSurface);
if (EGL.EGL_NO_SURFACE == eglSurface) {
throw new GLException("Creation of window surface w/ window handle failed: "+config+", "+this+", error "+GLDrawableImpl.toHexString(EGL.eglGetError()));
}
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
index d4fc0b005..995ff870e 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
@@ -63,6 +63,7 @@ import com.jogamp.opengl.fixedfunc.GLMatrixFunc;
import jogamp.nativewindow.macosx.OSXUtil;
import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLDrawableImpl;
+import jogamp.opengl.GLDynamicLookupHelper;
import jogamp.opengl.GLFBODrawableImpl;
import jogamp.opengl.GLGraphicsConfigurationUtil;
import jogamp.opengl.macosx.cgl.MacOSXCGLDrawable.GLBackendType;
@@ -85,6 +86,8 @@ public class MacOSXCGLContext extends GLContextImpl
// NSOpenGL-based or CGL-based)
protected interface GLBackendImpl {
boolean isNSContext();
+ /** Indicating CALayer, i.e. onscreen rendering using offscreen layer. */
+ boolean isUsingCALayer();
long create(long share, int ctp, int major, int minor);
boolean destroy(long ctx);
void associateDrawable(boolean bound);
@@ -108,6 +111,9 @@ public class MacOSXCGLContext extends GLContextImpl
}
static boolean isGLProfileSupported(final int ctp, final int major, final int minor) {
+ if( 0 != ( CTX_PROFILE_ES & ctp ) ) {
+ return false;
+ }
final boolean ctBwdCompat = 0 != ( CTX_PROFILE_COMPAT & ctp ) ;
final boolean ctCore = 0 != ( CTX_PROFILE_CORE & ctp ) ;
@@ -423,12 +429,33 @@ public class MacOSXCGLContext extends GLContextImpl
}
@Override
- protected boolean setSwapIntervalImpl(final int interval) {
- return impl.setSwapInterval(interval);
+ protected final Integer setSwapIntervalImpl2(final int interval) {
+ if( !impl.isUsingCALayer() && !drawable.getChosenGLCapabilities().isOnscreen() ) {
+ return null;
+ }
+ final int useInterval;
+ if( 0 > interval ) {
+ useInterval = Math.abs(interval);
+ } else {
+ useInterval = interval;
+ }
+ if( impl.setSwapInterval(useInterval) ) {
+ return Integer.valueOf(useInterval);
+ }
+ return null;
}
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Ignoring {@code contextFQN}, using {@code MacOSX}-{@link AbstractGraphicsDevice#getUniqueID()}.
+ * </p>
+ */
@Override
- protected final void updateGLXProcAddressTable() {
+ protected final void updateGLXProcAddressTable(final String contextFQN, final GLDynamicLookupHelper dlh) {
+ if( null == dlh ) {
+ throw new GLException("No GLDynamicLookupHelper for "+this);
+ }
final AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration();
final AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice();
final String key = "MacOSX-"+adevice.getUniqueID();
@@ -446,7 +473,7 @@ public class MacOSXCGLContext extends GLContextImpl
}
} else {
cglExtProcAddressTable = new CGLExtProcAddressTable(new GLProcAddressResolver());
- resetProcAddressTable(getCGLExtProcAddressTable());
+ resetProcAddressTable(getCGLExtProcAddressTable(), dlh);
synchronized(mappedContextTypeObjectLock) {
mappedGLXProcAddress.put(key, getCGLExtProcAddressTable());
if(DEBUG) {
@@ -521,6 +548,8 @@ public class MacOSXCGLContext extends GLContextImpl
@Override
public boolean isNSContext() { return true; }
+ @Override
+ public boolean isUsingCALayer() { return null != backingLayerHost; }
/** Only returns a valid NSView. If !NSView, return null and mark either isPBuffer, isFBO or isSurfaceless. */
private long getNSViewHandle(final boolean[] isPBuffer, final boolean[] isFBO, final boolean[] isSurfaceless) {
@@ -547,7 +576,7 @@ public class MacOSXCGLContext extends GLContextImpl
nsViewHandle = OSXUtil.GetNSView(drawableHandle);
} else if( isPBuffer[0] ) {
nsViewHandle = 0;
- } else if( isSurfacelessOK() ) {
+ } else if( isSurfaceless() ) {
isSurfaceless[0] = true;
nsViewHandle = 0;
} else {
@@ -1128,6 +1157,9 @@ public class MacOSXCGLContext extends GLContextImpl
public boolean isNSContext() { return false; }
@Override
+ public boolean isUsingCALayer() { return false; }
+
+ @Override
public long create(final long share, final int ctp, final int major, final int minor) {
long ctx = 0;
final MacOSXCGLGraphicsConfiguration config = (MacOSXCGLGraphicsConfiguration) drawable.getNativeSurface().getGraphicsConfiguration();
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java
index ab1d56e29..871067f4c 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java
@@ -148,7 +148,7 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
}
@Override
- public GLDynamicLookupHelper getGLDynamicLookupHelper(final String profileName) {
+ public final GLDynamicLookupHelper getGLDynamicLookupHelper(final int majorVersion, final int contextOptions) {
return macOSXCGLDynamicLookupHelper;
}
@@ -335,6 +335,33 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
return null;
}
+ /**
+ * {@inheritDoc}
+ * <p>
+ * This factory always supports native desktop OpenGL profiles.
+ * </p>
+ */
+ @Override
+ public final boolean hasOpenGLDesktopSupport() { return true; }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * This factory never supports native GLES profiles.
+ * </p>
+ */
+ @Override
+ public final boolean hasOpenGLESSupport() { return false; }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Always returns true.
+ * </p>
+ */
+ @Override
+ public final boolean hasMajorMinorCreateContextARB() { return true; }
+
@Override
protected List<GLCapabilitiesImmutable> getAvailableCapabilitiesImpl(final AbstractGraphicsDevice device) {
return MacOSXCGLGraphicsConfiguration.getAvailableCapabilities(this, device);
diff --git a/src/jogl/classes/jogamp/opengl/openal/av/ALAudioSink.java b/src/jogl/classes/jogamp/opengl/openal/av/ALAudioSink.java
index 562d4883d..bdd9b6c95 100644
--- a/src/jogl/classes/jogamp/opengl/openal/av/ALAudioSink.java
+++ b/src/jogl/classes/jogamp/opengl/openal/av/ALAudioSink.java
@@ -195,11 +195,21 @@ public class ALAudioSink implements AudioSink {
clearPreALError("init."+checkErrIter++);
preferredAudioFormat = new AudioFormat(querySampleRate(), DefaultFormat.sampleSize, DefaultFormat.channelCount, DefaultFormat.signed, DefaultFormat.fixedP, DefaultFormat.planar, DefaultFormat.littleEndian);
if( DEBUG ) {
- System.out.println("ALAudioSink: OpenAL Extensions:"+al.alGetString(ALConstants.AL_EXTENSIONS));
+ final int[] alcvers = { 0, 0 };
+ System.out.println("ALAudioSink: OpenAL Version: "+al.alGetString(ALConstants.AL_VERSION));
+ System.out.println("ALAudioSink: OpenAL Extensions: "+al.alGetString(ALConstants.AL_EXTENSIONS));
clearPreALError("init."+checkErrIter++);
- System.out.println("ALAudioSink: Null device OpenAL Extensions:"+alc.alcGetString(null, ALCConstants.ALC_EXTENSIONS));
+ System.out.println("ALAudioSink: Null device OpenALC:");
+ alc.alcGetIntegerv(null, ALCConstants.ALC_MAJOR_VERSION, 1, alcvers, 0);
+ alc.alcGetIntegerv(null, ALCConstants.ALC_MINOR_VERSION, 1, alcvers, 1);
+ System.out.println(" Version: "+alcvers[0]+"."+alcvers[1]);
+ System.out.println(" Extensions: "+alc.alcGetString(null, ALCConstants.ALC_EXTENSIONS));
clearPreALError("init."+checkErrIter++);
- System.out.println("ALAudioSink: Device "+deviceSpecifier+" OpenAL Extensions:"+alc.alcGetString(device, ALCConstants.ALC_EXTENSIONS));
+ System.out.println("ALAudioSink: Device "+deviceSpecifier+" OpenALC:");
+ alc.alcGetIntegerv(device, ALCConstants.ALC_MAJOR_VERSION, 1, alcvers, 0);
+ alc.alcGetIntegerv(device, ALCConstants.ALC_MINOR_VERSION, 1, alcvers, 1);
+ System.out.println(" Version: "+alcvers[0]+"."+alcvers[1]);
+ System.out.println(" Extensions: "+alc.alcGetString(device, ALCConstants.ALC_EXTENSIONS));
System.out.println("ALAudioSink: hasSOFTBufferSamples "+hasSOFTBufferSamples);
System.out.println("ALAudioSink: hasALC_thread_local_context "+hasALC_thread_local_context);
System.out.println("ALAudioSink: preferredAudioFormat "+preferredAudioFormat);
@@ -310,12 +320,14 @@ public class ALAudioSink implements AudioSink {
final int alSrcName = null != alSource ? alSource[0] : 0;
final int alBuffersLen = null != alBufferNames ? alBufferNames.length : 0;
final int ctxHash = context != null ? context.hashCode() : 0;
+ final int alFramesAvailSize = alFramesAvail != null ? alFramesAvail.size() : 0;
+ final int alFramesPlayingSize = alFramesPlaying != null ? alFramesPlaying.size() : 0;
return "ALAudioSink[init "+initialized+", playRequested "+playRequested+", device "+deviceSpecifier+", ctx "+toHexString(ctxHash)+", alSource "+alSrcName+
", chosen "+chosenFormat+
", al[chan "+ALHelpers.alChannelLayoutName(alChannelLayout)+", type "+ALHelpers.alSampleTypeName(alSampleType)+
", fmt "+toHexString(alFormat)+", soft "+hasSOFTBufferSamples+
- "], playSpeed "+playSpeed+", buffers[total "+alBuffersLen+", avail "+alFramesAvail.size()+", "+
- "queued["+alFramesPlaying.size()+", apts "+getPTS()+", "+getQueuedTime() + " ms, " + alBufferBytesQueued+" bytes], "+
+ "], playSpeed "+playSpeed+", buffers[total "+alBuffersLen+", avail "+alFramesAvailSize+", "+
+ "queued["+alFramesPlayingSize+", apts "+getPTS()+", "+getQueuedTime() + " ms, " + alBufferBytesQueued+" bytes], "+
"queue[g "+frameGrowAmount+", l "+frameLimit+"]";
}
diff --git a/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java b/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java
index cfecbfd8d..f09d289fa 100644
--- a/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java
+++ b/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java
@@ -46,10 +46,14 @@ import com.jogamp.opengl.GLProfile;
import jogamp.opengl.Debug;
import com.jogamp.common.net.UriQueryProps;
+import com.jogamp.common.ExceptionUtils;
import com.jogamp.common.net.Uri;
import com.jogamp.common.os.Platform;
+import com.jogamp.common.util.InterruptSource;
+import com.jogamp.common.util.InterruptedRuntimeException;
import com.jogamp.common.util.LFRingbuffer;
import com.jogamp.common.util.Ringbuffer;
+import com.jogamp.common.util.SourcedInterruptedException;
import com.jogamp.opengl.GLExtensions;
import com.jogamp.opengl.util.TimeFrameI;
import com.jogamp.opengl.util.av.AudioSink;
@@ -365,7 +369,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
event_mask = addStateEventMask(event_mask, GLMediaPlayer.State.Paused);
setState( State.Paused );
if( null != streamWorker ) {
- streamWorker.doPause();
+ streamWorker.doPause(true);
}
if( flush ) {
resetAVPTSAndFlush();
@@ -414,7 +418,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
final State _state = state;
setState( State.Paused );
if( null != streamWorker ) {
- streamWorker.doPause();
+ streamWorker.doPause(true);
}
// Adjust target ..
if( msec >= duration ) {
@@ -571,7 +575,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
this.vid = vid;
this.aid = aid;
- new Thread() {
+ new InterruptSource.Thread() {
public void run() {
try {
// StreamWorker may be used, see API-doc of StreamWorker
@@ -968,8 +972,9 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
* shall be <code>null</code> for audio only.
* @return the last processed video PTS value, maybe {@link TimeFrameI#INVALID_PTS} if video frame is invalid or n/a.
* Will be {@link TimeFrameI#END_OF_STREAM_PTS} if end of stream reached.
+ * @throws InterruptedException if waiting for next frame fails
*/
- protected abstract int getNextTextureImpl(GL gl, TextureFrame nextFrame);
+ protected abstract int getNextTextureImpl(GL gl, TextureFrame nextFrame) throws InterruptedException;
protected final int getNextSingleThreaded(final GL gl, final TextureFrame nextFrame, final boolean[] gotVFrame) throws InterruptedException {
final int pts;
@@ -1064,7 +1069,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
* {@link GLMediaPlayerImpl#updateAttributes(int, int, int, int, int, int, int, float, int, int, int, String, String) updateAttributes(..)},
* the latter decides whether StreamWorker is being used.
*/
- class StreamWorker extends Thread {
+ class StreamWorker extends InterruptSource.Thread {
private volatile boolean isRunning = false;
private volatile boolean isActive = false;
private volatile boolean isBlocked = false;
@@ -1086,13 +1091,13 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
setDaemon(true);
synchronized(this) {
start();
- while( !isRunning ) {
+ try {
this.notifyAll(); // wake-up startup-block
- try {
+ while( !isRunning && !shallStop ) {
this.wait(); // wait until started
- } catch (final InterruptedException e) {
- e.printStackTrace();
}
+ } catch (final InterruptedException e) {
+ throw new InterruptedRuntimeException(e);
}
}
}
@@ -1140,18 +1145,20 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
sharedGLCtx.release();
}
}
- public final synchronized void doPause() {
+ public final synchronized void doPause(final boolean waitUntilDone) {
if( isActive ) {
shallPause = true;
- if( Thread.currentThread() != this ) {
+ if( java.lang.Thread.currentThread() != this ) {
if( isBlocked && isActive ) {
this.interrupt();
}
- while( isActive && isRunning ) {
+ if( waitUntilDone ) {
try {
- this.wait(); // wait until paused
+ while( isActive && isRunning ) {
+ this.wait(); // wait until paused
+ }
} catch (final InterruptedException e) {
- e.printStackTrace();
+ throw new InterruptedRuntimeException(e);
}
}
}
@@ -1160,14 +1167,16 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
public final synchronized void doResume() {
if( isRunning && !isActive ) {
shallPause = false;
- if( Thread.currentThread() != this ) {
- while( !isActive && !shallPause && isRunning ) {
+ if( java.lang.Thread.currentThread() != this ) {
+ try {
this.notifyAll(); // wake-up pause-block
- try {
+ while( !isActive && !shallPause && isRunning ) {
this.wait(); // wait until resumed
- } catch (final InterruptedException e) {
- e.printStackTrace();
}
+ } catch (final InterruptedException e) {
+ final InterruptedException e2 = SourcedInterruptedException.wrap(e);
+ doPause(false);
+ throw new InterruptedRuntimeException(e2);
}
}
}
@@ -1175,17 +1184,17 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
public final synchronized void doStop() {
if( isRunning ) {
shallStop = true;
- if( Thread.currentThread() != this ) {
+ if( java.lang.Thread.currentThread() != this ) {
if( isBlocked && isRunning ) {
this.interrupt();
}
- while( isRunning ) {
+ try {
this.notifyAll(); // wake-up pause-block (opt)
- try {
+ while( isRunning ) {
this.wait(); // wait until stopped
- } catch (final InterruptedException e) {
- e.printStackTrace();
}
+ } catch (final InterruptedException e) {
+ throw new InterruptedRuntimeException(e);
}
}
}
@@ -1203,48 +1212,48 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
this.notifyAll(); // wake-up ctor()
}
- while( !shallStop ){
- if( shallPause ) {
- synchronized ( this ) {
- if( sharedGLCtxCurrent ) {
- postNextTextureImpl(sharedGLCtx.getGL());
- sharedGLCtx.release();
- }
- while( shallPause && !shallStop ) {
- isActive = false;
- this.notifyAll(); // wake-up doPause()
- try {
- this.wait(); // wait until resumed
- } catch (final InterruptedException e) {
- if( !shallPause ) {
- e.printStackTrace();
+ while( !shallStop ) {
+ TextureFrame nextFrame = null;
+ try {
+ if( shallPause ) {
+ synchronized ( this ) {
+ if( sharedGLCtxCurrent ) {
+ postNextTextureImpl(sharedGLCtx.getGL());
+ sharedGLCtx.release();
+ }
+ while( shallPause && !shallStop ) {
+ isActive = false;
+ this.notifyAll(); // wake-up doPause()
+ try {
+ this.wait(); // wait until resumed
+ } catch (final InterruptedException e) {
+ if( !shallPause ) {
+ throw SourcedInterruptedException.wrap(e);
+ }
}
}
+ if( sharedGLCtxCurrent ) {
+ makeCurrent(sharedGLCtx);
+ preNextTextureImpl(sharedGLCtx.getGL());
+ }
+ isActive = true;
+ this.notifyAll(); // wake-up doResume()
}
- if( sharedGLCtxCurrent ) {
- makeCurrent(sharedGLCtx);
- preNextTextureImpl(sharedGLCtx.getGL());
- }
- isActive = true;
- this.notifyAll(); // wake-up doResume()
}
- }
- if( !sharedGLCtxCurrent && null != sharedGLCtx ) {
- synchronized ( this ) {
- if( null != sharedGLCtx ) {
- makeCurrent( sharedGLCtx );
- preNextTextureImpl(sharedGLCtx.getGL());
- sharedGLCtxCurrent = true;
- }
- if( null == videoFramesFree ) {
- throw new InternalError("XXX videoFramesFree is null");
+ if( !sharedGLCtxCurrent && null != sharedGLCtx ) {
+ synchronized ( this ) {
+ if( null != sharedGLCtx ) {
+ makeCurrent( sharedGLCtx );
+ preNextTextureImpl(sharedGLCtx.getGL());
+ sharedGLCtxCurrent = true;
+ }
+ if( null == videoFramesFree ) {
+ throw new InternalError("XXX videoFramesFree is null");
+ }
}
}
- }
- if( !shallStop ) {
- TextureFrame nextFrame = null;
- try {
+ if( !shallStop ) {
isBlocked = true;
final GL gl;
if( STREAM_ID_NONE != vid ) {
@@ -1260,7 +1269,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
if( TimeFrameI.INVALID_PTS != vPTS ) {
if( null != nextFrame ) {
if( STREAM_WORKER_DELAY > 0 ) {
- Thread.sleep(STREAM_WORKER_DELAY);
+ java.lang.Thread.sleep(STREAM_WORKER_DELAY);
}
if( !videoFramesDecoded.put(nextFrame) ) {
throw new InternalError("XXX: free "+videoFramesFree+", decoded "+videoFramesDecoded+", "+GLMediaPlayerImpl.this);
@@ -1294,31 +1303,30 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
}
pauseImpl(true, GLMediaEventListener.EVENT_CHANGE_EOS);
}
- } catch (final InterruptedException e) {
- isBlocked = false;
- if( !shallStop && !shallPause ) {
- streamErr = new StreamException("InterruptedException while decoding: "+GLMediaPlayerImpl.this.toString(), e);
- }
- } catch (final Throwable t) {
- streamErr = new StreamException(t.getClass().getSimpleName()+" while decoding: "+GLMediaPlayerImpl.this.toString(), t);
- } finally {
- if( null != nextFrame ) { // put back
- videoFramesFree.put(nextFrame);
+ }
+ } catch (final InterruptedException e) {
+ if( !isBlocked ) { // !shallStop && !shallPause
+ streamErr = new StreamException("InterruptedException while decoding: "+GLMediaPlayerImpl.this.toString(),
+ SourcedInterruptedException.wrap(e));
+ }
+ isBlocked = false;
+ } catch (final Throwable t) {
+ streamErr = new StreamException(t.getClass().getSimpleName()+" while decoding: "+GLMediaPlayerImpl.this.toString(), t);
+ } finally {
+ if( null != nextFrame ) { // put back
+ videoFramesFree.put(nextFrame);
+ }
+ if( null != streamErr ) {
+ if( DEBUG ) {
+ ExceptionUtils.dumpThrowable("handled", streamErr);
}
- if( null != streamErr ) {
- if( DEBUG ) {
- final Throwable t = null != streamErr.getCause() ? streamErr.getCause() : streamErr;
- System.err.println("Caught StreamException: "+t.getMessage());
- t.printStackTrace();
- }
- // state transition incl. notification
- synchronized ( this ) {
- shallPause = true;
- isActive = false;
- this.notifyAll(); // wake-up potential do*()
- }
- pauseImpl(true, GLMediaEventListener.EVENT_CHANGE_ERR);
+ // state transition incl. notification
+ synchronized ( this ) {
+ shallPause = true;
+ isActive = false;
+ this.notifyAll(); // wake-up potential do*()
}
+ pauseImpl(true, GLMediaEventListener.EVENT_CHANGE_ERR);
}
}
}
@@ -1379,6 +1387,16 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
}
}
+ /**
+ * Called initially by {@link #initStreamImpl(int, int)}, which
+ * is called off-thread by {@link #initStream(Uri, int, int, int)}.
+ * <p>
+ * The latter catches an occurring exception and set the state delivers the error events.
+ * </p>
+ * <p>
+ * Further calls are issues off-thread by the decoder implementation.
+ * </p>
+ */
protected final void updateAttributes(int vid, final int aid, final int width, final int height, final int bps_stream,
final int bps_video, final int bps_audio, final float fps,
final int videoFrames, final int audioFrames, final int duration, final String vcodec, final String acodec) {
@@ -1413,7 +1431,12 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
this.fps = fps;
if( 0 != fps ) {
this.frame_duration = 1000f / fps;
- this.maxNullFrameCountUntilEOS = MAX_FRAMELESS_MS_UNTIL_EOS / (int)this.frame_duration;
+ final int fdurI = (int)this.frame_duration;
+ if( 0 < fdurI ) {
+ this.maxNullFrameCountUntilEOS = MAX_FRAMELESS_MS_UNTIL_EOS / fdurI;
+ } else {
+ this.maxNullFrameCountUntilEOS = MAX_FRAMELESS_UNTIL_EOS_DEFAULT;
+ }
} else {
this.frame_duration = 0;
this.maxNullFrameCountUntilEOS = MAX_FRAMELESS_UNTIL_EOS_DEFAULT;
@@ -1524,7 +1547,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
final int decVideoFrames = null != videoFramesDecoded ? videoFramesDecoded.size() : 0;
final int video_scr = video_scr_pts + (int) ( ( Platform.currentTimeMillis() - video_scr_t0 ) * playSpeed );
final String camPath = null != cameraPath ? ", camera: "+cameraPath : "";
- return "GLMediaPlayer["+state+", vSCR "+video_scr+", frames[p "+presentedFrameCount+", d "+decodedFrameCount+", t "+videoFrames+" ("+tt+" s), z "+nullFrameCount+" / "+maxNullFrameCountUntilEOS+"], "+
+ return getClass().getSimpleName()+"["+state+", vSCR "+video_scr+", frames[p "+presentedFrameCount+", d "+decodedFrameCount+", t "+videoFrames+" ("+tt+" s), z "+nullFrameCount+" / "+maxNullFrameCountUntilEOS+"], "+
"speed "+playSpeed+", "+bps_stream+" bps, hasSW "+(null!=streamWorker)+
", Texture[count "+textureCount+", free "+freeVideoFrames+", dec "+decVideoFrames+", tagt "+toHexString(textureTarget)+", ifmt "+toHexString(textureInternalFormat)+", fmt "+toHexString(textureFormat)+", type "+toHexString(textureType)+"], "+
"Video[id "+vid+", <"+vcodec+">, "+width+"x"+height+", glOrient "+isInGLOrientation+", "+fps+" fps, "+frame_duration+" fdur, "+bps_video+" bps], "+
diff --git a/src/jogl/classes/jogamp/opengl/util/av/VideoPixelFormat.java b/src/jogl/classes/jogamp/opengl/util/av/VideoPixelFormat.java
index 44d83e78d..db8da6157 100644
--- a/src/jogl/classes/jogamp/opengl/util/av/VideoPixelFormat.java
+++ b/src/jogl/classes/jogamp/opengl/util/av/VideoPixelFormat.java
@@ -64,7 +64,7 @@ public enum VideoPixelFormat {
XVMC_MPEG2_MC,
/** */
XVMC_MPEG2_IDCT,
- /** packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1 */
+ /** packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1 ( sharing Cb and Cr w/ 2 pixels ) */
UYVY422,
/** packed YUV 4:1:1, 12bpp, Cb Y0 Y1 Cr Y2 Y3 */
UYYVYY411,
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 f294d5bc0..6a4257ade 100644
--- a/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGDynamicLibraryBundleInfo.java
+++ b/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGDynamicLibraryBundleInfo.java
@@ -37,7 +37,7 @@ import java.util.List;
import java.util.Set;
import com.jogamp.opengl.GLProfile;
-
+import com.jogamp.common.ExceptionUtils;
import com.jogamp.common.os.DynamicLibraryBundle;
import com.jogamp.common.os.DynamicLibraryBundleInfo;
import com.jogamp.common.util.RunnableExecutor;
@@ -190,7 +190,8 @@ class FFMPEGDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo {
libLoaded[i] = dl.isToolLibLoaded(i);
}
if( !libLoaded[LIB_IDX_UTI] || !libLoaded[LIB_IDX_FMT] || !libLoaded[LIB_IDX_COD] ) {
- throw new RuntimeException("FFMPEG Tool library incomplete: [ avutil "+libLoaded[LIB_IDX_UTI]+", avformat "+libLoaded[LIB_IDX_FMT]+", avcodec "+libLoaded[LIB_IDX_COD]+"]");
+ System.err.println("FFMPEG Tool library incomplete: [ avutil "+libLoaded[LIB_IDX_UTI]+", avformat "+libLoaded[LIB_IDX_FMT]+", avcodec "+libLoaded[LIB_IDX_COD]+"]");
+ return null;
}
dl.claimAllLinkPermission();
try {
@@ -216,7 +217,10 @@ class FFMPEGDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo {
throw new InternalError("XXX0 "+symbolNames.length+" != "+symbolCount);
}
- AccessController.doPrivileged(privInitSymbolsAction);
+ final DynamicLibraryBundle dl = AccessController.doPrivileged(privInitSymbolsAction);
+ if( null == dl ) {
+ return false;
+ }
// optional symbol name set
final Set<String> optionalSymbolNameSet = new HashSet<String>();
@@ -254,7 +258,7 @@ class FFMPEGDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo {
try {
_ready = initSymbols(_versions);
} catch (final Throwable t) {
- t.printStackTrace();
+ ExceptionUtils.dumpThrowable("", t);
}
libsUFCLoaded = libLoaded[LIB_IDX_UTI] && libLoaded[LIB_IDX_FMT] && libLoaded[LIB_IDX_COD];
avUtilVersion = _versions[0];
@@ -328,6 +332,16 @@ class FFMPEGDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo {
}
@Override
+ public final boolean searchToolLibInSystemPath() {
+ return true;
+ }
+
+ @Override
+ public final boolean searchToolLibSystemPathFirst() {
+ return true;
+ }
+
+ @Override
public final List<List<String>> getToolLibNames() {
final List<List<String>> libsList = new ArrayList<List<String>>();
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 7df5d6a9e..b5cccdb6d 100644
--- a/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGMediaPlayer.java
+++ b/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGMediaPlayer.java
@@ -106,11 +106,12 @@ import jogamp.opengl.util.av.VideoPixelFormat;
* <p>
* Currently we are binary compatible w/:
* <table border="1">
- * <tr><th>libav / ffmpeg</th><th>lavc</th><th>lavf</th><th>lavu</th><th>lavr/lswr</th> <th>FFMPEG* class</th></tr>
+ * <tr><th>libav / ffmpeg</th><th>lavc</th><th>lavf</th><th>lavu</th><th>lavr/lswr</th> <th>FFMPEG* class</th></tr>
* <tr><td>0.8</td> <td>53</td> <td>53</td> <td>51</td> <td></td> <td>FFMPEGv08</td></tr>
* <tr><td>9.0 / 1.2</td> <td>54</td> <td>54</td> <td>52</td> <td>01/00</td> <td>FFMPEGv09</td></tr>
* <tr><td>10 / 2.[0-3]</td> <td>55</td> <td>55</td> <td>53/52</td> <td>01/00</td> <td>FFMPEGv10</td></tr>
- * <tr><td>11 / 2.[4-x]</td> <td>56</td> <td>56</td> <td>54</td> <td>02/01</td> <td>FFMPEGv11</td></tr>
+ * <tr><td>11 / 2.[4-8]</td> <td>56</td> <td>56</td> <td>54</td> <td>02/01</td> <td>FFMPEGv11</td></tr>
+ * <tr><td>12 / 2.[9-x]</td> <td>57</td> <td>57</td> <td>55</td> <td>02/01</td> <td>TODO</td></tr>
* </table>
* </p>
* <p>
@@ -145,17 +146,28 @@ import jogamp.opengl.util.av.VideoPixelFormat;
* <li>GNU/Linux: ffmpeg or libav are deployed in most distributions.</li>
* <li>Windows:
* <ul>
+ * <li>https://ffmpeg.org/download.html#build-windows</li>
* <li>http://ffmpeg.zeranoe.com/builds/ (ffmpeg) <i>recommended, works w/ dshow</i></li>
* <li>http://win32.libav.org/releases/ (libav)</li>
* </ul></li>
- * <li>MacOSX using Homebrew
+ * <li>MacOSX
* <ul>
- * <li>https://github.com/Homebrew/homebrew/wiki/Installation</li>
- * <li>https://trac.ffmpeg.org/wiki/CompilationGuide/MacOSX</li>
+ * <li>Building using Homebrew *
+ * <ul>
+ * <li>https://github.com/Homebrew/homebrew/wiki/Installation</li>
+ * <li>https://trac.ffmpeg.org/wiki/CompilationGuide/MacOSX<pre>
+ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
+brew install ffmpeg
+ * </pre></li>
+ * </ul></li>
+ * <li>Builds
+ * <ul>
+ * <li>https://ffmpeg.org/download.html#build-mac</li>
+ * </ul></li>
* </ul></li>
* <li>OpenIndiana/Solaris:<pre>
- * pkg set-publisher -p http://pkg.openindiana.org/sfe-encumbered.
- * pkt install pkg:/video/ffmpeg
+pkg set-publisher -p http://pkg.openindiana.org/sfe-encumbered.
+pkt install pkg:/video/ffmpeg
* </pre></li>
* </ul>
* </p>
@@ -337,12 +349,10 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl {
resStreamLocS = dev_video_linux + cameraPath.decode();
break;
case WINDOWS:
- resStreamLocS = cameraPath.decode();
- break;
case MACOS:
case OPENKODE:
default:
- resStreamLocS = streamLocS; // FIXME: ??
+ resStreamLocS = cameraPath.decode();
break;
}
if( null != cameraProps ) {
@@ -436,9 +446,10 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl {
}
break;
- case 2: if( vPixelFmt == VideoPixelFormat.YUYV422 ) {
+ case 2: if( vPixelFmt == VideoPixelFormat.YUYV422 || vPixelFmt == VideoPixelFormat.UYVY422 ) {
// YUYV422: // < packed YUV 4:2:2, 2x 16bpp, Y0 Cb Y1 Cr
- // Stuffed into RGBA half width texture
+ // UYVY422: // < packed YUV 4:2:2, 2x 16bpp, Cb Y0 Cr Y1
+ // Both stuffed into RGBA half width texture
tf = GL.GL_RGBA; tif=GL.GL_RGBA; break;
} else {
tf = GL2ES2.GL_RG; tif=GL2ES2.GL_RG; break;
@@ -606,6 +617,7 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl {
texWidth = vTexWidth[0] + vTexWidth[1] + vTexWidth[2]; texHeight = vH;
break;
case YUYV422: // < packed YUV 4:2:2, 2x 16bpp, Y0 Cb Y1 Cr - stuffed into RGBA half width texture
+ case UYVY422: // < packed YUV 4:2:2, 2x 16bpp, Cb Y0 Cr Y1 - stuffed into RGBA half width texture
case BGR24:
usesTexLookupShader = true;
texWidth = vTexWidth[0]; texHeight = vH;
@@ -764,6 +776,29 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl {
" return vec4(r, g, b, 1);\n"+
"}\n"
;
+ case UYVY422: // < packed YUV 4:2:2, 2 x 16bpp, Cb Y0 Cr Y1
+ // Stuffed into RGBA half width texture
+ return
+ "vec4 "+texLookupFuncName+"(in "+getTextureSampler2DType()+" image, in vec2 texCoord) {\n"+
+ " "+
+ " float y1,u,y2,v,y,r,g,b;\n"+
+ " vec2 tc_halfw = vec2(texCoord.x*0.5, texCoord.y);\n"+
+ " vec4 uyvy = texture2D(image, tc_halfw).rgba;\n"+
+ " u = uyvy.r;\n"+
+ " y1 = uyvy.g;\n"+
+ " v = uyvy.b;\n"+
+ " y2 = uyvy.a;\n"+
+ " y = mix( y1, y2, mod(gl_FragCoord.x, 2) ); /* avoid branching! */\n"+
+ " y = 1.1643*(y-0.0625);\n"+
+ " u = u-0.5;\n"+
+ " v = v-0.5;\n"+
+ " r = y+1.5958*v;\n"+
+ " g = y-0.39173*u-0.81290*v;\n"+
+ " b = y+2.017*u;\n"+
+ " return vec4(r, g, b, 1);\n"+
+ "}\n"
+ ;
+
case BGR24:
return
"vec4 "+texLookupFuncName+"(in "+getTextureSampler2DType()+" image, in vec2 texCoord) {\n"+
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 22dd1e61a..516aa0f6f 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
@@ -6,10 +6,10 @@
#define mgl_FragColor gl_FragColor
#endif
-#include es_precision.glsl
+#include "es_precision.glsl"
-#include mgl_uniform.glsl
-#include mgl_varying.glsl
+#include "mgl_uniform.glsl"
+#include "mgl_varying.glsl"
#include mgl_alphatest.fp
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 130711e19..8a610f062 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
@@ -8,14 +8,14 @@
#endif
-#include es_precision.glsl
-#include mgl_lightdef.glsl
+#include "es_precision.glsl"
+#include "mgl_lightdef.glsl"
-#include mgl_const.glsl
-#include mgl_uniform.glsl
-#include mgl_varying.glsl
+#include "mgl_const.glsl"
+#include "mgl_uniform.glsl"
+#include "mgl_varying.glsl"
-#include mgl_alphatest.fp
+#include "mgl_alphatest.fp"
const float gamma = 1.5; // FIXME
const vec3 igammav = vec3(1.0 / gamma); // FIXME
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java
index a8269ad5c..fd0db7c04 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java
@@ -50,15 +50,19 @@ import com.jogamp.nativewindow.NativeSurface;
import com.jogamp.opengl.GLContext;
import com.jogamp.opengl.GLException;
import com.jogamp.opengl.GLCapabilitiesImmutable;
+import com.jogamp.common.ExceptionUtils;
import com.jogamp.common.nio.Buffers;
import com.jogamp.gluegen.runtime.ProcAddressTable;
import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver;
import com.jogamp.opengl.GLExtensions;
+import com.jogamp.opengl.GLProfile;
import com.jogamp.opengl.GLRendererQuirks;
import jogamp.nativewindow.windows.GDI;
import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLDrawableImpl;
+import jogamp.opengl.GLDynamicLookupHelper;
+import jogamp.opengl.GLXExtensions;
public class WindowsWGLContext extends GLContextImpl {
static final Map<String, String> extensionNameMap;
@@ -70,7 +74,8 @@ public class WindowsWGLContext extends GLContextImpl {
// Table that holds the addresses of the native C-language entry points for
// WGL extension functions.
private WGLExtProcAddressTable wglExtProcAddressTable;
- private int hasSwapIntervalSGI = 0;
+ /** 2 WGL_EXT_swap_control_tear, 1 WGL_EXT_swap_control, 0 undefined, -1 none */
+ private int hasSwapInterval = 0;
private int hasSwapGroupNV = 0;
static {
@@ -93,7 +98,7 @@ public class WindowsWGLContext extends GLContextImpl {
wglGLReadDrawableAvailable=false;
// no inner state _wglExt=null;
wglExtProcAddressTable=null;
- hasSwapIntervalSGI = 0;
+ hasSwapInterval = 0;
hasSwapGroupNV = 0;
super.resetStates(isInit);
}
@@ -198,20 +203,37 @@ public class WindowsWGLContext extends GLContextImpl {
@Override
protected long createContextARBImpl(final long share, final boolean direct, final int ctp, final int major, final int minor) {
+ if(DEBUG) {
+ System.err.println(getThreadName()+" - WindowWGLContext.createContextARBImpl: "+getGLVersion(major, minor, ctp, "@creation") +
+ ", handle "+toHexString(drawable.getHandle()) + ", share "+toHexString(share)+", direct "+direct);
+ }
+ final boolean ctDesktopGL = 0 == ( CTX_PROFILE_ES & ctp );
+ final boolean ctBwdCompat = 0 != ( CTX_PROFILE_COMPAT & ctp ) ;
+ final boolean ctFwdCompat = 0 != ( CTX_OPTION_FORWARD & ctp ) ;
+ final boolean ctDebug = 0 != ( CTX_OPTION_DEBUG & ctp ) ;
+ if( !ctDesktopGL ) {
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": WindowWGLContext.createContextARBImpl: GL ES not avail "+getGLVersion(major, minor, ctp, "@creation"));
+ }
+ return 0; // n/a
+ }
if( null == getWGLExtProcAddressTable()) {
- updateGLXProcAddressTable();
+ final GLDynamicLookupHelper dlh = getGLDynamicLookupHelper(major, ctp);
+ if( null == dlh ) {
+ if(DEBUG) {
+ System.err.println(getThreadName()+" - WindowWGLContext.createContextARBImpl: Null GLDynamicLookupHelper");
+ }
+ return 0;
+ } else {
+ updateGLXProcAddressTable(null, dlh);
+ }
}
final WGLExt _wglExt = getWGLExt();
if(DEBUG) {
- System.err.println(getThreadName()+" - WindowWGLContext.createContextARBImpl: "+getGLVersion(major, minor, ctp, "@creation") +
- ", handle "+toHexString(drawable.getHandle()) + ", share "+toHexString(share)+", direct "+direct+
+ System.err.println(getThreadName()+" - WindowWGLContext.createContextARBImpl: "+
", wglCreateContextAttribsARB: "+toHexString(wglExtProcAddressTable._addressof_wglCreateContextAttribsARB));
}
- final boolean ctBwdCompat = 0 != ( CTX_PROFILE_COMPAT & ctp ) ;
- final boolean ctFwdCompat = 0 != ( CTX_OPTION_FORWARD & ctp ) ;
- final boolean ctDebug = 0 != ( CTX_OPTION_DEBUG & ctp ) ;
-
long ctx=0;
final int idx_flags = 4;
@@ -294,6 +316,11 @@ public class WindowsWGLContext extends GLContextImpl {
"], bitmap "+glCaps.isBitmap()+" -> "+createContextARBAvailable+
"], shared "+sharedCreatedWithARB+"]");
}
+ final GLProfile glp = glCaps.getGLProfile();
+ if( glp.isGLES() ) {
+ throw new GLException(getThreadName()+": Unable to create OpenGL ES context on desktopDevice "+device+
+ ", config "+config+", "+glp+", shareWith "+toHexString(shareWithHandle));
+ }
boolean createContextARBTried = false;
// utilize the shared context's GLXExt in case it was using the ARB method and it already exists
@@ -438,8 +465,17 @@ public class WindowsWGLContext extends GLContextImpl {
}
}
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Ignoring {@code contextFQN}, using {@code WGL}-{@link AbstractGraphicsDevice#getUniqueID()}.
+ * </p>
+ */
@Override
- protected final void updateGLXProcAddressTable() {
+ protected final void updateGLXProcAddressTable(final String contextFQN, final GLDynamicLookupHelper dlh) {
+ if( null == dlh ) {
+ throw new GLException("No GLDynamicLookupHelper for "+this);
+ }
final AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration();
final AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice();
final String key = "WGL-"+adevice.getUniqueID();
@@ -462,7 +498,7 @@ public class WindowsWGLContext extends GLContextImpl {
}
} else {
wglExtProcAddressTable = new WGLExtProcAddressTable(new GLProcAddressResolver());
- resetProcAddressTable(wglExtProcAddressTable);
+ resetProcAddressTable(wglExtProcAddressTable, dlh);
synchronized(mappedContextTypeObjectLock) {
mappedGLXProcAddress.put(key, getWGLExtProcAddressTable());
if(DEBUG) {
@@ -487,19 +523,42 @@ public class WindowsWGLContext extends GLContextImpl {
}
@Override
- protected boolean setSwapIntervalImpl(final int interval) {
- final WGLExt wglExt = getWGLExt();
- if(0==hasSwapIntervalSGI) {
+ protected final Integer setSwapIntervalImpl2(final int interval) {
+ if( !drawable.getChosenGLCapabilities().isOnscreen() ) {
+ return null;
+ }
+ if( 0 == hasSwapInterval ) {
try {
- hasSwapIntervalSGI = wglExt.isExtensionAvailable("WGL_EXT_swap_control")?1:-1;
- } catch (final Throwable t) { hasSwapIntervalSGI=1; }
+ if ( isExtensionAvailable(GLXExtensions.WGL_EXT_swap_control) ) {
+ hasSwapInterval = 1;
+ if ( isExtensionAvailable(GLXExtensions.WGL_EXT_swap_control_tear) ) {
+ hasSwapInterval = 2;
+ if(DEBUG) { System.err.println("WGLContext.setSwapInterval.2 using: "+GLXExtensions.WGL_EXT_swap_control_tear + ", " + GLXExtensions.WGL_EXT_swap_control_tear); }
+ } else {
+ hasSwapInterval = 1;
+ if(DEBUG) { System.err.println("WGLContext.setSwapInterval.1 using: "+GLXExtensions.WGL_EXT_swap_control); }
+ }
+ } else {
+ hasSwapInterval = -1;
+ if(DEBUG) { System.err.println("WGLContext.setSwapInterval.0 N/A"); }
+ }
+ } catch (final Throwable t) { hasSwapInterval=-1; if(DEBUG) { ExceptionUtils.dumpThrowable("", t); } }
}
- if (hasSwapIntervalSGI>0) {
+ if ( 0 < hasSwapInterval ) { // 2 || 1
+ final int useInterval;
+ if( 1 == hasSwapInterval && 0 > interval ) {
+ useInterval = Math.abs(interval);
+ } else {
+ useInterval = interval;
+ }
try {
- return wglExt.wglSwapIntervalEXT(interval);
- } catch (final Throwable t) { hasSwapIntervalSGI=-1; }
+ final WGLExt wglExt = getWGLExt();
+ if( wglExt.wglSwapIntervalEXT(useInterval) ) {
+ return Integer.valueOf(useInterval);
+ }
+ } catch (final Throwable t) { hasSwapInterval=-1; if(DEBUG) { ExceptionUtils.dumpThrowable("", t); } }
}
- return false;
+ return null;
}
private final int initSwapGroupImpl(final WGLExt wglExt) {
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
index 932c81f5d..652184e7e 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
@@ -44,8 +44,6 @@ import java.nio.Buffer;
import java.nio.ShortBuffer;
import java.security.AccessController;
import java.security.PrivilegedAction;
-import java.util.Collection;
-import java.util.HashMap;
import java.util.List;
import com.jogamp.nativewindow.AbstractGraphicsConfiguration;
@@ -191,11 +189,10 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
} catch (final Exception jre) { /* n/a .. */ }
}
- sharedMap = new HashMap<String, SharedResourceRunner.Resource>();
-
// Init shared resources off thread
// Will be released via ShutdownHook
- sharedResourceRunner = new SharedResourceRunner(new SharedResourceImplementation());
+ sharedResourceImplementation = new SharedResourceImplementation();
+ sharedResourceRunner = new SharedResourceRunner(sharedResourceImplementation);
sharedResourceRunner.start();
}
}
@@ -215,9 +212,9 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
sharedResourceRunner.stop();
sharedResourceRunner = null;
}
- if(null != sharedMap) {
- sharedMap.clear();
- sharedMap = null;
+ if(null != sharedResourceImplementation) {
+ sharedResourceImplementation.clear();
+ sharedResourceImplementation = null;
}
defaultDevice = null;
/**
@@ -231,15 +228,15 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
}
@Override
- public GLDynamicLookupHelper getGLDynamicLookupHelper(final String profileName) {
+ public final GLDynamicLookupHelper getGLDynamicLookupHelper(final int majorVersion, final int contextOptions) {
return windowsWGLDynamicLookupHelper;
}
/* pp */ static String toHexString(final long l) { return "0x"+Long.toHexString(l); }
private WindowsGraphicsDevice defaultDevice;
+ private SharedResourceImplementation sharedResourceImplementation;
private SharedResourceRunner sharedResourceRunner;
- private HashMap<String /*connection*/, SharedResourceRunner.Resource> sharedMap;
@Override
protected void enterThreadCriticalZone() {
@@ -300,26 +297,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
final boolean hasReadDrawable() { return hasARBReadDrawable; }
}
- class SharedResourceImplementation implements SharedResourceRunner.Implementation {
- @Override
- public void clear() {
- sharedMap.clear();
- }
- @Override
- public SharedResourceRunner.Resource mapPut(final AbstractGraphicsDevice device, final SharedResourceRunner.Resource resource) {
- return sharedMap.put(device.getConnection(), resource);
- }
- @Override
- public SharedResourceRunner.Resource mapGet(final AbstractGraphicsDevice device) {
- return sharedMap.get(device.getConnection());
- }
- @Override
- public Collection<SharedResourceRunner.Resource> mapValues() {
- synchronized(sharedMap) {
- return sharedMap.values();
- }
- }
-
+ class SharedResourceImplementation extends SharedResourceRunner.AImplementation {
@Override
public boolean isDeviceSupported(final AbstractGraphicsDevice device) {
return true;
@@ -465,6 +443,33 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
return null;
}
+ /**
+ * {@inheritDoc}
+ * <p>
+ * This factory always supports native desktop OpenGL profiles.
+ * </p>
+ */
+ @Override
+ public final boolean hasOpenGLDesktopSupport() { return true; }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * This factory never supports native GLES profiles.
+ * </p>
+ */
+ @Override
+ public final boolean hasOpenGLESSupport() { return false; }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Always returns true.
+ * </p>
+ */
+ @Override
+ public final boolean hasMajorMinorCreateContextARB() { return true; }
+
@Override
protected List<GLCapabilitiesImmutable> getAvailableCapabilitiesImpl(final AbstractGraphicsDevice device) {
return WindowsWGLGraphicsConfigurationFactory.getAvailableCapabilities(this, device);
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java
index f88718d1b..4ffe6e7d1 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java
@@ -171,24 +171,7 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
": error code " + GDI.GetLastError());
}
if( !caps.isBackgroundOpaque() ) {
- final long hwnd = GDI.WindowFromDC(hdc);
- final DWM_BLURBEHIND bb = DWM_BLURBEHIND.create();
- bb.setDwFlags(GDI.DWM_BB_ENABLE| GDI.DWM_BB_TRANSITIONONMAXIMIZED);
- bb.setFEnable( 1 );
- boolean ok = GDI.DwmEnableBlurBehindWindow(hwnd, bb);
- if( ok ) {
- final MARGINS m = MARGINS.create();
- m.setCxLeftWidth(-1);
- m.setCxRightWidth(-1);
- m.setCyBottomHeight(-1);
- m.setCyTopHeight(-1);
- ok = GDI.DwmExtendFrameIntoClientArea(hwnd, m);
- }
- if(DEBUG) {
- final boolean isUndecorated = GDIUtil.IsUndecorated(hwnd);
- final boolean isChild = GDIUtil.IsChild(hwnd);
- System.err.println("translucency enabled on wnd: 0x"+Long.toHexString(hwnd)+" - isUndecorated "+isUndecorated+", isChild "+isChild+", ok: "+ok);
- }
+ GDIUtil.DwmSetupTranslucency(GDI.WindowFromDC(hdc), true);
}
if (DEBUG) {
System.err.println("setPixelFormat: hdc "+toHexString(hdc) +", "+caps);
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
index 21eb6b8f3..99268f13f 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
@@ -56,6 +56,7 @@ import com.jogamp.common.nio.Buffers;
import com.jogamp.opengl.GLRendererQuirks;
import jogamp.nativewindow.windows.GDI;
+import jogamp.nativewindow.windows.GDIUtil;
import jogamp.nativewindow.windows.PIXELFORMATDESCRIPTOR;
import jogamp.opengl.GLDrawableImpl;
import jogamp.opengl.GLGraphicsConfigurationFactory;
@@ -349,7 +350,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
}
final GLCapabilitiesImmutable capsChosen = (GLCapabilitiesImmutable) config.getChosenCapabilities();
- final boolean isOpaque = capsChosen.isBackgroundOpaque() && GDI.DwmIsCompositionEnabled();
+ final boolean isOpaque = capsChosen.isBackgroundOpaque() && GDIUtil.DwmIsCompositionEnabled();
final int winattrbits = GLGraphicsConfigurationUtil.getExclusiveWinAttributeBits(capsChosen)
& ~GLGraphicsConfigurationUtil.BITMAP_BIT; // w/o BITMAP
final GLProfile glProfile = capsChosen.getGLProfile();
@@ -358,7 +359,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
if(DEBUG) {
System.err.println("updateGraphicsConfigurationARB: hdc "+toHexString(hdc)+", pfdIDCount(hdc) "+pfdIDCount+", capsChosen "+capsChosen+", "+GLGraphicsConfigurationUtil.winAttributeBits2String(null, winattrbits).toString());
- System.err.println("\tisOpaque "+isOpaque+" (translucency requested: "+(!capsChosen.isBackgroundOpaque())+", compositioning enabled: "+GDI.DwmIsCompositionEnabled()+")");
+ System.err.println("\tisOpaque "+isOpaque+" (translucency requested: "+(!capsChosen.isBackgroundOpaque())+", compositioning enabled: "+GDIUtil.DwmIsCompositionEnabled()+")");
final int pformatsNum = null != pformats ? pformats.length : -1;
System.err.println("\textHDC "+extHDC+", chooser "+(null!=chooser)+", pformatsNum "+pformatsNum);
}
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java
index 63b0b35c0..24f2ab8dd 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java
@@ -56,6 +56,7 @@ import jogamp.nativewindow.x11.X11Lib;
import jogamp.nativewindow.x11.X11Util;
import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLDrawableImpl;
+import jogamp.opengl.GLDynamicLookupHelper;
import jogamp.opengl.GLXExtensions;
import com.jogamp.common.ExceptionUtils;
@@ -72,7 +73,7 @@ public class X11GLXContext extends GLContextImpl {
// Table that holds the addresses of the native C-language entry points for
// GLX extension functions.
private GLXExtProcAddressTable glXExtProcAddressTable;
- /** 1 MESA, 2 SGI, 0 undefined, -1 none */
+ /** 3 SGI, 2 GLX_EXT_swap_control_tear, 1 GLX_EXT_swap_control, 0 undefined, -1 none */
private int hasSwapInterval = 0;
private int hasSwapGroupNV = 0;
@@ -224,17 +225,34 @@ public class X11GLXContext extends GLContextImpl {
@Override
protected long createContextARBImpl(final long share, final boolean direct, final int ctp, final int major, final int minor) {
- updateGLXProcAddressTable();
- final GLXExt _glXExt = getGLXExt();
if(DEBUG) {
System.err.println(getThreadName()+": X11GLXContext.createContextARBImpl: "+getGLVersion(major, minor, ctp, "@creation") +
- ", handle "+toHexString(drawable.getHandle()) + ", share "+toHexString(share)+", direct "+direct+
- ", glXCreateContextAttribsARB: "+toHexString(glXExtProcAddressTable._addressof_glXCreateContextAttribsARB));
+ ", handle "+toHexString(drawable.getHandle()) + ", share "+toHexString(share)+", direct "+direct);
}
-
+ final boolean ctDesktopGL = 0 == ( CTX_PROFILE_ES & ctp );
final boolean ctBwdCompat = 0 != ( CTX_PROFILE_COMPAT & ctp ) ;
final boolean ctFwdCompat = 0 != ( CTX_OPTION_FORWARD & ctp ) ;
final boolean ctDebug = 0 != ( CTX_OPTION_DEBUG & ctp ) ;
+ if( !ctDesktopGL ) {
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": X11GLXContext.createContextARBImpl: GL ES not avail "+getGLVersion(major, minor, ctp, "@creation"));
+ }
+ return 0; // n/a
+ }
+ final GLDynamicLookupHelper dlh = getGLDynamicLookupHelper(major, ctp);
+ if( null == dlh ) {
+ if(DEBUG) {
+ System.err.println(getThreadName()+" - X11GLXContext.createContextARBImpl: Null GLDynamicLookupHelper");
+ }
+ return 0;
+ } else {
+ updateGLXProcAddressTable(null, dlh);
+ }
+ final GLXExt _glXExt = getGLXExt();
+ if(DEBUG) {
+ System.err.println(getThreadName()+": X11GLXContext.createContextARBImpl: "+
+ ", glXCreateContextAttribsARB: "+toHexString(glXExtProcAddressTable._addressof_glXCreateContextAttribsARB));
+ }
final IntBuffer attribs = Buffers.newDirectIntBuffer(ctx_arb_attribs_rom);
attribs.put(ctx_arb_attribs_idx_major + 1, major);
@@ -322,6 +340,10 @@ public class X11GLXContext extends GLContextImpl {
"], fbCfg "+config.hasFBConfig()+" -> "+createContextARBAvailable+
"], shared "+sharedCreatedWithARB+"]");
}
+ if( glp.isGLES() ) {
+ throw new GLException(getThreadName()+": Unable to create OpenGL ES context on desktopDevice "+device+
+ ", config "+config+", "+glp+", shareWith "+toHexString(shareWithHandle));
+ }
if( !config.hasFBConfig() ) {
// not able to use FBConfig -> GLX 1.1
@@ -479,8 +501,17 @@ public class X11GLXContext extends GLContextImpl {
// Should check for X errors and raise GLException
}
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Ignoring {@code contextFQN}, using {@code GLX}+{@link AbstractGraphicsDevice#getUniqueID()}.
+ * </p>
+ */
@Override
- protected final void updateGLXProcAddressTable() {
+ protected final void updateGLXProcAddressTable(final String contextFQN, final GLDynamicLookupHelper dlh) {
+ if( null == dlh ) {
+ throw new GLException("No GLDynamicLookupHelper for "+this);
+ }
final AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration();
final AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice();
final String key = "GLX-"+adevice.getUniqueID();
@@ -498,7 +529,7 @@ public class X11GLXContext extends GLContextImpl {
}
} else {
glXExtProcAddressTable = new GLXExtProcAddressTable(new GLProcAddressResolver());
- resetProcAddressTable(getGLXExtProcAddressTable());
+ resetProcAddressTable(getGLXExtProcAddressTable(), dlh);
synchronized(mappedContextTypeObjectLock) {
mappedGLXProcAddress.put(key, getGLXExtProcAddressTable());
if(DEBUG) {
@@ -549,39 +580,67 @@ public class X11GLXContext extends GLContextImpl {
}
@Override
- protected boolean setSwapIntervalImpl(final int interval) {
- if( !drawable.getChosenGLCapabilities().isOnscreen() ) { return false; }
-
- final GLXExt glXExt = getGLXExt();
- if(0==hasSwapInterval) {
+ protected final Integer setSwapIntervalImpl2(final int interval) {
+ if( !drawable.getChosenGLCapabilities().isOnscreen() ) {
+ return null;
+ }
+ final long displayHandle = drawable.getNativeSurface().getDisplayHandle();
+ if( 0 == hasSwapInterval ) {
try {
- /** 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;
+ if ( isExtensionAvailable(GLXExtensions.GLX_EXT_swap_control) ) {
+ hasSwapInterval = 1;
+ if ( isExtensionAvailable(GLXExtensions.GLX_EXT_swap_control_tear) ) {
+ try {
+ final IntBuffer val = Buffers.newDirectIntBuffer(1);
+ GLX.glXQueryDrawable(displayHandle, drawable.getHandle(), GLX.GLX_LATE_SWAPS_TEAR_EXT, val);
+ if( 1 == val.get(0) ) {
+ hasSwapInterval = 2;
+ if(DEBUG) { System.err.println("X11GLXContext.setSwapInterval.2 using: "+GLXExtensions.GLX_EXT_swap_control_tear + ", " + GLXExtensions.GLX_EXT_swap_control_tear); }
+ } else if(DEBUG) {
+ System.err.println("X11GLXContext.setSwapInterval.2 n/a: "+GLXExtensions.GLX_EXT_swap_control_tear+", query: "+val.get(0));
+ }
+ } catch (final Throwable t) { if(DEBUG) { ExceptionUtils.dumpThrowable("", t); } }
+ }
+ if(DEBUG) {
+ if( 1 == hasSwapInterval ) {
+ System.err.println("X11GLXContext.setSwapInterval.1 using: "+GLXExtensions.GLX_EXT_swap_control);
+ }
+ }
+ } else if ( isExtensionAvailable(GLXExtensions.GLX_SGI_swap_control) ) {
+ hasSwapInterval = 3;
+ if(DEBUG) { System.err.println("X11GLXContext.setSwapInterval.3 using: "+GLXExtensions.GLX_SGI_swap_control); }
} else {
hasSwapInterval = -1;
+ if(DEBUG) { System.err.println("X11GLXContext.setSwapInterval.0 N/A"); }
}
- } catch (final Throwable t) { hasSwapInterval=-1; }
+ } catch (final Throwable t) { hasSwapInterval=-1; if(DEBUG) { ExceptionUtils.dumpThrowable("", t); } }
}
- /* try {
- switch( hasSwapInterval ) {
- case 1:
- return 0 == glXExt.glXSwapIntervalMESA(interval);
- case 2:
- return 0 == glXExt.glXSwapIntervalSGI(interval);
+ if (3 == hasSwapInterval) {
+ final int useInterval;
+ if( 0 > interval ) {
+ useInterval = Math.abs(interval);
+ } else {
+ useInterval = interval;
+ }
+ try {
+ final GLXExt glXExt = getGLXExt();
+ if( 0 == glXExt.glXSwapIntervalSGI(useInterval) ) {
+ return Integer.valueOf(useInterval);
+ }
+ } catch (final Throwable t) { hasSwapInterval=-1; if(DEBUG) { ExceptionUtils.dumpThrowable("", t); } }
+ } else if ( 0 < hasSwapInterval ) { // 2 || 1
+ final int useInterval;
+ if( 1 == hasSwapInterval && 0 > interval ) {
+ useInterval = Math.abs(interval);
+ } else {
+ useInterval = interval;
}
- } catch (Throwable t) { hasSwapInterval = -1; } */
- if (2 == hasSwapInterval) {
try {
- return 0 == glXExt.glXSwapIntervalSGI(interval);
- } catch (final Throwable t) { hasSwapInterval=-1; }
+ GLX.glXSwapIntervalEXT(displayHandle, drawable.getHandle(), useInterval);
+ return Integer.valueOf(useInterval);
+ } catch (final Throwable t) { hasSwapInterval=-1; if(DEBUG) { ExceptionUtils.dumpThrowable("", t); } }
}
- return false;
+ return null;
}
private final int initSwapGroupImpl(final GLXExt glXExt) {
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
index ecaf20d86..a03ce1641 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
@@ -41,8 +41,6 @@ import java.nio.Buffer;
import java.nio.ShortBuffer;
import java.security.AccessController;
import java.security.PrivilegedAction;
-import java.util.Collection;
-import java.util.HashMap;
import java.util.List;
import com.jogamp.nativewindow.AbstractGraphicsConfiguration;
@@ -126,11 +124,10 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
// The act of constructing them causes them to be registered
X11GLXGraphicsConfigurationFactory.registerFactory();
- sharedMap = new HashMap<String, SharedResourceRunner.Resource>();
-
// Init shared resources off thread
// Will be released via ShutdownHook
- sharedResourceRunner = new SharedResourceRunner(new SharedResourceImplementation());
+ sharedResourceImplementation = new SharedResourceImplementation();
+ sharedResourceRunner = new SharedResourceRunner(sharedResourceImplementation);
sharedResourceRunner.start();
}
}
@@ -149,9 +146,9 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
sharedResourceRunner.stop();
sharedResourceRunner = null;
}
- if(null != sharedMap) {
- sharedMap.clear();
- sharedMap = null;
+ if(null != sharedResourceImplementation) {
+ sharedResourceImplementation.clear();
+ sharedResourceImplementation = null;
}
defaultDevice = null;
/**
@@ -163,13 +160,13 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
}
@Override
- public final GLDynamicLookupHelper getGLDynamicLookupHelper(final String profileName) {
+ public final GLDynamicLookupHelper getGLDynamicLookupHelper(final int majorVersion, final int contextOptions) {
return x11GLXDynamicLookupHelper;
}
private X11GraphicsDevice defaultDevice;
+ private SharedResourceImplementation sharedResourceImplementation;
private SharedResourceRunner sharedResourceRunner;
- private HashMap<String /* connection */, SharedResourceRunner.Resource> sharedMap;
static class SharedResource implements SharedResourceRunner.Resource {
private final String glXServerVendorName;
@@ -226,24 +223,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
final boolean isGLXMultisampleAvailable() { return glXMultisampleAvailable; }
}
- class SharedResourceImplementation implements SharedResourceRunner.Implementation {
- @Override
- public void clear() {
- sharedMap.clear();
- }
- @Override
- public SharedResourceRunner.Resource mapPut(final AbstractGraphicsDevice device, final SharedResourceRunner.Resource resource) {
- return sharedMap.put(device.getConnection(), resource);
- }
- @Override
- public SharedResourceRunner.Resource mapGet(final AbstractGraphicsDevice device) {
- return sharedMap.get(device.getConnection());
- }
- @Override
- public Collection<SharedResourceRunner.Resource> mapValues() {
- return sharedMap.values();
- }
-
+ class SharedResourceImplementation extends SharedResourceRunner.AImplementation {
@Override
public boolean isDeviceSupported(final AbstractGraphicsDevice device) {
final boolean res;
@@ -399,6 +379,33 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
return 0;
}
+ /**
+ * {@inheritDoc}
+ * <p>
+ * This factory always supports native desktop OpenGL profiles.
+ * </p>
+ */
+ @Override
+ public final boolean hasOpenGLDesktopSupport() { return true; }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * This factory never supports native GLES profiles.
+ * </p>
+ */
+ @Override
+ public final boolean hasOpenGLESSupport() { return false; }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Always returns true.
+ * </p>
+ */
+ @Override
+ public final boolean hasMajorMinorCreateContextARB() { return true; }
+
@Override
protected List<GLCapabilitiesImmutable> getAvailableCapabilitiesImpl(final AbstractGraphicsDevice device) {
return X11GLXGraphicsConfigurationFactory.getAvailableCapabilities(this, device);
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java
index 86349b645..8f7d710cd 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java
@@ -275,21 +275,6 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
return val;
}
- static XRenderDirectFormat XVisual2XRenderMask(final long dpy, final long visual) {
- final XRenderPictFormat renderPictFmt = X11Lib.XRenderFindVisualFormat(dpy, visual);
- if(null == renderPictFmt) {
- return null;
- }
- return renderPictFmt.getDirect();
- }
- static XRenderDirectFormat XVisual2XRenderMask(final long dpy, final long visual, final XRenderPictFormat dest) {
- if( !X11Lib.XRenderFindVisualFormat(dpy, visual, dest) ) {
- return null;
- } else {
- return dest.getDirect();
- }
- }
-
static X11GLCapabilities GLXFBConfig2GLCapabilities(final X11GraphicsDevice device, final GLProfile glp, final long fbcfg,
final int winattrmask, final boolean isMultisampleAvailable) {
final IntBuffer tmp = Buffers.newDirectIntBuffer(1);
diff --git a/src/jogl/native/GLDebugMessageHandler.c b/src/jogl/native/GLDebugMessageHandler.c
index 5c18b94b1..e524df9bf 100644
--- a/src/jogl/native/GLDebugMessageHandler.c
+++ b/src/jogl/native/GLDebugMessageHandler.c
@@ -17,6 +17,7 @@
#define DBG_PRINT(...)
#endif
+// Note: 'ARB' is also used for 'KHR'!
static jmethodID glDebugMessageARB = NULL; // int source, int type, int id, int severity, String msg
static jmethodID glDebugMessageAMD = NULL; // int id, int category, int severity, String msg
@@ -120,7 +121,8 @@ JNIEXPORT jlong JNICALL Java_jogamp_opengl_GLDebugMessageHandler_register0
handle->extType = extType;
DBG_PRINT("GLDebugMessageHandler.register0: jobject %p, extType %d\n", (void*)handle->obj, handle->extType);
- if(jogamp_opengl_GLDebugMessageHandler_EXT_ARB == extType) {
+ if(jogamp_opengl_GLDebugMessageHandler_EXT_KHR == extType ||
+ jogamp_opengl_GLDebugMessageHandler_EXT_ARB == extType) {
_local_PFNGLDEBUGMESSAGECALLBACKARBPROC ptr_glDebugMessageCallbackARB;
ptr_glDebugMessageCallbackARB = (_local_PFNGLDEBUGMESSAGECALLBACKARBPROC) (intptr_t) procAddress;
ptr_glDebugMessageCallbackARB((_local_GLDEBUGPROCARB)GLDebugMessageARBCallback, handle);
@@ -151,7 +153,8 @@ JNIEXPORT void JNICALL Java_jogamp_opengl_GLDebugMessageHandler_unregister0
JoglCommon_throwNewRuntimeException(env, "wrong handle (obj doesn't match)");
}
- if(jogamp_opengl_GLDebugMessageHandler_EXT_ARB == handle->extType) {
+ if(jogamp_opengl_GLDebugMessageHandler_EXT_KHR == handle->extType ||
+ jogamp_opengl_GLDebugMessageHandler_EXT_ARB == handle->extType) {
_local_PFNGLDEBUGMESSAGECALLBACKARBPROC ptr_glDebugMessageCallbackARB;
ptr_glDebugMessageCallbackARB = (_local_PFNGLDEBUGMESSAGECALLBACKARBPROC) (intptr_t) procAddress;
ptr_glDebugMessageCallbackARB((_local_GLDEBUGPROCARB)NULL, NULL);
diff --git a/src/jogl/native/libav/ffmpeg_impl_template.c b/src/jogl/native/libav/ffmpeg_impl_template.c
index ca283ef52..d02770eb7 100644
--- a/src/jogl/native/libav/ffmpeg_impl_template.c
+++ b/src/jogl/native/libav/ffmpeg_impl_template.c
@@ -622,6 +622,7 @@ static const char * inFmtNames[] = {
"video4linux", // linux (old)
"dshow", // windows
"vfwcap", // windows (old)
+ "avfoundation", // osx
"mpg",
"yuv2",
"mjpeg",
@@ -732,6 +733,9 @@ JNIEXPORT void JNICALL FF_FUNC(setStream0)
fprintf(stderr, "Camera %d not found\n", devIdx);
}
}
+ if(pAV->verbose) {
+ fprintf(stderr, "Camera: Filename: %s\n", filename);
+ }
const char *sizeS = NULL != jSizeS ? (*env)->GetStringUTFChars(env, jSizeS, &iscopy) : NULL;
int hasSize = 0;
@@ -756,6 +760,7 @@ JNIEXPORT void JNICALL FF_FUNC(setStream0)
}
sp_av_dict_set(&inOpts, "framerate", buffer, 0);
}
+ // FIXME pre-select: sp_av_dict_set(&inOpts, "pixel_format", "yuyv422", 0);
}
MY_MUTEX_LOCK(env, mutex_avcodec_openclose);
@@ -1148,8 +1153,10 @@ JNIEXPORT void JNICALL FF_FUNC(setStream0)
#endif
} else {
vLinesize[0] = pAV->pVFrame->linesize[0];
- if( pAV->vPixFmt == PIX_FMT_YUYV422 ) {
- // Stuff 2x 16bpp (YUYV) into one RGBA pixel!
+ if( pAV->vPixFmt == PIX_FMT_YUYV422 ||
+ pAV->vPixFmt == PIX_FMT_UYVY422 )
+ {
+ // Stuff 2x 16bpp (YUYV, UYVY) into one RGBA pixel!
pAV->vTexWidth[0] = pAV->pVCodecCtx->width / 2;
} else {
pAV->vTexWidth[0] = pAV->pVCodecCtx->width;
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/DefaultGraphicsDevice.java b/src/nativewindow/classes/com/jogamp/nativewindow/DefaultGraphicsDevice.java
index 070b6bb28..56c196132 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/DefaultGraphicsDevice.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/DefaultGraphicsDevice.java
@@ -45,6 +45,23 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
protected ToolkitLock toolkitLock;
/**
+ * Return the default display connection for the given windowing toolkit type
+ * gathered via {@link NativeWindowFactory#getDefaultDisplayConnection()}.
+ * @param type
+ */
+ public static String getDefaultDisplayConnection() {
+ return NativeWindowFactory.getDefaultDisplayConnection();
+ }
+ /**
+ * Return the default display connection for the given windowing toolkit type
+ * gathered via {@link NativeWindowFactory#getDefaultDisplayConnection(String)}.
+ * @param type
+ */
+ public static String getDefaultDisplayConnection(final String type) {
+ return NativeWindowFactory.getDefaultDisplayConnection(type);
+ }
+
+ /**
* Create an instance with the system default {@link ToolkitLock},
* gathered via {@link NativeWindowFactory#getDefaultToolkitLock(String)}.
* @param type
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/DefaultGraphicsScreen.java b/src/nativewindow/classes/com/jogamp/nativewindow/DefaultGraphicsScreen.java
index 63c79af55..cbf3e22da 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/DefaultGraphicsScreen.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/DefaultGraphicsScreen.java
@@ -42,7 +42,7 @@ public class DefaultGraphicsScreen implements Cloneable, AbstractGraphicsScreen
}
public static AbstractGraphicsScreen createDefault(final String type) {
- return new DefaultGraphicsScreen(new DefaultGraphicsDevice(type, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT), 0);
+ return new DefaultGraphicsScreen(new DefaultGraphicsDevice(type, DefaultGraphicsDevice.getDefaultDisplayConnection(type), AbstractGraphicsDevice.DEFAULT_UNIT), 0);
}
@Override
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowException.java b/src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowException.java
index 8f841e7ea..9dc3f2d4b 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowException.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowException.java
@@ -42,6 +42,7 @@ package com.jogamp.nativewindow;
/** A generic exception for OpenGL errors used throughout the binding
as a substitute for {@link RuntimeException}. */
+@SuppressWarnings("serial")
public class NativeWindowException extends RuntimeException {
/** Constructs a NativeWindowException object. */
public NativeWindowException() {
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowFactory.java b/src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowFactory.java
index d01e3a203..323bc8c86 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowFactory.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowFactory.java
@@ -33,7 +33,6 @@
package com.jogamp.nativewindow;
-import java.io.File;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedAction;
@@ -43,9 +42,11 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import com.jogamp.nativewindow.util.Point;
import com.jogamp.nativewindow.util.PointImmutable;
import jogamp.common.os.PlatformPropsImpl;
+import jogamp.nativewindow.BcmVCArtifacts;
import jogamp.nativewindow.Debug;
import jogamp.nativewindow.NativeWindowFactoryImpl;
import jogamp.nativewindow.ToolkitProperties;
@@ -54,13 +55,16 @@ import jogamp.nativewindow.WrappedWindow;
import jogamp.nativewindow.macosx.OSXUtil;
import jogamp.nativewindow.windows.GDIUtil;
import jogamp.nativewindow.x11.X11Lib;
+import jogamp.nativewindow.x11.X11Util;
import com.jogamp.common.os.Platform;
+import com.jogamp.common.util.InterruptSource;
import com.jogamp.common.util.PropertyAccess;
import com.jogamp.common.util.ReflectionUtil;
import com.jogamp.nativewindow.UpstreamWindowHookMutableSizePos;
import com.jogamp.nativewindow.awt.AWTGraphicsDevice;
import com.jogamp.nativewindow.awt.AWTGraphicsScreen;
+import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
import com.jogamp.nativewindow.macosx.MacOSXGraphicsDevice;
import com.jogamp.nativewindow.windows.WindowsGraphicsDevice;
import com.jogamp.nativewindow.x11.X11GraphicsDevice;
@@ -79,28 +83,28 @@ public abstract class NativeWindowFactory {
protected static final boolean DEBUG;
/** OpenKODE/EGL type, as retrieved with {@link #getNativeWindowType(boolean)}. String is canonical via {@link String#intern()}.*/
- public static final String TYPE_EGL = ".egl".intern();
+ public static final String TYPE_EGL = ".egl";
/** Microsoft Windows type, as retrieved with {@link #getNativeWindowType(boolean)}. String is canonical via {@link String#intern()}. */
- public static final String TYPE_WINDOWS = ".windows".intern();
+ public static final String TYPE_WINDOWS = ".windows";
/** X11 type, as retrieved with {@link #getNativeWindowType(boolean)}. String is canonical via {@link String#intern()}. */
- public static final String TYPE_X11 = ".x11".intern();
+ public static final String TYPE_X11 = ".x11";
/** 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();
+ public static final String TYPE_BCM_VC_IV = ".bcm.vc.iv";
/** Android/EGL type, as retrieved with {@link #getNativeWindowType(boolean)}. String is canonical via {@link String#intern()}.*/
- public static final String TYPE_ANDROID = ".android".intern();
+ public static final String TYPE_ANDROID = ".android";
/** 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();
+ public static final String TYPE_MACOSX = ".macosx";
/** Generic AWT type, as retrieved with {@link #getNativeWindowType(boolean)}. String is canonical via {@link String#intern()}. */
- public static final String TYPE_AWT = ".awt".intern();
+ public static final String TYPE_AWT = ".awt";
/** 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();
+ public static final String TYPE_DEFAULT = ".default";
private static final String nativeWindowingTypePure; // canonical String via String.intern()
private static final String nativeWindowingTypeCustom; // canonical String via String.intern()
@@ -133,20 +137,6 @@ public abstract class NativeWindowFactory {
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");
- @Override
- public Boolean run() {
- if ( vcliblocation.isFile() ) {
- return Boolean.TRUE;
- }
- return Boolean.FALSE;
- }
- } ).booleanValue();
- }
-
private static String _getNativeWindowingType() {
switch(PlatformPropsImpl.OS_TYPE) {
case ANDROID:
@@ -163,7 +153,7 @@ public abstract class NativeWindowFactory {
case SUNOS:
case HPUX:
default:
- if( guessBroadcomVCIV() ) {
+ if( BcmVCArtifacts.guessVCIVUsed() ) {
return TYPE_BCM_VC_IV;
}
return TYPE_X11;
@@ -181,7 +171,7 @@ public abstract class NativeWindowFactory {
_DEBUG[0] = Debug.debug("NativeWindow");
_tmp[0] = PropertyAccess.getProperty("nativewindow.ws.name", true);
Runtime.getRuntime().addShutdownHook(
- new Thread(new Runnable() {
+ new InterruptSource.Thread(null, new Runnable() {
@Override
public void run() {
NativeWindowFactory.shutdown(true);
@@ -647,6 +637,17 @@ public abstract class NativeWindowFactory {
VisualIDHolder.VID_UNDEFINED != visualID ;
}
+ public static String getDefaultDisplayConnection() {
+ return getDefaultDisplayConnection(NativeWindowFactory.getNativeWindowType(true));
+ }
+ public static String getDefaultDisplayConnection(final String nwt) {
+ if(NativeWindowFactory.TYPE_X11 == nwt) {
+ return X11Util.getNullDisplayName();
+ } else {
+ return AbstractGraphicsDevice.DEFAULT_CONNECTION;
+ }
+ }
+
/**
* Creates a native device type, following {@link #getNativeWindowType(boolean) getNativeWindowType(true)}.
* <p>
@@ -673,11 +674,32 @@ public abstract class NativeWindowFactory {
return new X11GraphicsDevice(displayConnection, AbstractGraphicsDevice.DEFAULT_UNIT);
}
} else if( NativeWindowFactory.TYPE_WINDOWS == nwt ) {
- return new WindowsGraphicsDevice(AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
+ return new WindowsGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT);
} else if( NativeWindowFactory.TYPE_MACOSX == nwt ) {
return new MacOSXGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT);
} else if( NativeWindowFactory.TYPE_EGL == nwt ) {
- throw new UnsupportedOperationException("n/a for windowing system: "+nwt);
+ final EGLGraphicsDevice device;
+ if( own ) {
+ Object odev = null;
+ try {
+ // EGLDisplayUtil.eglCreateEGLGraphicsDevice(EGL.EGL_DEFAULT_DISPLAY, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
+ odev = ReflectionUtil.callStaticMethod("jogamp.opengl.egl.EGLDisplayUtil", "eglCreateEGLGraphicsDevice",
+ new Class<?>[] { Long.class, String.class, Integer.class},
+ new Object[] { 0L /* EGL.EGL_DEFAULT_DISPLAY */, DefaultGraphicsDevice.getDefaultDisplayConnection(nwt), AbstractGraphicsDevice.DEFAULT_UNIT },
+ NativeWindowFactory.class.getClassLoader());
+ } catch (final Exception e) {
+ throw new NativeWindowException("EGLDisplayUtil.eglCreateEGLGraphicsDevice failed", e);
+ }
+ if( odev instanceof EGLGraphicsDevice ) {
+ device = (EGLGraphicsDevice)odev;
+ device.open();
+ } else {
+ throw new NativeWindowException("EGLDisplayUtil.eglCreateEGLGraphicsDevice failed");
+ }
+ } else {
+ device = new EGLGraphicsDevice(0, 0 /* EGL.EGL_NO_DISPLAY */, displayConnection, AbstractGraphicsDevice.DEFAULT_UNIT, null);
+ }
+ return device;
} else if( NativeWindowFactory.TYPE_AWT == nwt ) {
throw new UnsupportedOperationException("n/a for windowing system: "+nwt);
} else {
@@ -712,7 +734,7 @@ public abstract class NativeWindowFactory {
* FIXME: Bug 973 Needs service provider interface (SPI) for TK dependent implementation
* </p>
*/
- public static PointImmutable getLocationOnScreen(final NativeWindow nw) {
+ public static Point getLocationOnScreen(final NativeWindow nw) {
final String nwt = NativeWindowFactory.getNativeWindowType(true);
if( NativeWindowFactory.TYPE_X11 == nwt ) {
return X11Lib.GetRelativeLocation(nw.getDisplayHandle(), nw.getScreenIndex(), nw.getWindowHandle(), 0, 0, 0);
@@ -731,6 +753,4 @@ public abstract class NativeWindowFactory {
}
throw new UnsupportedOperationException("n/a for windowing system: "+nwt);
}
-
-
}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowHolder.java b/src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowHolder.java
new file mode 100644
index 000000000..8cf9bcb1a
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowHolder.java
@@ -0,0 +1,41 @@
+/**
+ * Copyright 2019 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.nativewindow;
+
+/**
+ * Accessor interface for implementing classes with ownership of a {@link NativeWindow}
+ * via an <i>is-a</i> or <i>has-a</i> relation.
+ */
+public interface NativeWindowHolder extends NativeSurfaceHolder {
+ /**
+ * Returns the associated {@link NativeWindow} of this {@link NativeWindowHolder}, which is identical to {@link #getNativeSurface()}
+ */
+ public NativeWindow getNativeWindow();
+}
+
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTGraphicsConfiguration.java b/src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTGraphicsConfiguration.java
index cc70b6b7b..84fce7fc9 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTGraphicsConfiguration.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTGraphicsConfiguration.java
@@ -73,27 +73,6 @@ public class AWTGraphicsConfiguration extends DefaultGraphicsConfiguration imple
}
/**
- * @deprecated Use {@link #create(GraphicsConfiguration, CapabilitiesImmutable, CapabilitiesImmutable)}
- * Method constructs a new {@link AWTGraphicsConfiguration} primarily based
- * on the given {@link Component}'s {@link GraphicsConfiguration}.
- * @param awtComp the {@link Component}, which {@link GraphicsConfiguration} is used for the resulting {@link AWTGraphicsConfiguration}
- * @param capsChosen if null, <code>capsRequested</code> is copied and aligned
- * with the graphics {@link Capabilities} of the AWT Component to produce the chosen {@link Capabilities}.
- * Otherwise the <code>capsChosen</code> is used.
- * @param capsRequested if null, default {@link Capabilities} are used, otherwise the given values.
- */
- public static AWTGraphicsConfiguration create(final Component awtComp, final CapabilitiesImmutable capsChosen, final CapabilitiesImmutable capsRequested) {
- if(null==awtComp) {
- throw new IllegalArgumentException("Null AWT Component");
- }
- final GraphicsConfiguration gc = awtComp.getGraphicsConfiguration();
- if( null == gc ) {
- throw new NativeWindowException("Null AWT GraphicsConfiguration @ "+awtComp);
- }
- return create(gc, capsChosen, capsRequested);
- }
-
- /**
* Method constructs a new {@link AWTGraphicsConfiguration} primarily based
* on the given {@link GraphicsConfiguration}.
* @param gc the {@link GraphicsConfiguration} for the resulting {@link AWTGraphicsConfiguration}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/awt/AppContextInfo.java b/src/nativewindow/classes/com/jogamp/nativewindow/awt/AppContextInfo.java
index 2026ada0f..e5dcfa1c0 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/awt/AppContextInfo.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/awt/AppContextInfo.java
@@ -97,24 +97,23 @@ public class AppContextInfo {
* The resulting thread name will have either '-OnAppContextTG' or '-OnSystemTG' appended
* @return the {@link Thread} used to invoke the <code>runnable</code>, which may be the current {@link Thread} or a newly created one, see above.
*/
- public Thread invokeOnAppContextThread(final boolean waitUntilDone, final Runnable runnable, final String threadBaseName) {
- final Thread t;
+ public RunnableTask invokeOnAppContextThread(final boolean waitUntilDone, final Runnable runnable, final String threadBaseName) {
+ final RunnableTask rt;
if( update("invoke") ) {
- t = Thread.currentThread();
+ rt = RunnableTask.invokeOnCurrentThread(runnable);
if( DEBUG ) {
- System.err.println("Bug 1004: Invoke.0 on current AppContext thread: "+t+" "+toHexString(t.hashCode()));
+ System.err.println("Bug 1004: Invoke.0 on current AppContext: "+rt);
}
- runnable.run();
} else {
final ThreadGroup tg = getCachedThreadGroup();
final String tName = threadBaseName + ( null != tg ? "-OnAppContextTG" : "-OnSystemTG" );
- t = RunnableTask.invokeOnNewThread(tg, waitUntilDone, runnable, tName);
+ rt = RunnableTask.invokeOnNewThread(tg, tName, waitUntilDone, runnable);
if( DEBUG ) {
final int tgHash = null != tg ? tg.hashCode() : 0;
- System.err.println("Bug 1004: Invoke.1 on new AppContext thread: "+t+" "+toHexString(t.hashCode())+", tg "+tg+" "+toHexString(tgHash));
+ System.err.println("Bug 1004: Invoke.1 on new AppContext: "+rt+", tg "+tg+" "+toHexString(tgHash));
}
}
- return t;
+ return rt;
}
/**
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java b/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java
index 5d84325de..71a7602e6 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java
@@ -120,7 +120,7 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
*/
protected JAWTWindow(final Object comp, final AbstractGraphicsConfiguration config) {
if (config == null) {
- throw new NativeWindowException("Error: AbstractGraphicsConfiguration is null");
+ throw new IllegalArgumentException("Error: AbstractGraphicsConfiguration is null");
}
if(! ( config instanceof AWTGraphicsConfiguration ) ) {
throw new NativeWindowException("Error: AbstractGraphicsConfiguration is not an AWTGraphicsConfiguration: "+config);
@@ -132,9 +132,13 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
this.awtConfig = (AWTGraphicsConfiguration) config;
this.isApplet = false;
this.offscreenSurfaceLayer = 0;
+ if(DEBUG) {
+ System.err.println(jawtStr2("ctor"));
+ }
}
private static String id(final Object obj) { return ( null!=obj ? toHexString(obj.hashCode()) : "nil" ); }
- private String jawtStr() { return "JAWTWindow["+id(JAWTWindow.this)+"]"; }
+ private String jawtStr1() { return "JAWTWindow["+id(JAWTWindow.this)+"]"; }
+ private String jawtStr2(final String sub) { return jawtStr1()+"."+sub+" @ Thread "+getThreadName(); }
private class JAWTComponentListener implements ComponentListener, HierarchyListener {
private volatile boolean isShowing;
@@ -180,7 +184,7 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
public void run() {
isShowing = component.isShowing(); // Bug 1161: Runnable might be deferred, hence need to update
if(DEBUG) {
- System.err.println(jawtStr()+".attach @ Thread "+getThreadName()+": "+JAWTComponentListener.this.toString());
+ System.err.println(jawtStr2("attach")+": "+JAWTComponentListener.this.toString());
}
component.addComponentListener(JAWTComponentListener.this);
component.addHierarchyListener(JAWTComponentListener.this);
@@ -192,7 +196,7 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
@Override
public void run() {
if(DEBUG) {
- System.err.println(jawtStr()+".detach @ Thread "+getThreadName()+": "+JAWTComponentListener.this.toString());
+ System.err.println(jawtStr2("detach")+": "+JAWTComponentListener.this.toString());
}
component.removeComponentListener(JAWTComponentListener.this);
component.removeHierarchyListener(JAWTComponentListener.this);
@@ -202,7 +206,7 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
@Override
public final void componentResized(final ComponentEvent e) {
if(DEBUG) {
- System.err.println(jawtStr()+".componentResized: "+s(e));
+ System.err.println(jawtStr2("componentResized")+": "+s(e));
}
layoutSurfaceLayerIfEnabled(isShowing);
}
@@ -210,7 +214,7 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
@Override
public final void componentMoved(final ComponentEvent e) {
if(DEBUG) {
- System.err.println(jawtStr()+".componentMoved: "+s(e));
+ System.err.println(jawtStr2("componentMoved")+": "+s(e));
}
layoutSurfaceLayerIfEnabled(isShowing);
}
@@ -218,7 +222,7 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
@Override
public final void componentShown(final ComponentEvent e) {
if(DEBUG) {
- System.err.println(jawtStr()+".componentShown: "+s(e));
+ System.err.println(jawtStr2("componentShown")+": "+s(e));
}
layoutSurfaceLayerIfEnabled(isShowing);
}
@@ -226,7 +230,7 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
@Override
public final void componentHidden(final ComponentEvent e) {
if(DEBUG) {
- System.err.println(jawtStr()+".componentHidden: "+s(e));
+ System.err.println(jawtStr2("componentHidden")+": "+s(e));
}
layoutSurfaceLayerIfEnabled(isShowing);
}
@@ -248,7 +252,7 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
final java.awt.Component changed = e.getChanged();
final boolean displayable = changed.isDisplayable();
final boolean showing = changed.isShowing();
- System.err.println(jawtStr()+".hierarchyChanged: action "+action+", displayable "+displayable+", showing [changed "+showing+", comp "+wasShowing+" -> "+isShowing+"], "+s(e));
+ System.err.println(jawtStr2("hierarchyChanged")+": action "+action+", displayable "+displayable+", showing [changed "+showing+", comp "+wasShowing+" -> "+isShowing+"], "+s(e));
}
}
}
@@ -257,7 +261,7 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
protected synchronized void invalidate() {
if(DEBUG) {
- System.err.println(jawtStr()+".invalidate() - "+jawtComponentListener.toString());
+ System.err.println(jawtStr2("invalidate")+" - "+jawtComponentListener.toString());
if( isSurfaceLayerAttached() ) {
System.err.println("OffscreenSurfaceLayer still attached: 0x"+Long.toHexString(offscreenSurfaceLayer));
}
@@ -295,9 +299,12 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
*/
public final void setAWTGraphicsConfiguration(final AWTGraphicsConfiguration config) {
if(DEBUG) {
- System.err.println(jawtStr()+".setAWTGraphicsConfiguration(): "+this.awtConfig+" -> "+config);
+ System.err.println(jawtStr2("setAWTGraphicsConfiguration")+": "+this.awtConfig+" -> "+config);
// Thread.dumpStack();
}
+ if( null == awtConfig ) {
+ throw new IllegalArgumentException(jawtStr2("")+": null config");
+ }
this.awtConfig = config;
}
/**
@@ -395,26 +402,6 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
return hasPixelScaleChanged;
}
}
- /**
- * @deprecated Use {@link #updatePixelScale(GraphicsConfiguration, boolean)}.
- */
- public final boolean updatePixelScale(final boolean clearFlag) {
- return updatePixelScale(awtConfig.getAWTGraphicsConfiguration(), clearFlag);
- }
-
- /**
- * @deprecated Use {@link #updateLockedData(JAWT_Rectangle, GraphicsConfiguration)}.
- */
- protected final boolean updateLockedData(final JAWT_Rectangle jawtBounds) {
- throw new RuntimeException("Invalid API entry");
- }
- /**
- * @deprecated Use {@link #lockSurfaceImpl(GraphicsConfiguration)}
- */
- protected int lockSurfaceImpl() throws NativeWindowException {
- throw new RuntimeException("Invalid API entry");
- }
-
/**
* Returns and clears the {@code hasPixelScaleChanged} flag, as set via {@link #lockSurface()}.
@@ -771,6 +758,9 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
@Override
public final AbstractGraphicsConfiguration getGraphicsConfiguration() {
+ if( null == awtConfig ) {
+ throw new NativeWindowException(jawtStr2("")+": null awtConfig, invalidated");
+ }
return awtConfig.getNativeGraphicsConfiguration();
}
@@ -826,7 +816,7 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
surfaceLock.lock();
try {
if(DEBUG) {
- System.err.println(jawtStr()+".destroy @ Thread "+getThreadName());
+ System.err.println(jawtStr2("destroy"));
}
jawtComponentListener.detach();
invalidate();
@@ -930,7 +920,7 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
public String toString() {
final StringBuilder sb = new StringBuilder();
- sb.append(jawtStr()+"[");
+ sb.append(jawtStr1()+"[");
jawt2String(sb);
sb.append( ", shallUseOffscreenLayer "+shallUseOffscreenLayer+", isOffscreenLayerSurface "+isOffscreenLayerSurface+
", attachedSurfaceLayer "+toHexString(getAttachedSurfaceLayer())+
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java b/src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java
index 04d304cd5..320c0ec75 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java
@@ -32,9 +32,11 @@
package com.jogamp.nativewindow.egl;
-import com.jogamp.nativewindow.*;
-
import com.jogamp.common.util.VersionNumber;
+import com.jogamp.nativewindow.AbstractGraphicsDevice;
+import com.jogamp.nativewindow.DefaultGraphicsDevice;
+import com.jogamp.nativewindow.NativeWindowException;
+import com.jogamp.nativewindow.NativeWindowFactory;
/** Encapsulates a graphics device on EGL platforms.
*/
@@ -73,11 +75,23 @@ public class EGLGraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
* This constructor exist to setup a default device connection/unit.<br>
*/
public EGLGraphicsDevice() {
- super(NativeWindowFactory.TYPE_EGL, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
+ super(NativeWindowFactory.TYPE_EGL, DefaultGraphicsDevice.getDefaultDisplayConnection(), AbstractGraphicsDevice.DEFAULT_UNIT);
this.nativeDisplayID[0] = 0 ; // EGL.EGL_DEFAULT_DISPLAY
this.eglLifecycleCallback = null;
}
+ public EGLGraphicsDevice(final AbstractGraphicsDevice aDevice, final long eglDisplay, final EGLDisplayLifecycleCallback eglLifecycleCallback) {
+ super(NativeWindowFactory.TYPE_EGL, aDevice.getConnection(), aDevice.getUnitID(), eglDisplay);
+ final long nativeDisplayID;
+ if( aDevice instanceof EGLGraphicsDevice ) {
+ nativeDisplayID = ((EGLGraphicsDevice)aDevice).getNativeDisplayID();
+ } else {
+ nativeDisplayID = aDevice.getHandle();
+ }
+ this.nativeDisplayID[0] = nativeDisplayID;
+ this.eglLifecycleCallback = eglLifecycleCallback;
+ }
+
public EGLGraphicsDevice(final long nativeDisplayID, final long eglDisplay, final String connection, final int unitID, final EGLDisplayLifecycleCallback eglLifecycleCallback) {
super(NativeWindowFactory.TYPE_EGL, connection, unitID, eglDisplay);
this.nativeDisplayID[0] = nativeDisplayID;
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/javafx/JFXAccessor.java b/src/nativewindow/classes/com/jogamp/nativewindow/javafx/JFXAccessor.java
new file mode 100644
index 000000000..bffabdd5a
--- /dev/null
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/javafx/JFXAccessor.java
@@ -0,0 +1,291 @@
+/**
+ * Copyright 2019 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.nativewindow.javafx;
+
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import com.jogamp.nativewindow.AbstractGraphicsDevice;
+import com.jogamp.nativewindow.AbstractGraphicsScreen;
+import com.jogamp.nativewindow.NativeWindowException;
+import com.jogamp.nativewindow.NativeWindowFactory;
+import com.jogamp.nativewindow.VisualIDHolder;
+import com.jogamp.nativewindow.macosx.MacOSXGraphicsDevice;
+import com.jogamp.nativewindow.windows.WindowsGraphicsDevice;
+import com.jogamp.nativewindow.x11.X11GraphicsDevice;
+import com.jogamp.common.ExceptionUtils;
+import com.jogamp.common.util.InterruptedRuntimeException;
+import com.jogamp.common.util.ReflectionUtil;
+import com.jogamp.common.util.RunnableTask;
+import com.sun.javafx.tk.TKStage;
+
+import javafx.application.Platform;
+import javafx.stage.Window;
+import jogamp.nativewindow.Debug;
+import jogamp.nativewindow.x11.X11Lib;
+import jogamp.nativewindow.x11.X11Util;
+
+public class JFXAccessor {
+ private static final boolean DEBUG;
+
+ private static final boolean jfxAvailable;
+ private static final Method fxUserThreadGetter;
+ private static final Method tkStageGetter;
+ private static final Method glassWindowGetter;
+ private static final Method nativeWindowGetter;
+
+ private static final String nwt;
+ private static final boolean isOSX;
+ private static final boolean isWindows;
+ private static final boolean isX11;
+
+ static {
+ final boolean[] _DEBUG = new boolean[] { true };
+
+ final Method[] res = AccessController.doPrivileged(new PrivilegedAction<Method[]>() {
+ @Override
+ public Method[] run() {
+ NativeWindowFactory.initSingleton(); // last resort ..
+ final Method[] res = new Method[] { null, null, null, null };
+ try {
+ int i=0;
+ _DEBUG[0] = Debug.debug("JFX");
+ /**
+ * com.sun.javafx.tk.Toolkit
+ */
+ final Class<?> jfxToolkitClz = ReflectionUtil.getClass("com.sun.javafx.tk.Toolkit", false, JFXAccessor.class.getClassLoader());
+ res[i] = jfxToolkitClz.getDeclaredMethod("getFxUserThread");
+ res[i++].setAccessible(true);
+
+ /***
+ * class javafx.stage.Window
+ * class javafx.stage.Stage extends javafx.stage.Window
+ * class com.sun.javafx.tk.quantum.WindowStage extends com.sun.javafx.tk.quantum.GlassStage implements com.sun.javafx.tk.TKStage
+ * abstract com.sun.glass.ui.Window
+ *
+ * javafx.stage.Window: com.sun.javafx.tk.TKStage [impl_]getPeer()
+ * com.sun.javafx.tk.quantum.WindowStage: final com.sun.glass.ui.Window getPlatformWindow()
+ * com.sun.glass.ui.Window: public long getNativeWindow()
+ */
+ final Class<?> jfxStageWindowClz = ReflectionUtil.getClass("javafx.stage.Window", false, JFXAccessor.class.getClassLoader());
+ // final Class<?> jfxTkTKStageClz = ReflectionUtil.getClass("com.sun.javafx.tk.TKStage", false, JFXAccessor.class.getClassLoader());
+ final Class<?> jfxTkQuWindowStageClz = ReflectionUtil.getClass("com.sun.javafx.tk.quantum.WindowStage", false, JFXAccessor.class.getClassLoader());
+ final Class<?> jfxGlassUiWindowClz = ReflectionUtil.getClass("com.sun.glass.ui.Window", false, JFXAccessor.class.getClassLoader());
+
+ try {
+ // jfx 9, 11, 12, ..
+ res[i] = jfxStageWindowClz.getDeclaredMethod("getPeer");
+ } catch (final NoSuchMethodException ex) {
+ // jfx 8
+ res[i] = jfxStageWindowClz.getDeclaredMethod("impl_getPeer");
+ }
+ res[i++].setAccessible(true);
+
+ res[i] = jfxTkQuWindowStageClz.getDeclaredMethod("getPlatformWindow");
+ res[i++].setAccessible(true);
+ res[i] = jfxGlassUiWindowClz.getDeclaredMethod("getNativeWindow");
+ res[i++].setAccessible(true);
+ } catch (final Throwable t) {
+ if(_DEBUG[0]) {
+ ExceptionUtils.dumpThrowable("jfx-init", t);
+ }
+ }
+ return res;
+ }
+ });
+ {
+ int i=0;
+ fxUserThreadGetter = res[i++];
+ tkStageGetter = res[i++];
+ glassWindowGetter = res[i++];
+ nativeWindowGetter = res[i++];
+ }
+ jfxAvailable = null != fxUserThreadGetter && null != tkStageGetter && null != glassWindowGetter && null != nativeWindowGetter;
+
+ nwt = NativeWindowFactory.getNativeWindowType(false);
+ isOSX = NativeWindowFactory.TYPE_MACOSX == nwt;
+ isWindows = NativeWindowFactory.TYPE_WINDOWS == nwt;
+ isX11 = NativeWindowFactory.TYPE_X11 == nwt;
+
+ DEBUG = _DEBUG[0];
+ if(DEBUG) {
+ System.err.println(Thread.currentThread().getName()+" - Info: JFXAccessor.<init> available "+jfxAvailable+", nwt "+nwt+"( x11 "+isX11+", win "+isWindows+", osx "+isOSX+")");
+ }
+ }
+
+ //
+ // Common any toolkit
+ //
+
+ public static boolean isJFXAvailable() { return jfxAvailable; }
+
+ /**
+ * Runs given {@code task} on the JFX Thread if it has not stopped and if caller is not already on the JFX Thread,
+ * otherwise execute given {@code task} on the current thread.
+ * @param wait
+ * @param task
+ * @see #isJFXThreadOrHasJFXThreadStopped()
+ */
+ public static void runOnJFXThread(final boolean wait, final Runnable task) {
+ final Object rTaskLock = new Object();
+ synchronized(rTaskLock) { // lock the task execution
+ if( isJFXThreadOrHasJFXThreadStopped() ) {
+ task.run();
+ } else if( !wait ) {
+ Platform.runLater(task);
+ } else {
+ final RunnableTask rTask = new RunnableTask(task,
+ rTaskLock,
+ true /* always catch and report Exceptions, don't disturb EDT */,
+ null);
+ Platform.runLater(rTask);
+ try {
+ while( rTask.isInQueue() ) {
+ rTaskLock.wait(); // free lock, allow execution of rTask
+ }
+ } catch (final InterruptedException ie) {
+ throw new InterruptedRuntimeException(ie);
+ }
+ final Throwable throwable = rTask.getThrowable();
+ if(null!=throwable) {
+ if(throwable instanceof NativeWindowException) {
+ throw (NativeWindowException)throwable;
+ }
+ throw new RuntimeException(throwable);
+ }
+ }
+ }
+ }
+
+ public static Thread getJFXThread() throws NativeWindowException {
+ try {
+ return (Thread) fxUserThreadGetter.invoke(null);
+ } catch (final Throwable e) {
+ throw new NativeWindowException("Error getting JFX-Thread", e);
+ }
+ }
+ public static String getJFXThreadName() {
+ final Thread t = getJFXThread();
+ return null != t ? t.getName() : null;
+ }
+ /**
+ * @return true if the JFX Thread has stopped
+ */
+ public static boolean hasJFXThreadStopped() {
+ final Thread t = getJFXThread();
+ return null == t || !t.isAlive();
+ }
+ /**
+ * @return true if caller is on the JFX Thread
+ */
+ public static boolean isJFXThread() {
+ final Thread t = getJFXThread();
+ return Thread.currentThread() == t;
+ }
+ /**
+ * @return true if the JFX Thread has stopped or if caller is on the JFX Thread
+ */
+ public static boolean isJFXThreadOrHasJFXThreadStopped() {
+ final Thread t = getJFXThread();
+ return null == t || !t.isAlive() || Thread.currentThread() == t;
+ }
+
+ /**
+ * @param stageWindow the JavaFX top heavyweight window handle
+ * @return the AbstractGraphicsDevice w/ the native device handle
+ * @throws NativeWindowException if an exception occurs retrieving the window handle or deriving the native device
+ * @throws UnsupportedOperationException if the windowing system is not supported
+ */
+ public static AbstractGraphicsDevice getDevice(final Window stageWindow) throws NativeWindowException, UnsupportedOperationException {
+ if( isX11 ) {
+ // Decoupled X11 Device/Screen allowing X11 display lock-free off-thread rendering
+ final String connection = null;
+ final long x11DeviceHandle = X11Util.openDisplay(connection);
+ if( 0 == x11DeviceHandle ) {
+ throw new NativeWindowException("Error creating display: "+connection);
+ }
+ return new X11GraphicsDevice(x11DeviceHandle, AbstractGraphicsDevice.DEFAULT_UNIT, true /* owner */);
+ }
+ if( isWindows ) {
+ return new WindowsGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT);
+ }
+ if( isOSX ) {
+ return new MacOSXGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT);
+ }
+ throw new UnsupportedOperationException("n/a for this windowing system: "+nwt);
+ }
+
+ /**
+ * @param device
+ * @param screen -1 is default screen of the given device, e.g. maybe 0 or determined by native API. >= 0 is specific screen
+ * @return
+ */
+ public static AbstractGraphicsScreen getScreen(final AbstractGraphicsDevice device, final int screen) {
+ return NativeWindowFactory.createScreen(device, screen);
+ }
+
+ public static int getNativeVisualID(final AbstractGraphicsDevice device, final long windowHandle) {
+ if( isX11 ) {
+ return X11Lib.GetVisualIDFromWindow(device.getHandle(), windowHandle);
+ }
+ if( isWindows || isOSX ) {
+ return VisualIDHolder.VID_UNDEFINED;
+ }
+ throw new UnsupportedOperationException("n/a for this windowing system: "+nwt);
+ }
+
+ /**
+ * @param stageWindow the JavaFX top heavyweight window handle
+ * @return the native window handle
+ * @throws NativeWindowException if an exception occurs retrieving the window handle
+ */
+ public static long getWindowHandle(final Window stageWindow) throws NativeWindowException {
+ final long h[] = { 0 };
+ runOnJFXThread(true, new Runnable() {
+ public void run() {
+ try {
+ final TKStage tkStage = (TKStage) tkStageGetter.invoke(stageWindow);
+ if( null != tkStage ) {
+ final Object platformWindow = glassWindowGetter.invoke(tkStage);
+ if( null != platformWindow ) {
+ final Object nativeHandle = nativeWindowGetter.invoke(platformWindow);
+ h[0] = ((Long) nativeHandle).longValue();
+ } else if(DEBUG) {
+ System.err.println(Thread.currentThread().getName()+" - Info: JFXAccessor null GlassWindow");
+ }
+ } else if(DEBUG) {
+ System.err.println(Thread.currentThread().getName()+" - Info: JFXAccessor null TKStage");
+ }
+ } catch (final Throwable e) {
+ throw new NativeWindowException("Error getting Window handle", e);
+ }
+ } });
+ return h[0];
+ }
+}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java b/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java
index 26a5f452b..6ddfc8950 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java
@@ -387,7 +387,7 @@ public class SWTAccessor {
return new X11GraphicsDevice(xdisplay0, AbstractGraphicsDevice.DEFAULT_UNIT, false /* owner */);
}
if( isWindows ) {
- return new WindowsGraphicsDevice(AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
+ return new WindowsGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT);
}
if( isOSX ) {
return new MacOSXGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT);
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/util/Point.java b/src/nativewindow/classes/com/jogamp/nativewindow/util/Point.java
index fc5465bbf..aa511b625 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/util/Point.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/util/Point.java
@@ -120,6 +120,18 @@ public class Point implements Cloneable, PointImmutable {
/**
* Translate this instance's x- and y-components,
+ * i.e. add the values of the given delta point to them.
+ * @param pd delta point
+ * @return this instance for scaling
+ */
+ public final Point translate(final PointImmutable pd) {
+ x += pd.getX() ;
+ y += pd.getY() ;
+ return this;
+ }
+
+ /**
+ * Translate this instance's x- and y-components,
* i.e. add the given deltas to them.
* @param dx delta for x
* @param dy delta for y
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsConfiguration.java b/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsConfiguration.java
index 04619962d..bcb9741d6 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsConfiguration.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsConfiguration.java
@@ -33,10 +33,15 @@
package com.jogamp.nativewindow.x11;
+import com.jogamp.common.util.Bitfield;
import com.jogamp.nativewindow.CapabilitiesImmutable;
import com.jogamp.nativewindow.MutableGraphicsConfiguration;
+import jogamp.nativewindow.x11.X11Capabilities;
+import jogamp.nativewindow.x11.X11Lib;
+import jogamp.nativewindow.x11.XRenderDirectFormat;
+import jogamp.nativewindow.x11.XRenderPictFormat;
import jogamp.nativewindow.x11.XVisualInfo;
/** Encapsulates a graphics configuration, or OpenGL pixel format, on
@@ -48,6 +53,44 @@ import jogamp.nativewindow.x11.XVisualInfo;
public class X11GraphicsConfiguration extends MutableGraphicsConfiguration implements Cloneable {
private XVisualInfo info;
+ // FBConfig
+
+ protected static XRenderDirectFormat XVisual2XRenderMask(final long dpy, final long visual) {
+ final XRenderPictFormat xRenderPictFormat = XRenderPictFormat.create();
+ return XVisual2XRenderMask(dpy, visual, xRenderPictFormat);
+ }
+ protected static XRenderDirectFormat XVisual2XRenderMask(final long dpy, final long visual, final XRenderPictFormat dest) {
+ if( !X11Lib.XRenderFindVisualFormat(dpy, visual, dest) ) {
+ return null;
+ } else {
+ return dest.getDirect();
+ }
+ }
+
+ public static X11Capabilities XVisualInfo2X11Capabilities(final X11GraphicsDevice device, final XVisualInfo info) {
+ final long display = device.getHandle();
+ final X11Capabilities res = new X11Capabilities(info);
+
+ final XRenderDirectFormat xrmask = ( null != info ) ? XVisual2XRenderMask( display, info.getVisual() ) : null ;
+ final int alphaMask = ( null != xrmask ) ? xrmask.getAlphaMask() : 0;
+ if( 0 < alphaMask ) {
+ res.setBackgroundOpaque(false);
+ res.setTransparentRedValue(xrmask.getRedMask());
+ res.setTransparentGreenValue(xrmask.getGreenMask());
+ res.setTransparentBlueValue(xrmask.getBlueMask());
+ res.setTransparentAlphaValue(alphaMask);
+ } else {
+ res.setBackgroundOpaque(true);
+ }
+ // ALPHA shall be set at last - due to it's auto setting by the above (!opaque / samples)
+ res.setRedBits (Bitfield.Util.bitCount((int)info.getRed_mask()));
+ res.setGreenBits (Bitfield.Util.bitCount((int)info.getGreen_mask()));
+ res.setBlueBits (Bitfield.Util.bitCount((int)info.getBlue_mask()));
+ res.setAlphaBits (Bitfield.Util.bitCount(alphaMask));
+
+ return res;
+ }
+
public X11GraphicsConfiguration(final X11GraphicsScreen screen,
final CapabilitiesImmutable capsChosen, final CapabilitiesImmutable capsRequested,
final XVisualInfo info) {
diff --git a/src/nativewindow/classes/jogamp/nativewindow/BcmVCArtifacts.java b/src/nativewindow/classes/jogamp/nativewindow/BcmVCArtifacts.java
new file mode 100644
index 000000000..216c55a3a
--- /dev/null
+++ b/src/nativewindow/classes/jogamp/nativewindow/BcmVCArtifacts.java
@@ -0,0 +1,76 @@
+/**
+ * Copyright 2018 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.io.File;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * Heuristics about Broadcom (BCM) VideoCore (VC) existence and usage
+ */
+public class BcmVCArtifacts {
+ static final boolean hasVCLib;
+ static final boolean hasVC4ModLocation;
+ static final boolean hasDriCard0File;
+
+ static {
+ final File vcLibLocation = new File(
+ "/opt/vc/lib/libbcm_host.so");
+ final File vc4ModLocation = new File(
+ "/sys/module/vc4");
+ final File driCard0Location = new File(
+ "/dev/dri/card0");
+ final boolean[] res = new boolean [3];
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ @Override
+ public Object run() {
+ res[0] = vcLibLocation.isFile();
+ res[1] = vc4ModLocation.isDirectory();
+ res[2] = driCard0Location.isFile();
+ return null;
+ } } );
+ hasVCLib = res[0];
+ hasVC4ModLocation = res[1];
+ hasDriCard0File = res[2];
+ }
+
+ /**
+ * @return True if proprietary BCM VC IV is probably being present
+ */
+ public static final boolean guessVCIVPresent() {
+ return hasVCLib;
+ }
+ /**
+ * @return True if proprietary BCM VC IV is probably being used and not Xorg drivers
+ */
+ public static final boolean guessVCIVUsed() {
+ return hasVCLib && !hasVC4ModLocation && !hasDriCard0File;
+ }
+}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java
index 264bdf9d3..5a0c8a79a 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java
@@ -101,14 +101,15 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface {
OSXUtil.RunOnMainThread(false, true /* kickNSApp */, new Runnable() {
@Override
public void run() {
+ if( 0 != jawtSurfaceLayersHandle) {
+ // null rootSurfaceLayer OK
+ UnsetJAWTRootSurfaceLayer0(jawtSurfaceLayersHandle, rootSurfaceLayer);
+ }
+ jawtSurfaceLayersHandle = 0;
if( 0 != rootSurfaceLayer ) {
- if( 0 != jawtSurfaceLayersHandle) {
- UnsetJAWTRootSurfaceLayer0(jawtSurfaceLayersHandle, rootSurfaceLayer);
- }
OSXUtil.DestroyCALayer(rootSurfaceLayer);
rootSurfaceLayer = 0;
}
- jawtSurfaceLayersHandle = 0;
}
});
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
index 8ad089a56..f71dff1cb 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
@@ -34,6 +34,7 @@ import com.jogamp.nativewindow.util.Point;
import com.jogamp.common.util.Function;
import com.jogamp.common.util.FunctionTask;
+import com.jogamp.common.util.InterruptedRuntimeException;
import com.jogamp.common.util.RunnableTask;
import jogamp.nativewindow.Debug;
@@ -267,22 +268,21 @@ public class OSXUtil implements ToolkitProperties {
} else {
// Utilize Java side lock/wait and simply pass the Runnable async to OSX main thread,
// otherwise we may freeze the OSX main thread.
- Throwable throwable = null;
final Object sync = new Object();
final RunnableTask rt = new RunnableTask( runnable, waitUntilDone ? sync : null, true, waitUntilDone ? null : System.err );
synchronized(sync) {
RunOnMainThread0(kickNSApp, rt);
if( waitUntilDone ) {
- try {
- sync.wait();
- } catch (final InterruptedException ie) {
- throwable = ie;
- }
- if(null==throwable) {
- throwable = rt.getThrowable();
- }
- if(null!=throwable) {
- throw new RuntimeException(throwable);
+ while( rt.isInQueue() ) {
+ try {
+ sync.wait();
+ } catch (final InterruptedException ie) {
+ throw new InterruptedRuntimeException(ie);
+ }
+ final Throwable throwable = rt.getThrowable();
+ if(null!=throwable) {
+ throw new RuntimeException(throwable);
+ }
}
}
}
@@ -341,23 +341,22 @@ public class OSXUtil implements ToolkitProperties {
} else {
// Utilize Java side lock/wait and simply pass the Runnable async to OSX main thread,
// otherwise we may freeze the OSX main thread.
- Throwable throwable = null;
final Object sync = new Object();
final FunctionTask<R,A> rt = new FunctionTask<R,A>( func, waitUntilDone ? sync : null, true, waitUntilDone ? null : System.err );
synchronized(sync) {
rt.setArgs(args);
RunOnMainThread0(kickNSApp, rt);
if( waitUntilDone ) {
- try {
- sync.wait();
- } catch (final InterruptedException ie) {
- throwable = ie;
- }
- if(null==throwable) {
- throwable = rt.getThrowable();
- }
- if(null!=throwable) {
- throw new RuntimeException(throwable);
+ while( rt.isInQueue() ) {
+ try {
+ sync.wait();
+ } catch (final InterruptedException ie) {
+ throw new InterruptedRuntimeException(ie);
+ }
+ final Throwable throwable = rt.getThrowable();
+ if(null!=throwable) {
+ throw new RuntimeException(throwable);
+ }
}
}
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java b/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java
index bdf9630af..c0f277f09 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java
@@ -32,6 +32,8 @@ import com.jogamp.nativewindow.NativeWindowException;
import com.jogamp.nativewindow.NativeWindowFactory;
import com.jogamp.common.ExceptionUtils;
+import com.jogamp.common.os.Platform;
+import com.jogamp.common.util.VersionNumber;
import jogamp.nativewindow.NWJNILibLoader;
import jogamp.nativewindow.Debug;
@@ -122,6 +124,107 @@ public class GDIUtil implements ToolkitProperties {
return (Point) GetRelativeLocation0(src_win, dest_win, src_x, src_y);
}
+ /**
+ * Windows >= 8, even if not manifested
+ * @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms724832%28v=vs.85%29.aspx
+ */
+ public static final VersionNumber Win8Version = new VersionNumber(6, 2, 0);
+
+ /**
+ * Windows >= 10, manifested
+ * @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms724832%28v=vs.85%29.aspx
+ */
+ public static final VersionNumber Win10Version = new VersionNumber(10, 0, 0);
+
+ /**
+ * Wrapper for {@link GDI#DwmIsCompositionEnabled()}
+ * taking the Windows 8 version into account.
+ * <p>
+ * If Windows version >= {@link #Win8Version} method always returns {@code true},
+ * otherwise value of {@link GDI#DwmIsCompositionEnabled()} is returned.
+ * </p>
+ * @see https://msdn.microsoft.com/en-us/library/windows/desktop/aa969518%28v=vs.85%29.aspx
+ */
+ public static boolean DwmIsCompositionEnabled() {
+ final VersionNumber winVer = Platform.getOSVersionNumber();
+ if( winVer.compareTo(Win8Version) >= 0 ) {
+ return true;
+ } else {
+ return GDI.DwmIsCompositionEnabled();
+ }
+ }
+
+ public static boolean DwmSetupTranslucency(final long hwnd, final boolean enable) {
+ if( !GDI.DwmIsExtensionAvailable() ) {
+ if(DEBUG) {
+ System.err.println("GDIUtil.DwmSetupTranslucency on wnd 0x"+Long.toHexString(hwnd)+": enable "+enable+" -> failed, extension not available");
+ }
+ return !enable;
+ }
+ final VersionNumber winVer = Platform.getOSVersionNumber();
+ final boolean isWin8 = winVer.compareTo(Win8Version) >= 0;
+ if( !isWin8 && !GDI.DwmIsCompositionEnabled() ) {
+ if(DEBUG) {
+ System.err.println("GDIUtil.DwmSetupTranslucency on wnd 0x"+Long.toHexString(hwnd)+": enable "+enable+" -> failed, composition disabled");
+ }
+ return !enable;
+ }
+ final boolean hasWinCompEXT = GDI.IsWindowCompositionExtensionAvailable();
+ final boolean useWinCompEXT = isWin8 && hasWinCompEXT;
+ final boolean isUndecorated = IsUndecorated(hwnd);
+ boolean ok;
+ if( useWinCompEXT && !isUndecorated ) {
+ final AccentPolicy accentPolicy = AccentPolicy.create();
+ if( enable ) {
+ // For undecorated windows, this would also enable the Glass effect!
+ accentPolicy.setAccentState(GDI.ACCENT_ENABLE_BLURBEHIND);
+ } else {
+ accentPolicy.setAccentState(GDI.ACCENT_DISABLED);
+ }
+ ok = GDI.SetWindowCompositionAccentPolicy(hwnd, accentPolicy);
+ } else {
+ // Works even for >= Win8, if undecorated
+ final DWM_BLURBEHIND bb = DWM_BLURBEHIND.create();
+ final int dwFlags = enable ? GDI.DWM_BB_ENABLE | GDI.DWM_BB_BLURREGION | GDI.DWM_BB_TRANSITIONONMAXIMIZED : GDI.DWM_BB_ENABLE;
+ // final int dwFlags = GDI.DWM_BB_ENABLE;
+ bb.setDwFlags( dwFlags );
+ bb.setFEnable( enable ? 1 : 0 );
+ bb.setHRgnBlur(0);
+ bb.setFTransitionOnMaximized(1);
+ ok = GDI.DwmEnableBlurBehindWindow(hwnd, bb);
+ if( ok ) {
+ final MARGINS m = MARGINS.create();
+ m.setCxLeftWidth(-1);
+ m.setCxRightWidth(-1);
+ m.setCyBottomHeight(-1);
+ m.setCyTopHeight(-1);
+ ok = GDI.DwmExtendFrameIntoClientArea(hwnd, m);
+ }
+ }
+ /***
+ * Not required ..
+ *
+ if( ok && isWin8 && !isUndecorated ) {
+ final IntBuffer pvAttribute = Buffers.newDirectIntBuffer(1);
+ if( enable ) {
+ // Glass Effect even if undecorated, hence not truly 100% translucent!
+ pvAttribute.put(0, GDI.DWMNCRP_ENABLED);
+ } else {
+ pvAttribute.put(0, GDI.DWMNCRP_DISABLED);
+ }
+ final int err = GDI.DwmSetWindowAttribute(hwnd, GDI.DWMWA_NCRENDERING_POLICY,
+ pvAttribute,
+ Buffers.sizeOfBufferElem(pvAttribute)*pvAttribute.capacity());
+ ok = 0 == err; // S_OK
+ } */
+ if(DEBUG) {
+ final boolean isChild = IsChild(hwnd);
+ System.err.println("GDIUtil.DwmSetupTranslucency on wnd 0x"+Long.toHexString(hwnd)+": enable "+enable+", isUndecorated "+isUndecorated+", isChild "+isChild+
+ ", version "+winVer+", isWin8 "+isWin8+", hasWinCompEXT "+hasWinCompEXT+", useWinCompEXT "+useWinCompEXT+" -> ok: "+ok);
+ }
+ return ok;
+ }
+
public static boolean IsUndecorated(final long win) {
return IsUndecorated0(win);
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/X11GraphicsConfigurationFactory.java b/src/nativewindow/classes/jogamp/nativewindow/x11/X11GraphicsConfigurationFactory.java
index f8a11f91e..4257376a0 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/x11/X11GraphicsConfigurationFactory.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/x11/X11GraphicsConfigurationFactory.java
@@ -42,6 +42,7 @@ import com.jogamp.nativewindow.NativeWindowException;
import com.jogamp.nativewindow.VisualIDHolder;
import com.jogamp.nativewindow.x11.X11GraphicsConfiguration;
+import com.jogamp.nativewindow.x11.X11GraphicsDevice;
import com.jogamp.nativewindow.x11.X11GraphicsScreen;
public class X11GraphicsConfigurationFactory extends GraphicsConfigurationFactory {
@@ -59,15 +60,17 @@ public class X11GraphicsConfigurationFactory extends GraphicsConfigurationFactor
if(!(screen instanceof X11GraphicsScreen)) {
throw new NativeWindowException("Only valid X11GraphicsScreen are allowed");
}
- final X11Capabilities x11CapsChosen;
+ final XVisualInfo x11VisualInfo;
if(VisualIDHolder.VID_UNDEFINED == nativeVisualID) {
- x11CapsChosen = new X11Capabilities(getXVisualInfo(screen, capsChosen));
+ x11VisualInfo = getXVisualInfo(screen, capsChosen);
} else {
- x11CapsChosen = new X11Capabilities(getXVisualInfo(screen, nativeVisualID));
+ x11VisualInfo = getXVisualInfo(screen, nativeVisualID);
}
+
+ final X11Capabilities x11CapsChosen = X11GraphicsConfiguration.XVisualInfo2X11Capabilities((X11GraphicsDevice)screen.getDevice(), x11VisualInfo);
final AbstractGraphicsConfiguration res = new X11GraphicsConfiguration((X11GraphicsScreen)screen, x11CapsChosen, capsRequested, x11CapsChosen.getXVisualInfo());
if(DEBUG) {
- System.err.println("X11GraphicsConfigurationFactory.chooseGraphicsConfigurationImpl(visualID 0x"+Integer.toHexString(nativeVisualID)+", "+screen+","+capsChosen+"): "+res);
+ System.err.println("X11GraphicsConfigurationFactory.chooseGraphicsConfigurationImpl(visualID 0x"+Integer.toHexString(nativeVisualID)+", "+x11VisualInfo+", "+screen+","+capsChosen+"): "+res);
}
return res;
}
@@ -85,7 +88,6 @@ public class X11GraphicsConfigurationFactory extends GraphicsConfigurationFactor
if(xvis==null || num[0]<1) {
return null;
}
-
return XVisualInfo.create(xvis[0]);
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java
index e59ff2ea8..6af5467f0 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java
@@ -463,10 +463,12 @@ public class X11Util implements ToolkitProperties {
if(markAllDisplaysUnclosable) {
namedDpy.setUncloseable(true);
}
- }
- if(DEBUG) {
- System.err.println("X11Util.Display: openDisplay [reuse "+reused+"] "+namedDpy+". Thread "+Thread.currentThread().getName());
- // Thread.dumpStack();
+ if(DEBUG) {
+ System.err.println("X11Util.Display: openDisplay [reuse "+reused+"] "+namedDpy+
+ ". Open[reuseable "+reusableDisplayList.size()+", pending "+pendingDisplayList.size()+
+ "]. Thread "+Thread.currentThread().getName());
+ // Thread.dumpStack();
+ }
}
return namedDpy.getHandle();
}
diff --git a/src/nativewindow/native/macosx/OSXmisc.m b/src/nativewindow/native/macosx/OSXmisc.m
index 919108db9..c04ba786e 100644
--- a/src/nativewindow/native/macosx/OSXmisc.m
+++ b/src/nativewindow/native/macosx/OSXmisc.m
@@ -336,6 +336,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_CreateNSWindow0
(JNIEnv *env, jclass unused, jint x, jint y, jint width, jint height)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ [CATransaction begin];
NSRect rect = NSMakeRect(x, y, width, height);
// Allocate the window
@@ -365,6 +366,7 @@ NS_ENDHANDLER
// [myView lockFocus];
// [myView unlockFocus];
+ [CATransaction commit];
[pool release];
return (jlong) ((intptr_t) myWindow);
@@ -379,9 +381,17 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_DestroyNSWindow0
(JNIEnv *env, jclass unused, jlong nsWindow)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- NSWindow* mWin = (NSWindow*) ((intptr_t) nsWindow);
+ [CATransaction begin];
+NS_DURING
+ NSWindow* mWin = (NSWindow*) ((intptr_t) nsWindow);
[mWin close]; // performs release!
+NS_HANDLER
+ // On killing or terminating the process [NSWindow _close], rarely
+ // throws an NSRangeException while ordering out menu items
+NS_ENDHANDLER
+
+ [CATransaction commit];
[pool release];
}
@@ -861,8 +871,12 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow_Ge
NativewindowCommon_throwNewRuntimeException(env, "Argument \"jawtDrawingSurfaceInfoBuffer\" was not a direct buffer");
return 0;
}
- id <JAWT_SurfaceLayers> surfaceLayers = (id <JAWT_SurfaceLayers>)dsi->platformInfo;
- return (jlong) ((intptr_t) surfaceLayers);
+ NSObject *surfaceLayersObj = (NSObject*) dsi->platformInfo;
+ [surfaceLayersObj retain]; // Pairs w/ Unset
+ DBG_PRINT("CALayer::GetJAWTSurfaceLayersHandle: surfaceLayers %p (refcnt %d)\n", surfaceLayersObj, (int)[surfaceLayersObj retainCount]);
+
+ id <JAWT_SurfaceLayers> surfaceLayers = (id <JAWT_SurfaceLayers>)surfaceLayersObj;
+ return (jlong) (intptr_t) surfaceLayers;
}
/*
@@ -878,9 +892,11 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow_Set
[CATransaction begin];
[CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
- id <JAWT_SurfaceLayers> surfaceLayers = (id <JAWT_SurfaceLayers>)(intptr_t)jawtSurfaceLayersHandle;
+ NSObject *surfaceLayersObj = (NSObject*) (intptr_t) jawtSurfaceLayersHandle;
+ id <JAWT_SurfaceLayers> surfaceLayers = (id <JAWT_SurfaceLayers>)surfaceLayersObj;
MyCALayer* layer = (MyCALayer*) (intptr_t) caLayer;
DBG_PRINT("CALayer::SetJAWTRootSurfaceLayer.0: pre %p -> root %p (refcnt %d)\n", [surfaceLayers layer], layer, (int)[layer retainCount]);
+
[surfaceLayers setLayer: [layer retain]]; // Pairs w/ Unset
[CATransaction commit];
@@ -902,20 +918,26 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow_Uns
[CATransaction begin];
[CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
- id <JAWT_SurfaceLayers> surfaceLayers = (id <JAWT_SurfaceLayers>)(intptr_t)jawtSurfaceLayersHandle;
+ NSObject *surfaceLayersObj = (NSObject*) (intptr_t) jawtSurfaceLayersHandle;
+ id <JAWT_SurfaceLayers> surfaceLayers = (id <JAWT_SurfaceLayers>)surfaceLayersObj;
+ DBG_PRINT("CALayer::UnsetJAWTRootSurfaceLayer.0: surfaceLayers %p (refcnt %d)\n", surfaceLayersObj, (int)[surfaceLayersObj retainCount]);
+
MyCALayer* layer = (MyCALayer*) (intptr_t) caLayer;
- if(layer != [surfaceLayers layer]) {
- NativewindowCommon_throwNewRuntimeException(env, "Attached layer %p doesn't match given layer %p\n", surfaceLayers.layer, layer);
- return;
+ if(NULL != layer) {
+ if(layer != [surfaceLayers layer]) {
+ NativewindowCommon_throwNewRuntimeException(env, "Attached layer %p doesn't match given layer %p\n", surfaceLayers.layer, layer);
+ return;
+ }
+ DBG_PRINT("CALayer::UnsetJAWTRootSurfaceLayer.1: root %p (refcnt %d) -> nil\n", layer, (int)[layer retainCount]);
+ [layer release]; // Pairs w/ Set
+ [surfaceLayers setLayer: NULL]; // Pairs w/ Set
}
- DBG_PRINT("CALayer::UnsetJAWTRootSurfaceLayer.0: root %p (refcnt %d) -> nil\n", layer, (int)[layer retainCount]);
- [layer release]; // Pairs w/ Set
- [surfaceLayers setLayer: NULL];
+ [surfaceLayersObj release]; // Pairs w/ Get
[CATransaction commit];
[pool release];
- DBG_PRINT("CALayer::UnsetJAWTRootSurfaceLayer.X: root %p (refcnt %d) -> nil\n", layer, (int)[layer retainCount]);
+ DBG_PRINT("CALayer::UnsetJAWTRootSurfaceLayer.X\n");
}
@interface MainRunnable : NSObject
diff --git a/src/nativewindow/native/win32/WindowsDWM.c b/src/nativewindow/native/win32/WindowsDWM.c
index cc9ed6d8c..925ddd1d1 100644
--- a/src/nativewindow/native/win32/WindowsDWM.c
+++ b/src/nativewindow/native/win32/WindowsDWM.c
@@ -1,4 +1,5 @@
+#include <windows.h>
#include "WindowsDWM.h"
#include <stdlib.h>
@@ -21,39 +22,68 @@ typedef HRESULT (WINAPI *DwmEnableCompositionPROCADDR)(UINT uCompositionAction);
typedef HRESULT (WINAPI *DwmIsCompositionEnabledPROCADDR)(BOOL * pfEnabled);
typedef HRESULT (WINAPI *DwmEnableBlurBehindWindowPROCADDR)(HWND hWnd, const DWM_BLURBEHIND* pBlurBehind);
typedef HRESULT (WINAPI *DwmExtendFrameIntoClientAreaPROCADDR)(HWND hwnd, const MARGINS *pMarInset);
+typedef HRESULT (WINAPI *DwmGetWindowAttributePROCADDR)(HWND hwnd, DWORD dwAttribute, PVOID pvAttribute, DWORD cbAttribute);
+typedef HRESULT (WINAPI *DwmSetWindowAttributePROCADDR)(HWND hwnd, DWORD dwAttribute, LPCVOID pvAttribute, DWORD cbAttribute);
+typedef BOOL (WINAPI *GetWindowCompositionAttributePROCADDR)(HWND hwnd, WINCOMPATTRDATA* pAttrData);
+typedef BOOL (WINAPI *SetWindowCompositionAttributePROCADDR)(HWND hwnd, WINCOMPATTRDATA* pAttrData);
-static int _init = 0; // 1: init, 2: has DWM extension
+#define INIT_CALLED_MASK 1 << 0
+#define INIT_HAS_DWM_EXT_MASK 1 << 1
+#define INIT_HAS_WINCOMP_EXT_MASK 1 << 2
+
+#define HAS_INIT(a) ( 0 != ( INIT_CALLED_MASK & (a) ) )
+#define HAS_DWM_EXT(a) ( 0 != ( INIT_HAS_DWM_EXT_MASK & (a) ) )
+#define HAS_WINCOMP_EXT(a) ( 0 != ( INIT_HAS_WINCOMP_EXT_MASK & (a) ) )
+
+static int _init = 0; // INIT_ bits, see above
static DwmEnableCompositionPROCADDR _DwmEnableComposition = NULL;
static DwmIsCompositionEnabledPROCADDR _DwmIsCompositionEnabled = NULL;
static DwmEnableBlurBehindWindowPROCADDR _DwmEnableBlurBehindWindow = NULL;
static DwmExtendFrameIntoClientAreaPROCADDR _DwmExtendFrameIntoClientArea = NULL;
+static DwmGetWindowAttributePROCADDR _DwmGetWindowAttribute = NULL;
+static DwmSetWindowAttributePROCADDR _DwmSetWindowAttribute = NULL;
+static GetWindowCompositionAttributePROCADDR _GetWindowCompositionAttribute = NULL;
+static SetWindowCompositionAttributePROCADDR _SetWindowCompositionAttribute = NULL;
static int initWindowsDWM() {
- if(0 == _init) {
- _init = 1;
- HANDLE shell = LoadLibrary(TEXT("dwmapi.dll"));
- if (shell) {
- _DwmEnableComposition = (DwmEnableCompositionPROCADDR) GetProcAddressA (shell, "DwmEnableComposition");
- _DwmIsCompositionEnabled = (DwmIsCompositionEnabledPROCADDR) GetProcAddressA (shell, "DwmIsCompositionEnabled");
- _DwmEnableBlurBehindWindow = (DwmEnableBlurBehindWindowPROCADDR) GetProcAddressA (shell, "DwmEnableBlurBehindWindow");
- _DwmExtendFrameIntoClientArea = (DwmExtendFrameIntoClientAreaPROCADDR) GetProcAddressA (shell, "DwmExtendFrameIntoClientArea");
+ if( !HAS_INIT(_init) ) {
+ _init |= INIT_CALLED_MASK;
+ HANDLE hDwmAPI = LoadLibrary(TEXT("dwmapi.dll"));
+ if (hDwmAPI) {
+ _DwmEnableComposition = (DwmEnableCompositionPROCADDR) GetProcAddressA (hDwmAPI, "DwmEnableComposition");
+ _DwmIsCompositionEnabled = (DwmIsCompositionEnabledPROCADDR) GetProcAddressA (hDwmAPI, "DwmIsCompositionEnabled");
+ _DwmEnableBlurBehindWindow = (DwmEnableBlurBehindWindowPROCADDR) GetProcAddressA (hDwmAPI, "DwmEnableBlurBehindWindow");
+ _DwmExtendFrameIntoClientArea = (DwmExtendFrameIntoClientAreaPROCADDR) GetProcAddressA (hDwmAPI, "DwmExtendFrameIntoClientArea");
+ _DwmGetWindowAttribute = (DwmGetWindowAttributePROCADDR) GetProcAddressA (hDwmAPI, "DwmGetWindowAttribute");
+ _DwmSetWindowAttribute = (DwmSetWindowAttributePROCADDR) GetProcAddressA (hDwmAPI, "DwmSetWindowAttribute");
if(NULL != _DwmEnableComposition && NULL != _DwmIsCompositionEnabled &&
- NULL != _DwmEnableBlurBehindWindow && NULL != _DwmExtendFrameIntoClientArea) {
- _init = 2;
+ NULL != _DwmEnableBlurBehindWindow && NULL != _DwmExtendFrameIntoClientArea &&
+ NULL != _DwmGetWindowAttribute && NULL != _DwmSetWindowAttribute) {
+ _init |= INIT_HAS_DWM_EXT_MASK;
+ }
+ }
+ // FreeLibrary (hDwmAPI);
+ HANDLE hUser32 = LoadLibrary(TEXT("user32.dll"));
+ if (hUser32) {
+ _GetWindowCompositionAttribute = (GetWindowCompositionAttributePROCADDR) GetProcAddressA (hUser32, "GetWindowCompositionAttribute");
+ _SetWindowCompositionAttribute = (SetWindowCompositionAttributePROCADDR) GetProcAddressA (hUser32, "SetWindowCompositionAttribute");
+ if( NULL != _GetWindowCompositionAttribute &&
+ NULL != _SetWindowCompositionAttribute ) {
+ _init |= INIT_HAS_WINCOMP_EXT_MASK;
}
}
- // FreeLibrary (shell);
- DBG_PRINT("DWM - initWindowsDWM: %d - s %p, e %p, c %p\n", _init, shell, _DwmEnableBlurBehindWindow, _DwmExtendFrameIntoClientArea);
+ // FreeLibrary (hUser32);
+ DBG_PRINT("DWM - initWindowsDWM: hasDWM %d, hasWinComp %d\n", HAS_DWM_EXT(_init), HAS_WINCOMP_EXT(_init));
}
return _init;
}
BOOL DwmIsExtensionAvailable() {
- return (2 == initWindowsDWM()) ? TRUE : FALSE;
+ return HAS_DWM_EXT( initWindowsDWM() ) ? TRUE : FALSE;
}
BOOL DwmIsCompositionEnabled( ) {
- if(2 == initWindowsDWM()) {
+ if( HAS_DWM_EXT( initWindowsDWM() ) ) {
BOOL fEnabled = FALSE;
if( 0 == _DwmIsCompositionEnabled(&fEnabled) ) {
DBG_PRINT("DWM - DwmIsCompositionEnabled: %d\n", fEnabled);
@@ -65,14 +95,14 @@ BOOL DwmIsCompositionEnabled( ) {
}
BOOL DwmEnableComposition( UINT uCompositionAction ) {
- if(2 == initWindowsDWM()) {
+ if( HAS_DWM_EXT( initWindowsDWM() ) ) {
return 0 == _DwmEnableComposition(uCompositionAction) ? TRUE : FALSE;
}
return FALSE;
}
BOOL DwmEnableBlurBehindWindow(HWND hwnd, const DWM_BLURBEHIND* pBlurBehind) {
- if(2 == initWindowsDWM()) {
+ if( HAS_DWM_EXT( initWindowsDWM() ) ) {
_DwmEnableBlurBehindWindow(hwnd, pBlurBehind);
DBG_PRINT("DWM - DwmEnableBlurBehindWindow: hwnd %p, f %d, on %d, %p\n",
(void *)hwnd,
@@ -86,10 +116,59 @@ BOOL DwmEnableBlurBehindWindow(HWND hwnd, const DWM_BLURBEHIND* pBlurBehind) {
}
BOOL DwmExtendFrameIntoClientArea(HWND hwnd, const MARGINS *pMarInset) {
- if(2 == initWindowsDWM()) {
+ if( HAS_DWM_EXT( initWindowsDWM() ) ) {
_DwmExtendFrameIntoClientArea(hwnd, pMarInset);
return TRUE;
}
return FALSE;
}
+HRESULT DwmGetWindowAttribute(HWND hwnd, DWORD dwAttribute, PVOID pvAttribute, DWORD cbAttribute) {
+ if( HAS_DWM_EXT( initWindowsDWM() ) ) {
+ return _DwmGetWindowAttribute(hwnd, dwAttribute, pvAttribute, cbAttribute);
+ }
+ return E_NOINTERFACE;
+}
+
+HRESULT DwmSetWindowAttribute(HWND hwnd, DWORD dwAttribute, LPCVOID pvAttribute, DWORD cbAttribute) {
+ if( HAS_DWM_EXT( initWindowsDWM() ) ) {
+ return _DwmSetWindowAttribute(hwnd, dwAttribute, pvAttribute, cbAttribute);
+ }
+ return E_NOINTERFACE;
+}
+
+BOOL IsWindowCompositionExtensionAvailable() {
+ return HAS_WINCOMP_EXT( initWindowsDWM() ) ? TRUE : FALSE;
+}
+
+BOOL GetWindowCompositionAccentPolicy(HWND hwnd, AccentPolicy* pAccentPolicy) {
+ if( HAS_WINCOMP_EXT( initWindowsDWM() ) ) {
+ WINCOMPATTRDATA attrData = { WCA_ACCENT_POLICY, pAccentPolicy, sizeof(AccentPolicy) };
+ return _GetWindowCompositionAttribute(hwnd, &attrData);
+ }
+ return FALSE;
+}
+BOOL SetWindowCompositionAccentPolicy(HWND hwnd, const AccentPolicy* pAccentPolicy) {
+ if( HAS_WINCOMP_EXT( initWindowsDWM() ) ) {
+ WINCOMPATTRDATA attrData = { WCA_ACCENT_POLICY, (AccentPolicy*)pAccentPolicy, sizeof(AccentPolicy) };
+ return _SetWindowCompositionAttribute(hwnd, &attrData);
+ }
+ return FALSE;
+}
+
+#if 0
+BOOL GetWindowCompositionAttribute(HWND hwnd, WINCOMPATTRDATA* pAttrData) {
+ if( HAS_WINCOMP_EXT( initWindowsDWM() ) ) {
+ return _GetWindowCompositionAttribute(hwnd, pAttrData);
+ }
+ return FALSE;
+}
+
+BOOL SetWindowCompositionAttribute(HWND hwnd, WINCOMPATTRDATA* pAttrData) {
+ if( HAS_WINCOMP_EXT( initWindowsDWM() ) ) {
+ return _SetWindowCompositionAttribute(hwnd, pAttrData);
+ }
+ return FALSE;
+}
+#endif
+
diff --git a/src/nativewindow/native/win32/WindowsDWM.h b/src/nativewindow/native/win32/WindowsDWM.h
deleted file mode 100644
index 6e5160fa4..000000000
--- a/src/nativewindow/native/win32/WindowsDWM.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef _WINDOWS_DWM_H_
-#define _WINDOWS_DWM_H_
-
- #include <windows.h>
-
- #define DWM_BB_ENABLE 0x00000001 // fEnable has been specified
- #define DWM_BB_BLURREGION 0x00000002
- #define DWM_BB_TRANSITIONONMAXIMIZED 0x00000004
- #define DWM_EC_DISABLECOMPOSITION 0
- #define DWM_EC_ENABLECOMPOSITION 1
-
- typedef struct _DWM_BLURBEHIND
- {
- DWORD dwFlags;
- BOOL fEnable;
- HRGN hRgnBlur;
- BOOL fTransitionOnMaximized;
- } DWM_BLURBEHIND, *PDWM_BLURBEHIND;
-
- typedef struct _MARGINS
- {
- int cxLeftWidth; // width of left border that retains its size
- int cxRightWidth; // width of right border that retains its size
- int cyTopHeight; // height of top border that retains its size
- int cyBottomHeight; // height of bottom border that retains its size
- } MARGINS, *PMARGINS;
-
- BOOL DwmIsExtensionAvailable();
- BOOL DwmIsCompositionEnabled();
- BOOL DwmEnableComposition( UINT uCompositionAction );
- BOOL DwmEnableBlurBehindWindow(HWND hwnd, const DWM_BLURBEHIND* pBlurBehind);
- BOOL DwmExtendFrameIntoClientArea(HWND hwnd, const MARGINS *pMarInset);
-
-#endif /* _WINDOWS_DWM_H_ */
diff --git a/src/newt/classes/com/jogamp/newt/NewtFactory.java b/src/newt/classes/com/jogamp/newt/NewtFactory.java
index 2ed2194d8..dd15eb3ea 100644
--- a/src/newt/classes/com/jogamp/newt/NewtFactory.java
+++ b/src/newt/classes/com/jogamp/newt/NewtFactory.java
@@ -59,6 +59,7 @@ public class NewtFactory {
public static final String DRIVER_DEFAULT_ROOT_PACKAGE = "jogamp.newt.driver";
private static IOUtil.ClassResources defaultWindowIcons;
+ private static String sysPaths = "newt/data/jogamp-16x16.png newt/data/jogamp-32x32.png";
static {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@@ -67,12 +68,11 @@ public class NewtFactory {
NativeWindowFactory.initSingleton(); // last resort ..
{
/** See API Doc in {@link Window} ! */
- final String[] paths = PropertyAccess.getProperty("newt.window.icons", true, "newt/data/jogamp-16x16.png newt/data/jogamp-32x32.png").split("\\s");
+ final String[] paths = PropertyAccess.getProperty("newt.window.icons", true, sysPaths).split("[\\s,]");
if( paths.length < 2 ) {
throw new IllegalArgumentException("Property 'newt.window.icons' did not specify at least two PNG icons, but "+Arrays.toString(paths));
}
- final Class<?> clazz = NewtFactory.class;
- defaultWindowIcons = new IOUtil.ClassResources(clazz, paths);
+ defaultWindowIcons = new IOUtil.ClassResources(paths, NewtFactory.class.getClassLoader(), null);
}
return null;
} } );
@@ -81,7 +81,7 @@ public class NewtFactory {
/**
* Returns the application window icon resources to be used.
* <p>
- * Property <code>newt.window.icons</code> may define a list of PNG icons separated by a whitespace character.
+ * Property <code>newt.window.icons</code> may define a list of PNG icons separated by one whitespace or one comma character.
* Shall reference at least two PNG icons, from lower (16x16) to higher (>= 32x32) resolution.
* </p>
* <p>
diff --git a/src/newt/classes/com/jogamp/newt/Window.java b/src/newt/classes/com/jogamp/newt/Window.java
index 37147d1ca..30b02cb61 100644
--- a/src/newt/classes/com/jogamp/newt/Window.java
+++ b/src/newt/classes/com/jogamp/newt/Window.java
@@ -83,16 +83,22 @@ import com.jogamp.nativewindow.util.SurfaceSize;
* <a name="customwindowicons"><h5>Custom Window Icons</h5></a>
* <p>
* Custom window icons can be defined via system property <code>newt.window.icons</code>,
- * which shall contain a space separated list of PNG icon locations from low- to high-resolution.
+ * which shall contain a list of PNG icon locations from low- to high-resolution,
+ * separated by one whitespace or one comma character.
* The location must be resolvable via classpath, i.e. shall reference a location within the jar file.
* Example (our default):
* <pre>
- * -Dnewt.window.icons="newt/data/jogamp-16x16.png newt/data/jogamp-32x32.png"
- * -Djnlp.newt.window.icons="newt/data/jogamp-16x16.png newt/data/jogamp-32x32.png"
+ * -Dnewt.window.icons="newt/data/jogamp-16x16.png,newt/data/jogamp-32x32.png"
+ * -Djnlp.newt.window.icons="newt/data/jogamp-16x16.png,newt/data/jogamp-32x32.png"
* </pre>
* The property can also be set programmatically, which must happen before any NEWT classes are <i>touched</i>:
* <pre>
- * System.setProperty("newt.window.icons", "newt/data/jogamp-16x16.png newt/data/jogamp-32x32.png");
+ * System.setProperty("newt.window.icons", "newt/data/jogamp-16x16.png, newt/data/jogamp-32x32.png");
+ * </pre>
+ * To disable even Jogamp's own window icons in favor of system icons,
+ * simply set a non-existing location, e.g.:
+ * <pre>
+ * -Dnewt.window.icons="null,null"
* </pre>
* </p>
*
@@ -125,6 +131,7 @@ public interface Window extends NativeWindow, WindowClosingProtocol, ScalableSur
* <p>Bit number {@value}.</p>
* <p>Defaults to {@code false}.</p>
* @see #getStateMask()
+ * @since 2.3.2
*/
public static final int STATE_BIT_VISIBLE = 0; // reconfig-flag
/**
@@ -134,6 +141,7 @@ public interface Window extends NativeWindow, WindowClosingProtocol, ScalableSur
* <p>Bit number {@value}.</p>
* <p>Defaults to {@code true}.</p>
* @see #getStateMask()
+ * @since 2.3.2
*/
public static final int STATE_BIT_AUTOPOSITION = 1;
/**
@@ -145,6 +153,7 @@ public interface Window extends NativeWindow, WindowClosingProtocol, ScalableSur
* <p>Bit number {@value}.</p>
* <p>Defaults to {@code false}.</p>
* @see #getStateMask()
+ * @since 2.3.2
*/
public static final int STATE_BIT_CHILDWIN = 2; // reconfig-flag
/**
@@ -152,6 +161,7 @@ public interface Window extends NativeWindow, WindowClosingProtocol, ScalableSur
* <p>Bit number {@value}.</p>
* <p>Defaults to {@code false}.</p>
* @see #getStateMask()
+ * @since 2.3.2
*/
public static final int STATE_BIT_FOCUSED = 3;
/**
@@ -159,6 +169,7 @@ public interface Window extends NativeWindow, WindowClosingProtocol, ScalableSur
* <p>Bit number {@value}.</p>
* <p>Defaults to {@code false}.</p>
* @see #getStateMask()
+ * @since 2.3.2
*/
public static final int STATE_BIT_UNDECORATED = 4; // reconfig-flag
/**
@@ -166,6 +177,7 @@ public interface Window extends NativeWindow, WindowClosingProtocol, ScalableSur
* <p>Bit number {@value}.</p>
* <p>Defaults to {@code false}.</p>
* @see #getStateMask()
+ * @since 2.3.2
*/
public static final int STATE_BIT_ALWAYSONTOP = 5; // reconfig-flag
/**
@@ -173,6 +185,7 @@ public interface Window extends NativeWindow, WindowClosingProtocol, ScalableSur
* <p>Bit number {@value}.</p>
* <p>Defaults to {@code false}.</p>
* @see #getStateMask()
+ * @since 2.3.2
*/
public static final int STATE_BIT_ALWAYSONBOTTOM = 6; // reconfig-flag
/**
@@ -180,6 +193,7 @@ public interface Window extends NativeWindow, WindowClosingProtocol, ScalableSur
* <p>Bit number {@value}.</p>
* <p>Defaults to {@code false}.</p>
* @see #getStateMask()
+ * @since 2.3.2
*/
public static final int STATE_BIT_STICKY = 7; // reconfig-flag
/**
@@ -187,6 +201,7 @@ public interface Window extends NativeWindow, WindowClosingProtocol, ScalableSur
* <p>Bit number {@value}.</p>
* <p>Defaults to {@code true}.</p>
* @see #getStateMask()
+ * @since 2.3.2
*/
public static final int STATE_BIT_RESIZABLE = 8; // reconfig-flag
/**
@@ -194,6 +209,7 @@ public interface Window extends NativeWindow, WindowClosingProtocol, ScalableSur
* <p>Bit number {@value}.</p>
* <p>Defaults to {@code false}.</p>
* @see #getStateMask()
+ * @since 2.3.2
*/
public static final int STATE_BIT_MAXIMIZED_VERT = 9; // reconfig-flag
/**
@@ -201,77 +217,127 @@ public interface Window extends NativeWindow, WindowClosingProtocol, ScalableSur
* <p>Bit number {@value}.</p>
* <p>Defaults to {@code false}.</p>
* @see #getStateMask()
+ * @since 2.3.2
*/
public static final int STATE_BIT_MAXIMIZED_HORZ = 10; // reconfig-flag
/**
* Set if window is in <i>fullscreen mode</i>, otherwise cleared.
+ * <p>
+ * Usually fullscreen mode implies {@link #STATE_BIT_UNDECORATED},
+ * however, an implementation is allowed to ignore this if unavailable.
+ * </p>
* <p>Bit number {@value}.</p>
* <p>Defaults to {@code false}.</p>
* @see #getStateMask()
+ * @since 2.3.2
*/
public static final int STATE_BIT_FULLSCREEN = 11; // reconfig-flag
- // Hidden in WindowImpl:
- // static final int STATE_BIT_FULLSCREEN_SPAN = 12;
-
/**
* Set if the <i>pointer is visible</i> when inside the window, otherwise cleared.
* <p>Bit number {@value}.</p>
* <p>Defaults to {@code true}.</p>
* @see #getStateMask()
+ * @since 2.3.2
*/
- public static final int STATE_BIT_POINTERVISIBLE = 13;
+ public static final int STATE_BIT_POINTERVISIBLE = 12;
/**
* Set if the <i>pointer is confined</i> to the window, otherwise cleared.
* <p>Bit number {@value}.</p>
* <p>Defaults to {@code false}.</p>
* @see #getStateMask()
+ * @since 2.3.2
*/
- public static final int STATE_BIT_POINTERCONFINED = 14;
+ public static final int STATE_BIT_POINTERCONFINED = 13;
- /** Bitmask for {@link #STATE_BIT_VISIBLE}, {@value}. */
+ /**
+ * Bitmask for {@link #STATE_BIT_VISIBLE}, {@value}.
+ * @since 2.3.2
+ */
public static final int STATE_MASK_VISIBLE = 1 << STATE_BIT_VISIBLE;
- /** Bitmask for {@link #STATE_BIT_AUTOPOSITION}, {@value}. */
+ /**
+ * Bitmask for {@link #STATE_BIT_AUTOPOSITION}, {@value}.
+ * @since 2.3.2
+ */
public static final int STATE_MASK_AUTOPOSITION = 1 << STATE_BIT_AUTOPOSITION;
- /** Bitmask for {@link #STATE_BIT_CHILDWIN}, {@value}. */
+ /**
+ * Bitmask for {@link #STATE_BIT_CHILDWIN}, {@value}.
+ * @since 2.3.2
+ */
public static final int STATE_MASK_CHILDWIN = 1 << STATE_BIT_CHILDWIN;
- /** Bitmask for {@link #STATE_BIT_FOCUSED}, {@value}. */
+ /**
+ * Bitmask for {@link #STATE_BIT_FOCUSED}, {@value}.
+ * @since 2.3.2
+ */
public static final int STATE_MASK_FOCUSED = 1 << STATE_BIT_FOCUSED;
- /** Bitmask for {@link #STATE_BIT_UNDECORATED}, {@value}. */
+ /**
+ * Bitmask for {@link #STATE_BIT_UNDECORATED}, {@value}.
+ * @since 2.3.2
+ */
public static final int STATE_MASK_UNDECORATED = 1 << STATE_BIT_UNDECORATED;
- /** Bitmask for {@link #STATE_BIT_ALWAYSONTOP}, {@value}. */
+ /**
+ * Bitmask for {@link #STATE_BIT_ALWAYSONTOP}, {@value}.
+ * @since 2.3.2
+ */
public static final int STATE_MASK_ALWAYSONTOP = 1 << STATE_BIT_ALWAYSONTOP;
- /** Bitmask for {@link #STATE_BIT_ALWAYSONBOTTOM}, {@value}. */
+ /**
+ * Bitmask for {@link #STATE_BIT_ALWAYSONBOTTOM}, {@value}.
+ * @since 2.3.2
+ */
public static final int STATE_MASK_ALWAYSONBOTTOM = 1 << STATE_BIT_ALWAYSONBOTTOM;
- /** Bitmask for {@link #STATE_BIT_STICKY}, {@value}. */
+ /**
+ * Bitmask for {@link #STATE_BIT_STICKY}, {@value}.
+ * @since 2.3.2
+ */
public static final int STATE_MASK_STICKY = 1 << STATE_BIT_STICKY;
- /** Bitmask for {@link #STATE_BIT_RESIZABLE}, {@value}. */
+ /**
+ * Bitmask for {@link #STATE_BIT_RESIZABLE}, {@value}.
+ * @since 2.3.2
+ */
public static final int STATE_MASK_RESIZABLE = 1 << STATE_BIT_RESIZABLE;
- /** Bitmask for {@link #STATE_BIT_MAXIMIZED_VERT}, {@value}. */
+ /**
+ * Bitmask for {@link #STATE_BIT_MAXIMIZED_VERT}, {@value}.
+ * @since 2.3.2
+ */
public static final int STATE_MASK_MAXIMIZED_VERT = 1 << STATE_BIT_MAXIMIZED_VERT;
- /** Bitmask for {@link #STATE_BIT_MAXIMIZED_HORZ}, {@value}. */
+ /**
+ * Bitmask for {@link #STATE_BIT_MAXIMIZED_HORZ}, {@value}.
+ * @since 2.3.2
+ */
public static final int STATE_MASK_MAXIMIZED_HORZ = 1 << STATE_BIT_MAXIMIZED_HORZ;
- /** Bitmask for {@link #STATE_BIT_FULLSCREEN}, {@value}. */
+ /**
+ * Bitmask for {@link #STATE_BIT_FULLSCREEN}, {@value}.
+ * @since 2.3.2
+ */
public static final int STATE_MASK_FULLSCREEN = 1 << STATE_BIT_FULLSCREEN;
- /** Bitmask for {@link #STATE_BIT_POINTERVISIBLE}, {@value}. */
+ /**
+ * Bitmask for {@link #STATE_BIT_POINTERVISIBLE}, {@value}.
+ * @since 2.3.2
+ */
public static final int STATE_MASK_POINTERVISIBLE = 1 << STATE_BIT_POINTERVISIBLE;
- /** Bitmask for {@link #STATE_BIT_POINTERCONFINED}, {@value}. */
+ /**
+ * Bitmask for {@link #STATE_BIT_POINTERCONFINED}, {@value}.
+ * @since 2.3.2
+ */
public static final int STATE_MASK_POINTERCONFINED = 1 << STATE_BIT_POINTERCONFINED;
/**
* Number of all public state bits.
* @see #getStateMask()
+ * @since 2.3.2
*/
public int getStatePublicBitCount();
/**
* Bitmask covering all public state bits.
* @see #getStateMask()
+ * @since 2.3.2
*/
public int getStatePublicBitmask();
/**
* Returns the current status mask of this instance.
+ * @see #getSupportedStateMask()
* @see #STATE_MASK_VISIBLE
* @see #STATE_MASK_AUTOPOSITION
* @see #STATE_MASK_CHILDWIN
@@ -286,14 +352,62 @@ public interface Window extends NativeWindow, WindowClosingProtocol, ScalableSur
* @see #STATE_MASK_FULLSCREEN
* @see #STATE_MASK_POINTERVISIBLE
* @see #STATE_MASK_POINTERCONFINED
+ * @since 2.3.2
*/
int getStateMask();
/**
* Returns a string representation of the {@link #getStateMask() current state mask}.
+ * @since 2.3.2
*/
String getStateMaskString();
+ /**
+ * Returns the supported {@link #getStateMask() state mask} of the implementation.
+ * <p>
+ * Implementation provides supported {@link #getStateMask() state mask} values at runtime
+ * <i>after</i> native window creation, i.e. first visibility.
+ * </p>
+ * <p>
+ * Please note that a window's size shall also be allowed to change, i.e. {@link #setSize(int, int)}.
+ * </p>
+ * <p>
+ * Default value is {@link #STATE_MASK_VISIBLE} | {@link #STATE_MASK_FOCUSED} | {@link #STATE_MASK_FULLSCREEN},
+ * i.e. the <b>minimum requirement</b> for all implementations.
+ * </p>
+ * <p>
+ * Before native window creation {@link #getStatePublicBitmask()} is returned,
+ * i.e. it is assumed all features are supported.
+ * </p>
+ * <p>
+ * Semantic of the supported state-mask bits (after native creation, i.e. 1st visibility):
+ * <ul>
+ * <li>{@link #STATE_MASK_VISIBLE}: {@link #setVisible(boolean) Visibility} can be toggled. <b>Minimum requirement</b>.</li>
+ * <li>{@link #STATE_MASK_CHILDWIN}: {@link #reparentWindow(NativeWindow, int, int, int) Native window parenting} is supported.</li>
+ * <li>{@link #STATE_MASK_FOCUSED}: Window {@link #requestFocus() focus management} is supported. <b>Minimum requirement</b>.</li>
+ * <li>{@link #STATE_MASK_UNDECORATED}: {@link #setUndecorated(boolean) Window decoration} can be toggled.</li>
+ * <li>{@link #STATE_MASK_ALWAYSONTOP}: Window can be set {@link #setAlwaysOnTop(boolean) always-on-top}. </li>
+ * <li>{@link #STATE_MASK_ALWAYSONBOTTOM}: Window can be set {@link #setAlwaysOnBottom(boolean) always-on-bottom}. </li>
+ * <li>{@link #STATE_MASK_STICKY}: Window can be set {@link #setSticky(boolean) sticky}.</li>
+ * <li>{@link #STATE_MASK_RESIZABLE}: Window {@link #setResizable(boolean) resizability} can be toggled.</li>
+ * <li>{@link #STATE_MASK_MAXIMIZED_VERT}: Window can be {@link #setMaximized(boolean, boolean) maximized-vertically}. </li>
+ * <li>{@link #STATE_MASK_MAXIMIZED_HORZ}: Window can be {@link #setMaximized(boolean, boolean) maximized-horizontally}. </li>
+ * <li>{@link #STATE_MASK_FULLSCREEN}: Window {@link #setFullscreen(boolean) fullscreen} can be toggled. </li>
+ * <li>{@link #STATE_MASK_POINTERVISIBLE}: Window {@link #setPointerVisible(boolean) pointer visibility} can be toggled. </li>
+ * <li>{@link #STATE_MASK_POINTERCONFINED}: Window {@link #confinePointer(boolean) pointer can be confined}. </li>
+ * </ul>
+ * </p>
+ * @see #getStateMask()
+ * @since 2.3.2
+ */
+ int getSupportedStateMask();
+
+ /**
+ * Returns a string representation of the {@link #getSupportedStateMask() supported state mask}.
+ * @since 2.3.2
+ */
+ String getSupportedStateMaskString();
+
//
// Lifecycle
//
@@ -598,11 +712,13 @@ public interface Window extends NativeWindow, WindowClosingProtocol, ScalableSur
* <p>Operation is ignored if this instance {@link #isChildWindow() is a child window}.</p>
* @see {@link #STATE_BIT_ALWAYSONBOTTOM}
* @see {@link #STATE_MASK_ALWAYSONBOTTOM}
+ * @since 2.3.2
*/
void setAlwaysOnBottom(boolean value);
/**
* @see {@link #STATE_BIT_ALWAYSONBOTTOM}
* @see {@link #STATE_MASK_ALWAYSONBOTTOM}
+ * @since 2.3.2
*/
boolean isAlwaysOnBottom();
@@ -610,11 +726,13 @@ public interface Window extends NativeWindow, WindowClosingProtocol, ScalableSur
* <p>Operation is ignored if this instance {@link #isChildWindow() is a child window}.</p>
* @see {@link #STATE_BIT_RESIZABLE}
* @see {@link #STATE_MASK_RESIZABLE}
+ * @since 2.3.2
*/
void setResizable(final boolean value);
/**
* @see {@link #STATE_BIT_RESIZABLE}
* @see {@link #STATE_MASK_RESIZABLE}
+ * @since 2.3.2
*/
boolean isResizable();
@@ -622,31 +740,35 @@ public interface Window extends NativeWindow, WindowClosingProtocol, ScalableSur
* <p>Operation is ignored if this instance {@link #isChildWindow() is a child window}.</p>
* @see {@link #STATE_BIT_STICKY}
* @see {@link #STATE_MASK_STICKY}
+ * @since 2.3.2
*/
void setSticky(final boolean value);
/**
* @see {@link #STATE_BIT_STICKY}
* @see {@link #STATE_MASK_STICKY}
+ * @since 2.3.2
*/
boolean isSticky();
/**
- * <p>Operation is ignored in {@link #isFullscreen() fullscreen mode}.</p>
* <p>Operation is ignored if this instance {@link #isChildWindow() is a child window}.</p>
* @see {@link #STATE_BIT_MAXIMIZED_HORZ}
* @see {@link #STATE_BIT_MAXIMIZED_VERT}
* @see {@link #STATE_MASK_MAXIMIZED_HORZ}
* @see {@link #STATE_MASK_MAXIMIZED_VERT}
+ * @since 2.3.2
*/
void setMaximized(final boolean horz, final boolean vert);
/**
* @see {@link #STATE_BIT_MAXIMIZED_VERT}
* @see {@link #STATE_MASK_MAXIMIZED_VERT}
+ * @since 2.3.2
*/
boolean isMaximizedVert();
/**
* @see {@link #STATE_BIT_MAXIMIZED_HORZ}
* @see {@link #STATE_MASK_MAXIMIZED_HORZ}
+ * @since 2.3.2
*/
boolean isMaximizedHorz();
diff --git a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
index ae32fd164..a0083b4ea 100644
--- a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
+++ b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
@@ -49,7 +49,9 @@ import java.security.PrivilegedAction;
import java.util.Set;
import com.jogamp.nativewindow.CapabilitiesImmutable;
+import com.jogamp.nativewindow.NativeSurface;
import com.jogamp.nativewindow.NativeWindow;
+import com.jogamp.nativewindow.NativeWindowHolder;
import com.jogamp.nativewindow.OffscreenLayerOption;
import com.jogamp.nativewindow.WindowClosingProtocol;
import com.jogamp.opengl.GLAnimatorControl;
@@ -100,7 +102,7 @@ import com.jogamp.opengl.util.TileRenderer;
* the underlying JAWT mechanism to composite the image, if supported.
*/
@SuppressWarnings("serial")
-public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProtocol, OffscreenLayerOption, AWTPrintLifecycle {
+public class NewtCanvasAWT extends java.awt.Canvas implements NativeWindowHolder, WindowClosingProtocol, OffscreenLayerOption, AWTPrintLifecycle {
public static final boolean DEBUG = Debug.debug("Window");
private final Object sync = new Object();
@@ -110,7 +112,7 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
private Window newtChild = null;
private boolean newtChildAttached = false;
private boolean isOnscreen = true;
- private WindowClosingMode newtChildCloseOp;
+ private WindowClosingMode newtChildCloseOp = WindowClosingMode.DISPOSE_ON_CLOSE;
private final AWTParentWindowAdapter awtWinAdapter;
private final AWTAdapter awtMouseAdapter;
private final AWTAdapter awtKeyAdapter;
@@ -420,10 +422,22 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
return newtChild;
}
- /** @return this AWT Canvas NativeWindow representation, may be null in case {@link #removeNotify()} has been called,
- * or {@link #addNotify()} hasn't been called yet.*/
+ /**
+ * {@inheritDoc}
+ * @return this AWT Canvas {@link NativeWindow} representation, may be null in case {@link #removeNotify()} has been called,
+ * or {@link #addNotify()} hasn't been called yet.
+ */
+ @Override
public NativeWindow getNativeWindow() { return jawtWindow; }
+ /**
+ * {@inheritDoc}
+ * @return this AWT Canvas {@link NativeSurface} representation, may be null in case {@link #removeNotify()} has been called,
+ * or {@link #addNotify()} hasn't been called yet.
+ */
+ @Override
+ public NativeSurface getNativeSurface() { return jawtWindow; }
+
@Override
public WindowClosingMode getDefaultCloseOperation() {
return awtWindowClosingProtocol.getDefaultCloseOperation();
diff --git a/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtApplet1Run.java b/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtApplet1Run.java
index cd53294a1..6bf9f41a6 100644
--- a/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtApplet1Run.java
+++ b/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtApplet1Run.java
@@ -115,7 +115,7 @@ public class JOGLNewtApplet1Run extends Applet {
String glEventListenerClazzName=null;
String glProfileName=null;
- int glSwapInterval=0;
+ int glSwapInterval=1;
boolean glDebug=false;
boolean glTrace=false;
boolean glUndecorated=false;
diff --git a/src/newt/classes/com/jogamp/newt/javafx/NewtCanvasJFX.java b/src/newt/classes/com/jogamp/newt/javafx/NewtCanvasJFX.java
new file mode 100644
index 000000000..e04ed326d
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/javafx/NewtCanvasJFX.java
@@ -0,0 +1,670 @@
+/**
+ * Copyright 2019 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.newt.javafx;
+
+import com.jogamp.common.util.PropertyAccess;
+import com.jogamp.nativewindow.AbstractGraphicsConfiguration;
+import com.jogamp.nativewindow.AbstractGraphicsScreen;
+import com.jogamp.nativewindow.Capabilities;
+import com.jogamp.nativewindow.CapabilitiesImmutable;
+import com.jogamp.nativewindow.GraphicsConfigurationFactory;
+import com.jogamp.nativewindow.NativeSurface;
+import com.jogamp.nativewindow.NativeWindow;
+import com.jogamp.nativewindow.NativeWindowException;
+import com.jogamp.nativewindow.NativeWindowFactory;
+import com.jogamp.nativewindow.NativeWindowHolder;
+import com.jogamp.nativewindow.SurfaceUpdatedListener;
+import com.jogamp.nativewindow.WindowClosingProtocol;
+import com.jogamp.nativewindow.WindowClosingProtocol.WindowClosingMode;
+import com.jogamp.nativewindow.util.Insets;
+import com.jogamp.nativewindow.util.InsetsImmutable;
+import com.jogamp.nativewindow.util.Point;
+import com.jogamp.nativewindow.util.Rectangle;
+import com.jogamp.opengl.GLCapabilities;
+
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.event.EventHandler;
+import javafx.geometry.Bounds;
+import javafx.scene.Scene;
+import javafx.scene.canvas.Canvas;
+import jogamp.newt.Debug;
+import jogamp.newt.javafx.JFXEDTUtil;
+
+import com.jogamp.nativewindow.javafx.JFXAccessor;
+import com.jogamp.newt.Display;
+import com.jogamp.newt.Window;
+import com.jogamp.newt.event.WindowEvent;
+import com.jogamp.newt.util.EDTUtil;
+
+/**
+ * A NEWT based JFX {@link Canvas} specialization allowing a NEWT child {@link Window} to be attached using native parenting.
+ * <p>
+ * {@link NewtCanvasJFX} allows utilizing custom {@link GLCapabilities} settings independent from the JavaFX's window
+ * as well as independent rendering from JavaFX's thread.
+ * </p>
+ * <p>
+ * {@link NewtCanvasJFX} allows native parenting operations before and after
+ * it's belonging Group's Scene has been attached to the JavaFX {@link javafx.stage.Window Window}'s actual native window,
+ * i.e. becoming fully realized and visible.
+ * </p>
+ * <p>
+ * Note that {@link JFXAccessor#runOnJFXThread(boolean, Runnable)} is still used to for certain
+ * mandatory JavaFX lifecycle operation on the JavaFX thread.
+ * </p>
+ */
+public class NewtCanvasJFX extends Canvas implements NativeWindowHolder, WindowClosingProtocol {
+ private static final boolean DEBUG = Debug.debug("Window");
+ private static final boolean USE_JFX_EDT = PropertyAccess.getBooleanProperty("jogamp.newt.javafx.UseJFXEDT", true, true);
+ private volatile javafx.stage.Window parentWindow = null;
+ private volatile AbstractGraphicsScreen screen = null;
+
+ private WindowClosingMode newtChildClosingMode = WindowClosingMode.DISPOSE_ON_CLOSE;
+ private WindowClosingMode closingMode = WindowClosingMode.DISPOSE_ON_CLOSE;
+ private final Rectangle clientArea = new Rectangle();
+
+ private volatile JFXNativeWindow nativeWindow = null;
+ private volatile Window newtChild = null;
+ private volatile boolean newtChildReady = false; // ready if JFXEDTUtil is set and newtChild parented
+ private volatile boolean postSetSize = false; // pending resize
+ private volatile boolean postSetPos = false; // pending pos
+
+ private final EventHandler<javafx.stage.WindowEvent> windowClosingListener = new EventHandler<javafx.stage.WindowEvent>() {
+ public final void handle(final javafx.stage.WindowEvent e) {
+ if( DEBUG ) {
+ System.err.println("NewtCanvasJFX.Event.DISPOSE, "+e+", closeOp "+closingMode);
+ }
+ if( WindowClosingMode.DISPOSE_ON_CLOSE == closingMode ) {
+ NewtCanvasJFX.this.destroy();
+ } else {
+ // avoid JavaFX closing operation
+ e.consume();
+ }
+ } };
+ private final EventHandler<javafx.stage.WindowEvent> windowShownListener = new EventHandler<javafx.stage.WindowEvent>() {
+ public final void handle(final javafx.stage.WindowEvent e) {
+ if( DEBUG ) {
+ System.err.println("NewtCanvasJFX.Event.SHOWN, "+e);
+ }
+ repaintAction(true);
+ } };
+
+ /**
+ * Instantiates a NewtCanvas with a NEWT child.
+ *
+ * <p>
+ * Note: The NEWT child {@link Display}'s {@link EDTUtil} is being set to an JFX conform implementation
+ * via {@link Display#setEDTUtil(EDTUtil)}.
+ * </p>
+ * @param child optional preassigned {@link #Window}, maybe null
+ */
+ public NewtCanvasJFX(final Window child) {
+ super();
+
+ updateParentWindowAndScreen();
+
+ final ChangeListener<Number> sizeListener = new ChangeListener<Number>() {
+ @Override public void changed(final ObservableValue<? extends Number> observable, final Number oldValue, final Number newValue) {
+ if( DEBUG ) {
+ System.err.println("NewtCanvasJFX.Event.Size, "+oldValue.doubleValue()+" -> "+newValue.doubleValue()+", has "+getWidth()+"x"+getHeight());
+ }
+ updateSizeCheck((int)getWidth(), (int)getHeight());
+ repaintAction(isVisible());
+ } };
+ this.widthProperty().addListener(sizeListener);
+ this.heightProperty().addListener(sizeListener);
+ this.visibleProperty().addListener(new ChangeListener<Boolean>() {
+ @Override public void changed(final ObservableValue<? extends Boolean> observable, final Boolean oldValue, final Boolean newValue) {
+ if( DEBUG ) {
+ System.err.println("NewtCanvasJFX.Event.Visible, "+oldValue.booleanValue()+" -> "+newValue.booleanValue()+", has "+isVisible());
+ }
+ repaintAction(newValue.booleanValue());
+ }
+ });
+ this.sceneProperty().addListener(new ChangeListener<Scene>() {
+ @Override public void changed(final ObservableValue<? extends Scene> observable, final Scene oldValue, final Scene newValue) {
+ if( DEBUG ) {
+ System.err.println("NewtCanvasJFX.Event.Scene, "+oldValue+" -> "+newValue+", has "+getScene());
+ if(null != newValue) {
+ final javafx.stage.Window w = newValue.getWindow();
+ System.err.println("NewtCanvasJFX.Event.Scene window "+w+" (showing "+(null!=w?w.isShowing():0)+")");
+ }
+ }
+ if( updateParentWindowAndScreen() ) {
+ repaintAction(isVisible());
+ }
+ }
+ });
+
+ if(null != child) {
+ setNEWTChild(child);
+ }
+ }
+
+ private final void repaintAction(final boolean visible) {
+ if( visible && ( null != nativeWindow || validateNative(true /* completeReparent */) ) ) {
+ if( newtChildReady ) {
+ if( postSetSize ) {
+ newtChild.setSize(clientArea.getWidth(), clientArea.getHeight());
+ postSetSize = false;
+ }
+ if( postSetPos ) {
+ newtChild.setPosition(clientArea.getX(), clientArea.getY());
+ postSetPos = false;
+ }
+ newtChild.windowRepaint(0, 0, clientArea.getWidth(), clientArea.getHeight());
+ }
+ }
+ }
+
+ private final void updatePosSizeCheck() {
+ final Bounds b = localToScene(getBoundsInLocal());
+ updatePosCheck((int)b.getMinX(), (int)b.getMinY());
+ updateSizeCheck((int)getWidth(), (int)getHeight());
+ }
+ private final void updatePosCheck(final int newX, final int newY) {
+ final boolean posChanged;
+ {
+ final Rectangle oClientArea = clientArea;
+ posChanged = newX != oClientArea.getX() || newY != oClientArea.getY();
+ if( posChanged ) {
+ clientArea.setX(newX);
+ clientArea.setY(newY);
+ }
+ }
+ if(DEBUG) {
+ final long nsh = newtChildReady ? newtChild.getSurfaceHandle() : 0;
+ System.err.println("NewtCanvasJFX.updatePosCheck: posChanged "+posChanged+", ("+Thread.currentThread().getName()+"): newtChildReady "+newtChildReady+", "+clientArea.getX()+"/"+clientArea.getY()+" "+clientArea.getWidth()+"x"+clientArea.getHeight()+" - surfaceHandle 0x"+Long.toHexString(nsh));
+ }
+ if( posChanged ) {
+ if( newtChildReady ) {
+ newtChild.setPosition(clientArea.getX(), clientArea.getY());
+ } else {
+ postSetPos = true;
+ }
+ }
+ }
+ private final void updateSizeCheck(final int newWidth, final int newHeight) {
+ final boolean sizeChanged;
+ {
+ final Rectangle oClientArea = clientArea;
+ sizeChanged = newWidth != oClientArea.getWidth() || newHeight != oClientArea.getHeight();
+ if( sizeChanged ) {
+ clientArea.setWidth(newWidth);
+ clientArea.setHeight(newHeight);
+ }
+ }
+ if(DEBUG) {
+ final long nsh = newtChildReady ? newtChild.getSurfaceHandle() : 0;
+ System.err.println("NewtCanvasJFX.updateSizeCheck: sizeChanged "+sizeChanged+", ("+Thread.currentThread().getName()+"): newtChildReady "+newtChildReady+", "+clientArea.getX()+"/"+clientArea.getY()+" "+clientArea.getWidth()+"x"+clientArea.getHeight()+" - surfaceHandle 0x"+Long.toHexString(nsh));
+ }
+ if( sizeChanged ) {
+ if( newtChildReady ) {
+ newtChild.setSize(clientArea.getWidth(), clientArea.getHeight());
+ } else {
+ postSetSize = true;
+ }
+ }
+ }
+
+ private final ChangeListener<javafx.stage.Window> sceneWindowChangeListener = new ChangeListener<javafx.stage.Window>() {
+ @Override public void changed(final ObservableValue<? extends javafx.stage.Window> observable, final javafx.stage.Window oldValue, final javafx.stage.Window newValue) {
+ if( DEBUG ) {
+ System.err.println("NewtCanvasJFX.Event.Window, "+oldValue+" -> "+newValue);
+ }
+ if( updateParentWindowAndScreen() ) {
+ repaintAction(isVisible());
+ }
+ } };
+
+ private boolean updateParentWindowAndScreen() {
+ final Scene s = this.getScene();
+ if( null != s ) {
+ final javafx.stage.Window w = s.getWindow();
+ if( DEBUG ) {
+ System.err.println("NewtCanvasJFX.updateParentWindowAndScreen: Scene "+s+", Window "+w+" (showing "+(null!=w?w.isShowing():0)+")");
+ }
+ if( w != parentWindow ) {
+ destroyImpl(false);
+ }
+ parentWindow = w;
+ if( null != w ) {
+ screen = JFXAccessor.getScreen(JFXAccessor.getDevice(parentWindow), -1 /* default */);
+ parentWindow.addEventHandler(javafx.stage.WindowEvent.WINDOW_CLOSE_REQUEST, windowClosingListener);
+ parentWindow.addEventHandler(javafx.stage.WindowEvent.WINDOW_SHOWN, windowShownListener);
+ return true;
+ } else {
+ s.windowProperty().addListener(sceneWindowChangeListener);
+ }
+ } else {
+ if( DEBUG ) {
+ System.err.println("NewtCanvasJFX.updateParentWindowAndScreen: Null Scene");
+ }
+ if( null != parentWindow ) {
+ destroyImpl(false);
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Destroys this resource:
+ * <ul>
+ * <li> Make the NEWT Child invisible </li>
+ * <li> Disconnects the NEWT Child from this Canvas NativeWindow, reparent to NULL </li>
+ * <li> Issues {@link Window#destroy()} on the NEWT Child</li>
+ * <li> Remove reference to the NEWT Child</li>
+ * </ul>
+ * JavaFX will issue this call when sending out the {@link javafx.stage.WindowEvent#WINDOW_CLOSE_REQUEST} automatically,
+ * if the user has not overridden the default {@link WindowClosingMode#DISPOSE_ON_CLOSE} to {@link WindowClosingMode#DO_NOTHING_ON_CLOSE}
+ * via {@link #setDefaultCloseOperation(com.jogamp.nativewindow.WindowClosingProtocol.WindowClosingMode)}.
+ * @see Window#destroy()
+ * @see #setDefaultCloseOperation(com.jogamp.nativewindow.WindowClosingProtocol.WindowClosingMode)
+ */
+ public void destroy() {
+ destroyImpl(true);
+ }
+ private void destroyImpl(final boolean disposeNewtChild) {
+ if(DEBUG) {
+ System.err.println("NewtCanvasJFX.dispose: (has parent "+(null!=parentWindow)+", hasNative "+(null!=nativeWindow)+",\n\t"+newtChild);
+ }
+ if( null != newtChild ) {
+ if(DEBUG) {
+ System.err.println("NewtCanvasJFX.dispose.1: EDTUtil cur "+newtChild.getScreen().getDisplay().getEDTUtil());
+ }
+ if( null != nativeWindow ) {
+ configureNewtChild(false);
+ newtChild.setVisible(false);
+ newtChild.reparentWindow(null, -1, -1, 0 /* hint */);
+ }
+ if( disposeNewtChild ) {
+ newtChild.destroy();
+ newtChild = null;
+ }
+ }
+ if( null != parentWindow ) {
+ parentWindow.getScene().windowProperty().removeListener(sceneWindowChangeListener);
+ parentWindow.removeEventHandler(javafx.stage.WindowEvent.WINDOW_CLOSE_REQUEST, windowClosingListener);
+ parentWindow.removeEventHandler(javafx.stage.WindowEvent.WINDOW_SHOWN, windowShownListener);
+ parentWindow = null;
+ }
+ if( null != screen ) {
+ screen.getDevice().close();
+ screen = null;
+ }
+ nativeWindow = null;
+ }
+
+ private final boolean validateNative(final boolean completeReparent) {
+ if( null == parentWindow ) {
+ return false;
+ }
+ assert null == nativeWindow;
+ updatePosSizeCheck();
+ if(0 >= clientArea.getWidth() || 0 >= clientArea.getHeight()) {
+ return false;
+ }
+ final long nativeWindowHandle = JFXAccessor.getWindowHandle(parentWindow);
+ if( 0 == nativeWindowHandle ) {
+ return false;
+ }
+ screen.getDevice().open();
+
+ /* Native handle for the control, used to associate with GLContext */
+ final int visualID = JFXAccessor.getNativeVisualID(screen.getDevice(), nativeWindowHandle);
+ final boolean visualIDValid = NativeWindowFactory.isNativeVisualIDValidForProcessing(visualID);
+ if(DEBUG) {
+ System.err.println("NewtCanvasJFX.validateNative() windowHandle 0x"+Long.toHexString(nativeWindowHandle)+", visualID 0x"+Integer.toHexString(visualID)+", valid "+visualIDValid);
+ }
+ if( visualIDValid ) {
+ /* Get the nativewindow-Graphics Device associated with this control (which is determined by the parent Composite).
+ * Note: JFX is owner of the native handle, hence no closing operation will be a NOP. */
+ final CapabilitiesImmutable caps = new Capabilities();
+ final GraphicsConfigurationFactory factory = GraphicsConfigurationFactory.getFactory(screen.getDevice(), caps);
+ final AbstractGraphicsConfiguration config = factory.chooseGraphicsConfiguration( caps, caps, null, screen, visualID );
+ if(DEBUG) {
+ System.err.println("NewtCanvasJFX.validateNative() factory: "+factory+", windowHandle 0x"+Long.toHexString(nativeWindowHandle)+", visualID 0x"+Integer.toHexString(visualID)+", chosen config: "+config);
+ // Thread.dumpStack();
+ }
+ if (null == config) {
+ throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
+ }
+
+ nativeWindow = new JFXNativeWindow(config, nativeWindowHandle);
+ if( completeReparent ) {
+ reparentWindow( true );
+ }
+ }
+
+ return null != nativeWindow;
+ }
+
+ /**
+ * Sets a new NEWT child, provoking reparenting.
+ * <p>
+ * A previously detached <code>newChild</code> will be released to top-level status
+ * and made invisible.
+ * </p>
+ * <p>
+ * Note: When switching NEWT child's, detaching the previous first via <code>setNEWTChild(null)</code>
+ * produced much cleaner visual results.
+ * </p>
+ * <p>
+ * Note: The NEWT child {@link Display}'s {@link EDTUtil} is being set to an JFX conform implementation
+ * via {@link Display#setEDTUtil(EDTUtil)}.
+ * </p>
+ * @return the previous attached newt child.
+ */
+ public Window setNEWTChild(final Window newChild) {
+ final Window prevChild = newtChild;
+ if(DEBUG) {
+ System.err.println("NewtCanvasJFX.setNEWTChild.0: win "+newtWinHandleToHexString(prevChild)+" -> "+newtWinHandleToHexString(newChild));
+ }
+ // remove old one
+ if(null != newtChild) {
+ reparentWindow( false );
+ newtChild = null;
+ }
+ // add new one, reparent only if ready
+ newtChild = newChild;
+ if( null != newtChild && ( null != nativeWindow || validateNative(false /* completeReparent */) ) ) {
+ reparentWindow( true );
+ }
+ return prevChild;
+ }
+
+ private void reparentWindow(final boolean add) {
+ if( null == newtChild ) {
+ return; // nop
+ }
+ if(DEBUG) {
+ System.err.println("NewtCanvasJFX.reparentWindow.0: add="+add+", win "+newtWinHandleToHexString(newtChild)+", EDTUtil: cur "+newtChild.getScreen().getDisplay().getEDTUtil());
+ }
+
+ newtChild.setFocusAction(null); // no AWT focus traversal ..
+ if(add) {
+ assert null != nativeWindow && null != parentWindow;
+ updatePosSizeCheck();
+ final int x = clientArea.getX();
+ final int y = clientArea.getY();
+ final int w = clientArea.getWidth();
+ final int h = clientArea.getHeight();
+
+ if(USE_JFX_EDT) {
+ // setup JFX EDT and start it
+ final Display newtDisplay = newtChild.getScreen().getDisplay();
+ final EDTUtil oldEDTUtil = newtDisplay.getEDTUtil();
+ if( ! ( oldEDTUtil instanceof JFXEDTUtil ) ) {
+ final EDTUtil newEDTUtil = new JFXEDTUtil(newtDisplay);
+ if(DEBUG) {
+ System.err.println("NewtCanvasJFX.reparentWindow.1: replacing EDTUtil "+oldEDTUtil+" -> "+newEDTUtil);
+ }
+ newEDTUtil.start();
+ newtDisplay.setEDTUtil( newEDTUtil );
+ }
+ }
+
+ newtChild.setSize(w, h);
+ newtChild.reparentWindow(nativeWindow, x, y, Window.REPARENT_HINT_BECOMES_VISIBLE);
+ newtChild.setPosition(x, y);
+ newtChild.setVisible(true);
+ configureNewtChild(true);
+ newtChild.sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout to listener
+
+ // force this JFX Canvas to be focus-able,
+ // since it is completely covered by the newtChild (z-order).
+ // FIXME ??? super.requestFocus();
+ } else {
+ configureNewtChild(false);
+ newtChild.setVisible(false);
+ newtChild.reparentWindow(null, -1, -1, 0 /* hints */);
+ }
+ if(DEBUG) {
+ System.err.println("NewtCanvasJFX.reparentWindow.X: add="+add+", win "+newtWinHandleToHexString(newtChild)+", EDTUtil: cur "+newtChild.getScreen().getDisplay().getEDTUtil());
+ }
+ }
+
+ private void configureNewtChild(final boolean attach) {
+ newtChildReady = attach;
+ if( null != newtChild ) {
+ newtChild.setKeyboardFocusHandler(null);
+ if(attach) {
+ newtChildClosingMode = newtChild.setDefaultCloseOperation(WindowClosingMode.DO_NOTHING_ON_CLOSE);
+ } else {
+ newtChild.setFocusAction(null);
+ newtChild.setDefaultCloseOperation(newtChildClosingMode);
+ }
+ }
+ }
+
+ /** @return the current NEWT child */
+ public Window getNEWTChild() {
+ return newtChild;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @return this JFX Canvas {@link NativeWindow} representation, may be null in case it has not been realized
+ */
+ @Override
+ public NativeWindow getNativeWindow() { return nativeWindow; }
+
+ /**
+ * {@inheritDoc}
+ * @return this JFX Canvas {@link NativeSurface} representation, may be null in case it has not been realized
+ */
+ @Override
+ public NativeSurface getNativeSurface() { return nativeWindow; }
+
+ @Override
+ public WindowClosingMode getDefaultCloseOperation() {
+ return closingMode;
+ }
+
+ @Override
+ public WindowClosingMode setDefaultCloseOperation(final WindowClosingMode op) {
+ final WindowClosingMode old = closingMode;
+ closingMode = op;
+ return old;
+ }
+
+
+ boolean isParent() {
+ return null!=newtChild ;
+ }
+
+ boolean isFullscreen() {
+ return null != newtChild && newtChild.isFullscreen();
+ }
+
+ private final void requestFocusNEWTChild() {
+ if( newtChildReady ) {
+ newtChild.setFocusAction(null);
+ newtChild.requestFocus();
+ }
+ }
+
+ @Override
+ public void requestFocus() {
+ NewtCanvasJFX.super.requestFocus();
+ requestFocusNEWTChild();
+ }
+
+ private class JFXNativeWindow implements NativeWindow {
+ private final AbstractGraphicsConfiguration config;
+ private final long nativeWindowHandle;
+ private final InsetsImmutable insets; // only required to allow proper client position calculation on OSX
+
+ public JFXNativeWindow(final AbstractGraphicsConfiguration config, final long nativeWindowHandle) {
+ this.config = config;
+ this.nativeWindowHandle = nativeWindowHandle;
+ this.insets = new Insets(0, 0, 0, 0);
+ }
+
+ @Override
+ public int lockSurface() throws NativeWindowException, RuntimeException {
+ return NativeSurface.LOCK_SUCCESS;
+ }
+
+ @Override
+ public void unlockSurface() { }
+
+ @Override
+ public boolean isSurfaceLockedByOtherThread() {
+ return false;
+ }
+
+ @Override
+ public Thread getSurfaceLockOwner() {
+ return null;
+ }
+
+ @Override
+ public boolean surfaceSwap() {
+ return false;
+ }
+
+ @Override
+ public void addSurfaceUpdatedListener(final SurfaceUpdatedListener l) { }
+
+ @Override
+ public void addSurfaceUpdatedListener(final int index, final SurfaceUpdatedListener l) throws IndexOutOfBoundsException {
+ }
+
+ @Override
+ public void removeSurfaceUpdatedListener(final SurfaceUpdatedListener l) { }
+
+ @Override
+ public long getSurfaceHandle() {
+ return 0;
+ }
+
+ @Override
+ public int getWidth() {
+ return getSurfaceWidth(); // FIXME: Use 'scale' or an actual window-width
+ }
+
+ @Override
+ public int getHeight() {
+ return getSurfaceHeight(); // FIXME: Use 'scale' or an actual window-width
+ }
+
+ @Override
+ public final int[] convertToWindowUnits(final int[] pixelUnitsAndResult) {
+ return pixelUnitsAndResult; // FIXME HiDPI: use 'pixelScale'
+ }
+
+ @Override
+ public final int[] convertToPixelUnits(final int[] windowUnitsAndResult) {
+ return windowUnitsAndResult; // FIXME HiDPI: use 'pixelScale'
+ }
+
+ @Override
+ public int getSurfaceWidth() {
+ return clientArea.getWidth();
+ }
+
+ @Override
+ public int getSurfaceHeight() {
+ return clientArea.getHeight();
+ }
+
+ @Override
+ public final NativeSurface getNativeSurface() { return this; }
+
+ @Override
+ public AbstractGraphicsConfiguration getGraphicsConfiguration() {
+ return config;
+ }
+
+ @Override
+ public long getDisplayHandle() {
+ return config.getScreen().getDevice().getHandle();
+ }
+
+ @Override
+ public int getScreenIndex() {
+ return config.getScreen().getIndex();
+ }
+
+ @Override
+ public void surfaceUpdated(final Object updater, final NativeSurface ns, final long when) { }
+
+ @Override
+ public void destroy() { }
+
+ @Override
+ public NativeWindow getParent() {
+ return null;
+ }
+
+ @Override
+ public long getWindowHandle() {
+ return nativeWindowHandle;
+ }
+
+ @Override
+ public InsetsImmutable getInsets() {
+ return insets;
+ }
+
+ @Override
+ public int getX() {
+ return NewtCanvasJFX.this.clientArea.getX();
+ }
+
+ @Override
+ public int getY() {
+ return NewtCanvasJFX.this.clientArea.getY();
+ }
+
+ @Override
+ public Point getLocationOnScreen(final Point point) {
+ final Point los = NativeWindowFactory.getLocationOnScreen(this); // client window location on screen
+ if(null!=point) {
+ return point.translate(los);
+ } else {
+ return los;
+ }
+ }
+
+ @Override
+ public boolean hasFocus() {
+ return isFocused();
+ }
+ };
+
+ static String newtWinHandleToHexString(final Window w) {
+ return null != w ? toHexString(w.getWindowHandle()) : "nil";
+ }
+ static String toHexString(final long l) {
+ return "0x"+Long.toHexString(l);
+ }
+}
+
diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
index f15c87beb..569780311 100644
--- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
+++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
@@ -246,6 +246,16 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind
}
@Override
+ public final int getSupportedStateMask() {
+ return window.getSupportedStateMask();
+ }
+
+ @Override
+ public final String getSupportedStateMaskString() {
+ return window.getSupportedStateMaskString();
+ }
+
+ @Override
public CapabilitiesChooser setCapabilitiesChooser(final CapabilitiesChooser chooser) {
return window.setCapabilitiesChooser(chooser);
}
diff --git a/src/test/com/jogamp/opengl/test/junit/util/NEWTDemoListener.java b/src/newt/classes/com/jogamp/newt/opengl/util/NEWTDemoListener.java
index b70beae69..568b5d0bb 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/NEWTDemoListener.java
+++ b/src/newt/classes/com/jogamp/newt/opengl/util/NEWTDemoListener.java
@@ -25,28 +25,62 @@
* 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 com.jogamp.newt.opengl.util;
import java.net.URLConnection;
+import java.util.ArrayList;
+import java.util.List;
import com.jogamp.common.util.IOUtil;
import com.jogamp.nativewindow.CapabilitiesImmutable;
import com.jogamp.nativewindow.ScalableSurface;
+import com.jogamp.newt.Window;
import com.jogamp.newt.Display;
import com.jogamp.newt.Display.PointerIcon;
import com.jogamp.newt.event.KeyEvent;
import com.jogamp.newt.event.KeyListener;
-import com.jogamp.newt.event.MouseAdapter;
import com.jogamp.newt.event.MouseEvent;
+import com.jogamp.newt.event.MouseListener;
+import com.jogamp.newt.event.WindowAdapter;
+import com.jogamp.newt.event.WindowEvent;
import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.FPSCounter;
+import com.jogamp.opengl.GL;
+import com.jogamp.opengl.GLAnimatorControl;
+import com.jogamp.opengl.GLAutoDrawable;
+import com.jogamp.opengl.GLDrawable;
+import com.jogamp.opengl.GLRunnable;
import com.jogamp.opengl.util.Gamma;
import com.jogamp.opengl.util.PNGPixelRect;
import jogamp.newt.driver.PNGIcon;
-public class NEWTDemoListener extends MouseAdapter implements KeyListener {
+/**
+ * NEWT {@link GLWindow} Demo functionality
+ * <ul>
+ * <li>SPACE: Toggle animator {@link GLAnimatorControl#pause() pause}/{@link GLAnimatorControl#resume() resume}</li>
+ * <li>A: Toggle window {@link Window#setAlwaysOnTop(boolean) always on top}</li>
+ * <li>B: Toggle window {@link Window#setAlwaysOnBottom(boolean) always on bottom}</li>
+ * <li>C: Toggle different {@link Window#setPointerIcon(PointerIcon) pointer icons}</li>
+ * <li>D: Toggle window {@link Window#setUndecorated(boolean) decoration on/off}</li>
+ * <li>F: Toggle window {@link Window#setFullscreen(boolean) fullscreen on/off}</li>
+ * <li>Three-Finger Double-Tap: Toggle window {@link Window#setFullscreen(boolean) fullscreen on/off}</li>
+ * <li>G: Increase {@link Gamma#setDisplayGamma(GLDrawable, float, float, float) gamma} by 0.1, +SHIFT decrease gamma by 0.1</li>
+ * <li>I: Toggle {@link Window#setPointerVisible(boolean) pointer visbility}</li>
+ * <li>J: Toggle {@link Window#confinePointer(boolean) pointer jail (confine to window)}</li>
+ * <li>M: Toggle {@link Window#setMaximized(boolean, boolean) window maximized}: Y, +CTRL off, +SHIFT toggle X+Y, +ALT X</li>
+ * <li>P: Set window {@link Window#setPosition(int, int) position to 100/100}</li>
+ * <li>Q: Quit</li>
+ * <li>R: Toggle window {@link Window#setResizable(boolean) resizable}</li>
+ * <li>S: Toggle window {@link Window#setSticky(boolean) sticky}</li>
+ * <li>V: Toggle window {@link Window#setVisible(boolean) visibility} for 5s</li>
+ * <li>V: +CTRL: Rotate {@link GL#setSwapInterval(int) swap interval} -1, 0, 1</li>
+ * <li>W: {@link Window#warpPointer(int, int) Warp pointer} to center of window</li>
+ * <li>X: Toggle {@link ScalableSurface#setSurfaceScale(float[]) [{@link ScalableSurface#IDENTITY_PIXELSCALE}, {@link ScalableSurface#AUTOMAX_PIXELSCALE}]</li>
+ * </ul>
+ */
+public class NEWTDemoListener extends WindowAdapter implements KeyListener, MouseListener {
protected final GLWindow glWindow;
- protected final QuitAdapter quitAdapter;
final PointerIcon[] pointerIcons;
int pointerIconIdx = 0;
float gamma = 1f;
@@ -54,20 +88,16 @@ public class NEWTDemoListener extends MouseAdapter implements KeyListener {
float contrast = 1f;
boolean confinedFixedCenter = false;
- public NEWTDemoListener(final GLWindow glWin, final QuitAdapter quitAdapter, final PointerIcon[] pointerIcons) {
+ public NEWTDemoListener(final GLWindow glWin, final PointerIcon[] pointerIcons) {
this.glWindow = glWin;
- this.quitAdapter = quitAdapter;
if( null != pointerIcons ) {
this.pointerIcons = pointerIcons;
} else {
- this.pointerIcons = createPointerIcons(glWindow);
+ this.pointerIcons = createPointerIcons(glWindow.getScreen().getDisplay());
}
}
- public NEWTDemoListener(final GLWindow glWin, final PointerIcon[] pointerIcons) {
- this(glWin, null, pointerIcons);
- }
public NEWTDemoListener(final GLWindow glWin) {
- this(glWin, null, null);
+ this(glWin, null);
}
protected void printlnState(final String prelude) {
@@ -76,17 +106,6 @@ public class NEWTDemoListener extends MouseAdapter implements KeyListener {
protected void printlnState(final String prelude, final String post) {
System.err.println(prelude+": "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getSurfaceWidth()+"x"+glWindow.getSurfaceHeight()+", f "+glWindow.isFullscreen()+", a "+glWindow.isAlwaysOnTop()+", "+glWindow.getInsets()+", state "+glWindow.getStateMaskString()+", "+post);
}
- protected void quitAdapterOff() {
- if( null != quitAdapter ) {
- quitAdapter.enable(false);
- }
- }
- protected void quitAdapterOn() {
- if( null != quitAdapter ) {
- quitAdapter.clear();
- quitAdapter.enable(true);
- }
- }
@Override
public void keyPressed(final KeyEvent e) {
@@ -97,44 +116,38 @@ public class NEWTDemoListener extends MouseAdapter implements KeyListener {
switch(keySymbol) {
case KeyEvent.VK_SPACE:
e.setConsumed(true);
- new Thread() {
+ glWindow.invokeOnCurrentThread(new Runnable() {
public void run() {
if(glWindow.getAnimator().isPaused()) {
glWindow.getAnimator().resume();
} else {
glWindow.getAnimator().pause();
}
- }
- }.run();
+ } } );
break;
case KeyEvent.VK_A:
e.setConsumed(true);
- new Thread() {
+ glWindow.invokeOnNewThread(null, false, new Runnable() {
public void run() {
- final Thread t = glWindow.setExclusiveContextThread(null);
printlnState("[set alwaysontop pre]");
glWindow.setAlwaysOnTop(!glWindow.isAlwaysOnTop());
printlnState("[set alwaysontop post]");
- glWindow.setExclusiveContextThread(t);
- } }.start();
+ } } );
break;
case KeyEvent.VK_B:
e.setConsumed(true);
- new Thread() {
+ glWindow.invokeOnNewThread(null, false, new Runnable() {
public void run() {
- final Thread t = glWindow.setExclusiveContextThread(null);
printlnState("[set alwaysonbottom pre]");
glWindow.setAlwaysOnBottom(!glWindow.isAlwaysOnBottom());
printlnState("[set alwaysonbottom post]");
- glWindow.setExclusiveContextThread(t);
- } }.start();
+ } } );
break;
case KeyEvent.VK_C:
e.setConsumed(true);
- new Thread() {
+ glWindow.invokeOnNewThread(null, false, new Runnable() {
public void run() {
if( null != pointerIcons ) {
- final Thread t = glWindow.setExclusiveContextThread(null);
printlnState("[set pointer-icon pre]");
final PointerIcon currentPI = glWindow.getPointerIcon();
final PointerIcon newPI;
@@ -146,28 +159,23 @@ public class NEWTDemoListener extends MouseAdapter implements KeyListener {
}
glWindow.setPointerIcon( newPI );
printlnState("[set pointer-icon post]", currentPI+" -> "+glWindow.getPointerIcon());
- glWindow.setExclusiveContextThread(t);
}
- } }.start();
+ } } );
break;
case KeyEvent.VK_D:
e.setConsumed(true);
- new Thread() {
+ glWindow.invokeOnNewThread(null, false, new Runnable() {
public void run() {
- final Thread t = glWindow.setExclusiveContextThread(null);
- // while( null != glWindow.getExclusiveContextThread() ) ;
printlnState("[set undecorated pre]");
glWindow.setUndecorated(!glWindow.isUndecorated());
printlnState("[set undecorated post]");
- glWindow.setExclusiveContextThread(t);
- } }.start();
+ } } );
break;
case KeyEvent.VK_F:
e.setConsumed(true);
quitAdapterOff();
- new Thread() {
+ glWindow.invokeOnNewThread(null, false, new Runnable() {
public void run() {
- final Thread t = glWindow.setExclusiveContextThread(null);
printlnState("[set fullscreen pre]");
if( glWindow.isFullscreen() ) {
glWindow.setFullscreen( false );
@@ -179,37 +187,33 @@ public class NEWTDemoListener extends MouseAdapter implements KeyListener {
}
}
printlnState("[set fullscreen post]");
- glWindow.setExclusiveContextThread(t);
quitAdapterOn();
- } }.start();
+ } } );
break;
case KeyEvent.VK_G:
e.setConsumed(true);
- new Thread() {
+ glWindow.invokeOnNewThread(null, false, new Runnable() {
public void run() {
final float newGamma = gamma + ( e.isShiftDown() ? -0.1f : 0.1f );
System.err.println("[set gamma]: "+gamma+" -> "+newGamma);
if( Gamma.setDisplayGamma(glWindow, newGamma, brightness, contrast) ) {
gamma = newGamma;
}
- } }.start();
+ } } );
break;
case KeyEvent.VK_I:
e.setConsumed(true);
- new Thread() {
+ glWindow.invokeOnNewThread(null, false, new Runnable() {
public void run() {
- final Thread t = glWindow.setExclusiveContextThread(null);
printlnState("[set pointer-visible pre]");
glWindow.setPointerVisible(!glWindow.isPointerVisible());
printlnState("[set pointer-visible post]");
- glWindow.setExclusiveContextThread(t);
- } }.start();
+ } } );
break;
case KeyEvent.VK_J:
e.setConsumed(true);
- new Thread() {
+ glWindow.invokeOnNewThread(null, false, new Runnable() {
public void run() {
- final Thread t = glWindow.setExclusiveContextThread(null);
printlnState("[set pointer-confined pre]", "warp-center: "+e.isShiftDown());
final boolean confine = !glWindow.isPointerConfined();
glWindow.confinePointer(confine);
@@ -219,12 +223,11 @@ public class NEWTDemoListener extends MouseAdapter implements KeyListener {
} else if( !confine ) {
setConfinedFixedCenter(false);
}
- glWindow.setExclusiveContextThread(t);
- } }.start();
+ } } );
break;
case KeyEvent.VK_M:
e.setConsumed(true);
- new Thread() {
+ glWindow.invokeOnNewThread(null, false, new Runnable() {
public void run() {
// none: max-v
// alt: max-h
@@ -235,9 +238,9 @@ public class NEWTDemoListener extends MouseAdapter implements KeyListener {
horz = false;
vert = false;
} else if( e.isShiftDown() ) {
- final boolean anyMax = glWindow.isMaximizedHorz() || glWindow.isMaximizedVert();
- horz = !anyMax;
- vert = !anyMax;
+ final boolean bothMax = glWindow.isMaximizedHorz() && glWindow.isMaximizedVert();
+ horz = !bothMax;
+ vert = !bothMax;
} else if( !e.isAltDown() ) {
horz = glWindow.isMaximizedHorz();
vert = !glWindow.isMaximizedVert();
@@ -248,82 +251,102 @@ public class NEWTDemoListener extends MouseAdapter implements KeyListener {
vert = glWindow.isMaximizedVert();
horz = glWindow.isMaximizedHorz();
}
- final Thread t = glWindow.setExclusiveContextThread(null);
printlnState("[set maximize pre]", "max[vert "+vert+", horz "+horz+"]");
glWindow.setMaximized(horz, vert);
printlnState("[set maximize post]", "max[vert "+vert+", horz "+horz+"]");
- glWindow.setExclusiveContextThread(t);
- } }.start();
+ } } );
break;
case KeyEvent.VK_P:
e.setConsumed(true);
- new Thread() {
+ glWindow.invokeOnNewThread(null, false, new Runnable() {
public void run() {
- final Thread t = glWindow.setExclusiveContextThread(null);
printlnState("[set position pre]");
glWindow.setPosition(100, 100);
printlnState("[set position post]");
- glWindow.setExclusiveContextThread(t);
- } }.start();
+ } } );
+ break;
+ case KeyEvent.VK_Q:
+ if( quitAdapterEnabled && 0 == e.getModifiers() ) {
+ System.err.println("QUIT Key "+Thread.currentThread());
+ quitAdapterShouldQuit = true;
+ }
break;
case KeyEvent.VK_R:
e.setConsumed(true);
- new Thread() {
+ glWindow.invokeOnNewThread(null, false, new Runnable() {
public void run() {
- final Thread t = glWindow.setExclusiveContextThread(null);
printlnState("[set resizable pre]");
glWindow.setResizable(!glWindow.isResizable());
printlnState("[set resizable post]");
- glWindow.setExclusiveContextThread(t);
- } }.start();
+ } } );
break;
case KeyEvent.VK_S:
e.setConsumed(true);
- new Thread() {
+ glWindow.invokeOnNewThread(null, false, new Runnable() {
public void run() {
- final Thread t = glWindow.setExclusiveContextThread(null);
printlnState("[set sticky pre]");
glWindow.setSticky(!glWindow.isSticky());
printlnState("[set sticky post]");
- glWindow.setExclusiveContextThread(t);
- } }.start();
+ } } );
break;
case KeyEvent.VK_V:
e.setConsumed(true);
- new Thread() {
- public void run() {
- final boolean wasVisible = glWindow.isVisible();
- {
- final Thread t = glWindow.setExclusiveContextThread(null);
- printlnState("[set visible pre]");
- glWindow.setVisible(!wasVisible);
- printlnState("[set visible post]");
- glWindow.setExclusiveContextThread(t);
- }
- if( wasVisible && !e.isControlDown() ) {
- try {
- Thread.sleep(5000);
- } catch (final InterruptedException e) {
- e.printStackTrace();
+ if( e.isControlDown() ) {
+ glWindow.invoke(false, new GLRunnable() {
+ @Override
+ public boolean run(final GLAutoDrawable drawable) {
+ final GL gl = drawable.getGL();
+ final int _i = gl.getSwapInterval();
+ final int i;
+ switch(_i) {
+ case 0: i = -1; break;
+ case -1: i = 1; break;
+ case 1: i = 0; break;
+ default: i = 1; break;
}
- final Thread t = glWindow.setExclusiveContextThread(null);
- printlnState("[reset visible pre]");
- glWindow.setVisible(true);
- printlnState("[reset visible post]");
- glWindow.setExclusiveContextThread(t);
+ gl.setSwapInterval(i);
+
+ final GLAnimatorControl a = drawable.getAnimator();
+ if( null != a ) {
+ a.resetFPSCounter();
+ }
+ if(drawable instanceof FPSCounter) {
+ ((FPSCounter)drawable).resetFPSCounter();
+ }
+ System.err.println("Swap Interval: "+_i+" -> "+i+" -> "+gl.getSwapInterval());
+ return true;
}
- } }.start();
+ });
+ } else {
+ glWindow.invokeOnNewThread(null, false, new Runnable() {
+ public void run() {
+ final boolean wasVisible = glWindow.isVisible();
+ {
+ printlnState("[set visible pre]");
+ glWindow.setVisible(!wasVisible);
+ printlnState("[set visible post]");
+ }
+ if( wasVisible && !e.isShiftDown() ) {
+ try {
+ java.lang.Thread.sleep(5000);
+ } catch (final InterruptedException e) {
+ e.printStackTrace();
+ }
+ printlnState("[reset visible pre]");
+ glWindow.setVisible(true);
+ printlnState("[reset visible post]");
+ }
+ } } );
+ }
break;
case KeyEvent.VK_W:
e.setConsumed(true);
- new Thread() {
+ glWindow.invokeOnNewThread(null, false, new Runnable() {
public void run() {
- final Thread t = glWindow.setExclusiveContextThread(null);
printlnState("[set pointer-pos pre]");
glWindow.warpPointer(glWindow.getSurfaceWidth()/2, glWindow.getSurfaceHeight()/2);
printlnState("[set pointer-pos post]");
- glWindow.setExclusiveContextThread(t);
- } }.start();
+ } } );
break;
case KeyEvent.VK_X:
e.setConsumed(true);
@@ -365,7 +388,7 @@ public class NEWTDemoListener extends MouseAdapter implements KeyListener {
}
@Override
public void mouseClicked(final MouseEvent e) {
- if(e.getClickCount() == 2 && e.getPointerCount() == 1) {
+ if(e.getClickCount() == 2 && e.getPointerCount() == 3) {
glWindow.setFullscreen(!glWindow.isFullscreen());
System.err.println("setFullscreen: "+glWindow.isFullscreen());
}
@@ -377,6 +400,43 @@ public class NEWTDemoListener extends MouseAdapter implements KeyListener {
glWindow.warpPointer(x, y);
}
}
+ @Override
+ public void mouseEntered(final MouseEvent e) {}
+ @Override
+ public void mouseExited(final MouseEvent e) {}
+ @Override
+ public void mousePressed(final MouseEvent e) {}
+ @Override
+ public void mouseReleased(final MouseEvent e) {}
+ @Override
+ public void mouseWheelMoved(final MouseEvent e) {}
+
+ /////////////////////////////////////////////////////////////
+
+ private boolean quitAdapterShouldQuit = false;
+ private boolean quitAdapterEnabled = false;
+ private boolean quitAdapterEnabled2 = true;
+
+ protected void quitAdapterOff() {
+ quitAdapterEnabled2 = false;
+ }
+ protected void quitAdapterOn() {
+ clearQuitAdapter();
+ quitAdapterEnabled2 = true;
+ }
+ public void quitAdapterEnable(final boolean v) { quitAdapterEnabled = v; }
+ public void clearQuitAdapter() { quitAdapterShouldQuit = false; }
+ public boolean shouldQuit() { return quitAdapterShouldQuit; }
+ public void doQuit() { quitAdapterShouldQuit=true; }
+
+ public void windowDestroyNotify(final WindowEvent e) {
+ if( quitAdapterEnabled && quitAdapterEnabled2 ) {
+ System.err.println("QUIT Window "+Thread.currentThread());
+ quitAdapterShouldQuit = true;
+ }
+ }
+
+ /////////////////////////////////////////////////////////////
public void setTitle() {
setTitle(glWindow);
@@ -389,80 +449,82 @@ public class NEWTDemoListener extends MouseAdapter implements KeyListener {
final float[] sDPI = win.getPixelsPerMM(new float[2]);
sDPI[0] *= 25.4f;
sDPI[1] *= 25.4f;
- win.setTitle("GLWindow["+capsA+"], win: "+win.getBounds()+", pix: "+win.getSurfaceWidth()+"x"+win.getSurfaceHeight()+", sDPI "+sDPI[0]+" x "+sDPI[1]);
+ final float[] minSurfacePixelScale = win.getMinimumSurfaceScale(new float[2]);
+ final float[] maxSurfacePixelScale = win.getMaximumSurfaceScale(new float[2]);
+ final float[] reqSurfacePixelScale = win.getRequestedSurfaceScale(new float[2]);
+ final float[] hasSurfacePixelScale = win.getCurrentSurfaceScale(new float[2]);
+ win.setTitle("GLWindow["+capsA+"], win: "+win.getBounds()+", pix: "+win.getSurfaceWidth()+"x"+win.getSurfaceHeight()+", sDPI "+sDPI[0]+" x "+sDPI[1]+
+ ", scale[min "+minSurfacePixelScale[0]+"x"+minSurfacePixelScale[1]+", max "+
+ maxSurfacePixelScale[0]+"x"+maxSurfacePixelScale[1]+", req "+
+ reqSurfacePixelScale[0]+"x"+reqSurfacePixelScale[1]+" -> has "+
+ hasSurfacePixelScale[0]+"x"+hasSurfacePixelScale[1]+"]");
}
- public static PointerIcon[] createPointerIcons(final GLWindow glWindow) {
- final PointerIcon[] pointerIcons = { null, null, null, null, null };
+ public static PointerIcon[] createPointerIcons(final Display disp) {
+ final List<PointerIcon> pointerIcons = new ArrayList<PointerIcon>();
{
- final Display disp = glWindow.getScreen().getDisplay();
disp.createNative();
- int idx = 0;
{
PointerIcon _pointerIcon = null;
- final IOUtil.ClassResources res = new IOUtil.ClassResources(glWindow.getClass(), new String[] { "newt/data/cross-grey-alpha-16x16.png" } );
+ final IOUtil.ClassResources res = new IOUtil.ClassResources(new String[] { "newt/data/cross-grey-alpha-16x16.png" }, disp.getClass().getClassLoader(), null);
try {
_pointerIcon = disp.createPointerIcon(res, 8, 8);
- System.err.printf("Create PointerIcon #%02d: %s%n", idx, _pointerIcon.toString());
+ pointerIcons.add(_pointerIcon);
+ System.err.printf("Create PointerIcon #%02d: %s%n", pointerIcons.size(), _pointerIcon.toString());
} catch (final Exception e) {
- e.printStackTrace();
+ System.err.println(e.getMessage());
}
- pointerIcons[idx] = _pointerIcon;
}
- idx++;
{
PointerIcon _pointerIcon = null;
- final IOUtil.ClassResources res = new IOUtil.ClassResources(glWindow.getClass(), new String[] { "newt/data/pointer-grey-alpha-16x24.png" } );
+ final IOUtil.ClassResources res = new IOUtil.ClassResources(new String[] { "newt/data/pointer-grey-alpha-16x24.png" }, disp.getClass().getClassLoader(), null);
try {
_pointerIcon = disp.createPointerIcon(res, 0, 0);
- System.err.printf("Create PointerIcon #%02d: %s%n", idx, _pointerIcon.toString());
+ pointerIcons.add(_pointerIcon);
+ System.err.printf("Create PointerIcon #%02d: %s%n", pointerIcons.size(), _pointerIcon.toString());
} catch (final Exception e) {
- e.printStackTrace();
+ System.err.println(e.getMessage());
}
- pointerIcons[idx] = _pointerIcon;
}
- idx++;
{
PointerIcon _pointerIcon = null;
- final IOUtil.ClassResources res = new IOUtil.ClassResources(glWindow.getClass(), new String[] { "arrow-red-alpha-64x64.png" } );
+ final IOUtil.ClassResources res = new IOUtil.ClassResources(new String[] { "arrow-red-alpha-64x64.png" }, disp.getClass().getClassLoader(), null);
try {
_pointerIcon = disp.createPointerIcon(res, 0, 0);
- System.err.printf("Create PointerIcon #%02d: %s%n", idx, _pointerIcon.toString());
+ pointerIcons.add(_pointerIcon);
+ System.err.printf("Create PointerIcon #%02d: %s%n", pointerIcons.size(), _pointerIcon.toString());
} catch (final Exception e) {
- e.printStackTrace();
+ System.err.println(e.getMessage());
}
- pointerIcons[idx] = _pointerIcon;
}
- idx++;
{
PointerIcon _pointerIcon = null;
- final IOUtil.ClassResources res = new IOUtil.ClassResources(glWindow.getClass(), new String[] { "arrow-blue-alpha-64x64.png" } );
+ final IOUtil.ClassResources res = new IOUtil.ClassResources(new String[] { "arrow-blue-alpha-64x64.png" }, disp.getClass().getClassLoader(), null);
try {
_pointerIcon = disp.createPointerIcon(res, 0, 0);
- System.err.printf("Create PointerIcon #%02d: %s%n", idx, _pointerIcon.toString());
+ pointerIcons.add(_pointerIcon);
+ System.err.printf("Create PointerIcon #%02d: %s%n", pointerIcons.size(), _pointerIcon.toString());
} catch (final Exception e) {
- e.printStackTrace();
+ System.err.println(e.getMessage());
}
- pointerIcons[idx] = _pointerIcon;
}
- idx++;
if( PNGIcon.isAvailable() ) {
PointerIcon _pointerIcon = null;
- final IOUtil.ClassResources res = new IOUtil.ClassResources(glWindow.getClass(), new String[] { "jogamp-pointer-64x64.png" } );
+ final IOUtil.ClassResources res = new IOUtil.ClassResources(new String[] { "jogamp-pointer-64x64.png" }, disp.getClass().getClassLoader(), null);
try {
final URLConnection urlConn = res.resolve(0);
- final PNGPixelRect image = PNGPixelRect.read(urlConn.getInputStream(), null, false /* directBuffer */, 0 /* destMinStrideInBytes */, false /* destIsGLOriented */);
- System.err.printf("Create PointerIcon #%02d: %s%n", idx, image.toString());
- _pointerIcon = disp.createPointerIcon(image, 32, 0);
- System.err.printf("Create PointerIcon #%02d: %s%n", idx, _pointerIcon.toString());
+ if( null != urlConn ) {
+ final PNGPixelRect image = PNGPixelRect.read(urlConn.getInputStream(), null, false /* directBuffer */, 0 /* destMinStrideInBytes */, false /* destIsGLOriented */);
+ System.err.printf("Create PointerIcon #%02d: %s%n", pointerIcons.size()+1, image.toString());
+ _pointerIcon = disp.createPointerIcon(image, 32, 0);
+ pointerIcons.add(_pointerIcon);
+ System.err.printf("Create PointerIcon #%02d: %s%n", pointerIcons.size(), _pointerIcon.toString());
+ }
} catch (final Exception e) {
- e.printStackTrace();
+ System.err.println(e.getMessage());
}
- pointerIcons[idx] = _pointerIcon;
}
- idx++;
}
- return pointerIcons;
+ return pointerIcons.toArray(new PointerIcon[pointerIcons.size()]);
}
-
} \ No newline at end of file
diff --git a/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java b/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java
index 186ffb162..d1bd638d8 100644
--- a/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java
+++ b/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java
@@ -38,8 +38,10 @@ import com.jogamp.nativewindow.NativeSurface;
import com.jogamp.nativewindow.NativeWindow;
import com.jogamp.nativewindow.NativeWindowException;
import com.jogamp.nativewindow.NativeWindowFactory;
+import com.jogamp.nativewindow.NativeWindowHolder;
import com.jogamp.nativewindow.SurfaceUpdatedListener;
import com.jogamp.nativewindow.WindowClosingProtocol;
+import com.jogamp.nativewindow.WindowClosingProtocol.WindowClosingMode;
import com.jogamp.nativewindow.util.Insets;
import com.jogamp.nativewindow.util.InsetsImmutable;
import com.jogamp.nativewindow.util.Point;
@@ -70,12 +72,13 @@ import com.jogamp.newt.util.EDTUtil;
* Implementation allows use of custom {@link GLCapabilities}.
* </p>
*/
-public class NewtCanvasSWT extends Canvas implements WindowClosingProtocol {
+public class NewtCanvasSWT extends Canvas implements NativeWindowHolder, WindowClosingProtocol {
private static final boolean DEBUG = Debug.debug("Window");
private final AbstractGraphicsScreen screen;
- private WindowClosingMode newtChildCloseOp = WindowClosingMode.DISPOSE_ON_CLOSE;
+ private WindowClosingMode newtChildClosingMode = WindowClosingMode.DISPOSE_ON_CLOSE;
+ private final WindowClosingMode closingMode = WindowClosingMode.DISPOSE_ON_CLOSE;
private volatile Rectangle clientArea;
private volatile SWTNativeWindow nativeWindow;
@@ -330,17 +333,28 @@ public class NewtCanvasSWT extends Canvas implements WindowClosingProtocol {
return new Point(parentLoc[0].x, parentLoc[0].y);
}
- /** @return this SWT Canvas NativeWindow representation, may be null in case it has not been realized. */
+ /**
+ * {@inheritDoc}
+ * @return this SWT Canvas {@link NativeWindow} representation, may be null in case it has not been realized
+ */
+ @Override
public NativeWindow getNativeWindow() { return nativeWindow; }
+ /**
+ * {@inheritDoc}
+ * @return this SWT Canvas {@link NativeSurface} representation, may be null in case it has not been realized
+ */
+ @Override
+ public NativeSurface getNativeSurface() { return nativeWindow; }
+
@Override
public WindowClosingMode getDefaultCloseOperation() {
- return newtChildCloseOp; // TODO: implement ?!
+ return closingMode;
}
@Override
public WindowClosingMode setDefaultCloseOperation(final WindowClosingMode op) {
- return newtChildCloseOp = op; // TODO: implement ?!
+ return closingMode; // TODO: implement!
}
@@ -401,10 +415,10 @@ public class NewtCanvasSWT extends Canvas implements WindowClosingProtocol {
if( null != newtChild ) {
newtChild.setKeyboardFocusHandler(null);
if(attach) {
- newtChildCloseOp = newtChild.setDefaultCloseOperation(WindowClosingMode.DO_NOTHING_ON_CLOSE);
+ newtChildClosingMode = newtChild.setDefaultCloseOperation(WindowClosingMode.DO_NOTHING_ON_CLOSE);
} else {
newtChild.setFocusAction(null);
- newtChild.setDefaultCloseOperation(newtChildCloseOp);
+ newtChild.setDefaultCloseOperation(newtChildClosingMode);
}
}
}
diff --git a/src/newt/classes/com/jogamp/newt/util/MainThread.java b/src/newt/classes/com/jogamp/newt/util/MainThread.java
index 8bf4bc20f..05df63794 100644
--- a/src/newt/classes/com/jogamp/newt/util/MainThread.java
+++ b/src/newt/classes/com/jogamp/newt/util/MainThread.java
@@ -45,6 +45,7 @@ import java.util.List;
import com.jogamp.nativewindow.NativeWindowFactory;
import com.jogamp.common.os.Platform;
+import com.jogamp.common.util.InterruptSource;
import com.jogamp.common.util.PropertyAccess;
import com.jogamp.common.util.ReflectionUtil;
@@ -171,15 +172,14 @@ public class MainThread {
return res;
}
- static class UserApp extends Thread {
+ static class UserApp extends InterruptSource.Thread {
private final String mainClassNameShort;
private final String mainClassName;
private final String[] mainClassArgs;
private final Method mainClassMain;
- private List<Thread> nonDaemonThreadsAtStart;
+ private List<java.lang.Thread> nonDaemonThreadsAtStart;
public UserApp(final String mainClassName, final String[] mainClassArgs) throws SecurityException, NoSuchMethodException, ClassNotFoundException {
- super();
this.mainClassName=mainClassName;
this.mainClassArgs=mainClassArgs;
@@ -200,10 +200,10 @@ public class MainThread {
@Override
public void run() {
nonDaemonThreadsAtStart = getNonDaemonThreads();
- if(DEBUG) System.err.println("MainAction.run(): "+Thread.currentThread().getName()+" start, nonDaemonThreadsAtStart "+nonDaemonThreadsAtStart);
+ if(DEBUG) System.err.println("MainAction.run(): "+java.lang.Thread.currentThread().getName()+" start, nonDaemonThreadsAtStart "+nonDaemonThreadsAtStart);
// start user app ..
try {
- if(DEBUG) System.err.println("MainAction.run(): "+Thread.currentThread().getName()+" invoke "+mainClassName);
+ if(DEBUG) System.err.println("MainAction.run(): "+java.lang.Thread.currentThread().getName()+" invoke "+mainClassName);
mainClassMain.invoke(null, new Object[] { mainClassArgs } );
} catch (final InvocationTargetException ite) {
ite.getTargetException().printStackTrace();
@@ -219,30 +219,30 @@ public class MainThread {
while( 0 < ( ndtr = getNonDaemonThreadCount(nonDaemonThreadsAtStart) ) ) {
if(DEBUG) System.err.println("MainAction.run(): post user app, non daemon threads alive: "+ndtr);
try {
- Thread.sleep(1000);
+ java.lang.Thread.sleep(1000);
} catch (final InterruptedException e) {
e.printStackTrace();
}
}
- if(DEBUG) System.err.println("MainAction.run(): "+Thread.currentThread().getName()+" user app fin: "+ndtr);
+ if(DEBUG) System.err.println("MainAction.run(): "+java.lang.Thread.currentThread().getName()+" user app fin: "+ndtr);
}
if ( useMainThread ) {
if(isMacOSX) {
try {
if(DEBUG) {
- System.err.println("MainAction.main(): "+Thread.currentThread()+" MainAction fin - stopNSApp.0");
+ System.err.println("MainAction.main(): "+java.lang.Thread.currentThread()+" MainAction fin - stopNSApp.0");
}
ReflectionUtil.callStaticMethod(MACOSXDisplayClassName, "stopNSApplication",
null, null, MainThread.class.getClassLoader());
if(DEBUG) {
- System.err.println("MainAction.main(): "+Thread.currentThread()+" MainAction fin - stopNSApp.X");
+ System.err.println("MainAction.main(): "+java.lang.Thread.currentThread()+" MainAction fin - stopNSApp.X");
}
} catch (final Exception e) {
e.printStackTrace();
}
} else {
- if(DEBUG) System.err.println("MainAction.run(): "+Thread.currentThread().getName()+" MainAction fin - System.exit(0)");
+ if(DEBUG) System.err.println("MainAction.run(): "+java.lang.Thread.currentThread().getName()+" MainAction fin - System.exit(0)");
System.exit(0);
}
}
diff --git a/src/newt/classes/com/jogamp/newt/util/applet/JOGLNewtAppletBase.java b/src/newt/classes/com/jogamp/newt/util/applet/JOGLNewtAppletBase.java
index cc159e6ed..c30576ff4 100644
--- a/src/newt/classes/com/jogamp/newt/util/applet/JOGLNewtAppletBase.java
+++ b/src/newt/classes/com/jogamp/newt/util/applet/JOGLNewtAppletBase.java
@@ -42,10 +42,8 @@ import com.jogamp.opengl.GLPipelineFactory;
import jogamp.newt.Debug;
-import com.jogamp.common.util.IOUtil;
-import com.jogamp.newt.Display;
+import com.jogamp.common.util.InterruptSource;
import com.jogamp.newt.Window;
-import com.jogamp.newt.Display.PointerIcon;
import com.jogamp.newt.event.KeyEvent;
import com.jogamp.newt.event.KeyListener;
import com.jogamp.newt.event.MouseListener;
@@ -53,13 +51,18 @@ import com.jogamp.newt.event.WindowAdapter;
import com.jogamp.newt.event.WindowEvent;
import com.jogamp.newt.event.WindowListener;
import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.newt.opengl.util.NEWTDemoListener;
import com.jogamp.opengl.util.Animator;
import com.jogamp.opengl.util.AnimatorBase;
-/** Shows how to deploy an applet using JOGL. This demo must be
- referenced from a web page via an &lt;applet&gt; tag. */
-
+/**
+ * Shows how to deploy an applet using JOGL.
+ * This demo must be referenced from a web page via an &lt;applet&gt; tag.
+ * <p>
+ * The demo code uses {@link NEWTDemoListener} functionality.
+ * </p>
+ */
public class JOGLNewtAppletBase implements KeyListener, GLEventListener {
public static final boolean DEBUG = Debug.debug("Applet");
@@ -69,7 +72,6 @@ public class JOGLNewtAppletBase implements KeyListener, GLEventListener {
boolean glClosable;
boolean glDebug;
boolean glTrace;
- PointerIcon pointerIconTest = null;
GLEventListener glEventListener = null;
GLWindow glWindow = null;
@@ -193,8 +195,13 @@ public class JOGLNewtAppletBase implements KeyListener, GLEventListener {
glWindow.addKeyListener((KeyListener)glEventListener);
}
+ glWindow.addWindowListener(reparentHomeListener);
+
if(!noDefaultKeyListener) {
glWindow.addKeyListener(this);
+ final NEWTDemoListener newtDemoListener = new NEWTDemoListener(glWindow);
+ glWindow.addKeyListener(newtDemoListener);
+ glWindow.addMouseListener(newtDemoListener);
}
glWindow.setUpdateFPSFrames(FPSCounter.DEFAULT_FRAMES_PER_INTERVAL, System.err);
@@ -220,7 +227,7 @@ public class JOGLNewtAppletBase implements KeyListener, GLEventListener {
null == glWindow.getParent() && null != parentWin && 0 != parentWin.getWindowHandle() )
{
// we may be called directly by the native EDT
- new Thread(new Runnable() {
+ new InterruptSource.Thread(null, new Runnable() {
@Override
public void run() {
if( glWindow.isNativeValid() && null != parentWin && 0 != parentWin.getWindowHandle() ) {
@@ -235,24 +242,13 @@ public class JOGLNewtAppletBase implements KeyListener, GLEventListener {
if(isValid) {
glWindow.setVisible(true);
glWindow.sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED);
- if( null == pointerIconTest ) {
- final IOUtil.ClassResources res = new IOUtil.ClassResources(glWindow.getClass(), new String[] { "newt/data/cross-grey-alpha-16x16.png" } );
- final Display disp = glWindow.getScreen().getDisplay();
- try {
- pointerIconTest = disp.createPointerIcon(res, 8, 8);
- } catch (final Exception e) {
- e.printStackTrace();
- }
- }
glAnimator.start();
parentWin = glWindow.getParent();
- glWindow.addWindowListener(reparentHomeListener);
}
}
public void stop() {
if(null!=glAnimator) {
- glWindow.removeWindowListener(reparentHomeListener);
glAnimator.stop();
glWindow.setVisible(false);
}
@@ -291,10 +287,7 @@ public class JOGLNewtAppletBase implements KeyListener, GLEventListener {
_gl = _gl.getContext().setGL( GLPipelineFactory.create("com.jogamp.opengl.Trace", null, _gl, new Object[] { System.err } ) );
} catch (final Exception e) {e.printStackTrace();}
}
-
- if(glSwapInterval>=0) {
- _gl.setSwapInterval(glSwapInterval);
- }
+ _gl.setSwapInterval(glSwapInterval);
}
@Override
public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height) {
@@ -315,27 +308,14 @@ public class JOGLNewtAppletBase implements KeyListener, GLEventListener {
if( !e.isPrintableKey() || e.isAutoRepeat() ) {
return;
}
- if(e.getKeyChar()=='d') {
- new Thread() {
- public void run() {
- glWindow.setUndecorated(!glWindow.isUndecorated());
- } }.start();
- } if(e.getKeyChar()=='f') {
- new Thread() {
- public void run() {
- glWindow.setFullscreen(!glWindow.isFullscreen());
- } }.start();
- } else if(e.getKeyChar()=='a') {
- new Thread() {
- public void run() {
- glWindow.setAlwaysOnTop(!glWindow.isAlwaysOnTop());
- } }.start();
- } else if(e.getKeyChar()=='r' && null!=parentWin) {
- new Thread() {
+
+ if(e.getKeyChar()=='r' && 0==e.getModifiers() && null!=parentWin) {
+ e.setConsumed(true);
+ glWindow.invokeOnNewThread(null, false, new Runnable() {
public void run() {
if(null == glWindow.getParent()) {
- glWindow.reparentWindow(parentWin, -1, -1, 0 /* hints */);
- } else {
+ glWindow.reparentWindow(parentWin, -1, -1, 0 /* hints */);
+ } else {
final InsetsImmutable insets = glWindow.getInsets();
final int x, y;
if ( 0 >= insets.getTopHeight() ) {
@@ -349,43 +329,13 @@ public class JOGLNewtAppletBase implements KeyListener, GLEventListener {
glWindow.reparentWindow(null, x, y, 0 /* hints */);
glWindow.setDefaultCloseOperation( glClosable ? WindowClosingMode.DISPOSE_ON_CLOSE : WindowClosingMode.DO_NOTHING_ON_CLOSE );
}
- } }.start();
- } else if(e.getKeyChar()=='c') {
- new Thread() {
- public void run() {
- System.err.println("[set pointer-icon pre]");
- final PointerIcon currentPI = glWindow.getPointerIcon();
- glWindow.setPointerIcon( currentPI == pointerIconTest ? null : pointerIconTest);
- System.err.println("[set pointer-icon post] "+currentPI+" -> "+glWindow.getPointerIcon());
- } }.start();
- } else if(e.getKeyChar()=='i') {
- new Thread() {
- public void run() {
- System.err.println("[set mouse visible pre]: "+glWindow.isPointerVisible());
- glWindow.setPointerVisible(!glWindow.isPointerVisible());
- System.err.println("[set mouse visible post]: "+glWindow.isPointerVisible());
- } }.start();
- } else if(e.getKeyChar()=='j') {
- new Thread() {
- public void run() {
- final Thread t = glWindow.setExclusiveContextThread(null);
- System.err.println("[set mouse confined pre]: "+glWindow.isPointerConfined());
- glWindow.confinePointer(!glWindow.isPointerConfined());
- System.err.println("[set mouse confined post]: "+glWindow.isPointerConfined());
- glWindow.setExclusiveContextThread(t);
- } }.start();
- } else if(e.getKeyChar()=='w') {
- new Thread() {
- public void run() {
- System.err.println("[set mouse pos pre]");
- glWindow.warpPointer(glWindow.getSurfaceWidth()/2, glWindow.getSurfaceHeight()/2);
- System.err.println("[set mouse pos post]");
- } }.start();
+ } } );
}
}
@Override
public void keyReleased(final KeyEvent e) {
}
+
}
diff --git a/src/newt/classes/com/jogamp/newt/util/applet3/JOGLNewtApplet3Run.java b/src/newt/classes/com/jogamp/newt/util/applet3/JOGLNewtApplet3Run.java
index 9b9b7d532..fce43d71f 100644
--- a/src/newt/classes/com/jogamp/newt/util/applet3/JOGLNewtApplet3Run.java
+++ b/src/newt/classes/com/jogamp/newt/util/applet3/JOGLNewtApplet3Run.java
@@ -243,7 +243,7 @@ public class JOGLNewtApplet3Run implements Applet3 {
}
this.ctx = ctx;
String glEventListenerClazzName=null;
- int glSwapInterval=0;
+ int glSwapInterval=1;
boolean glDebug=false;
boolean glTrace=false;
boolean glNoDefaultKeyListener = false;
diff --git a/src/newt/classes/jogamp/newt/DefaultEDTUtil.java b/src/newt/classes/jogamp/newt/DefaultEDTUtil.java
index bf46ce609..ff713410b 100644
--- a/src/newt/classes/jogamp/newt/DefaultEDTUtil.java
+++ b/src/newt/classes/jogamp/newt/DefaultEDTUtil.java
@@ -44,6 +44,8 @@ import com.jogamp.nativewindow.NativeWindowException;
import jogamp.common.util.locks.LockDebugUtil;
import com.jogamp.common.ExceptionUtils;
+import com.jogamp.common.util.InterruptSource;
+import com.jogamp.common.util.InterruptedRuntimeException;
import com.jogamp.common.util.RunnableTask;
import com.jogamp.common.util.locks.Lock;
import com.jogamp.newt.util.EDTUtil;
@@ -68,7 +70,7 @@ public class DefaultEDTUtil implements EDTUtil {
this.threadGroup = tg;
this.name=Thread.currentThread().getName()+"-"+name+"-EDT-";
this.dispatchMessages=dispatchMessages;
- this.edt = new NEDT(threadGroup, name);
+ this.edt = new NEDT(threadGroup, this.name);
this.edt.setDaemon(true); // don't stop JVM from shutdown ..
}
@@ -169,8 +171,7 @@ public class DefaultEDTUtil implements EDTUtil {
};
private final boolean invokeImpl(boolean wait, Runnable task, final boolean stop, final boolean provokeError) {
- Throwable throwable = null;
- RunnableTask rTask = null;
+ final RunnableTask rTask;
final Object rTaskLock = new Object();
synchronized(rTaskLock) { // lock the optional task execution
synchronized(edtLock) { // lock the EDT status
@@ -187,6 +188,7 @@ public class DefaultEDTUtil implements EDTUtil {
task.run();
}
wait = false; // running in same thread (EDT) -> no wait
+ rTask = null;
if( stop ) {
edt.shouldStop = true;
if( edt.tasks.size()>0 ) {
@@ -230,18 +232,19 @@ public class DefaultEDTUtil implements EDTUtil {
}
} else {
wait = false;
+ rTask = null;
}
}
}
if( wait ) {
try {
- rTaskLock.wait(); // free lock, allow execution of rTask
+ while( rTask.isInQueue() ) {
+ rTaskLock.wait(); // free lock, allow execution of rTask
+ }
} catch (final InterruptedException ie) {
- throwable = ie;
- }
- if(null==throwable) {
- throwable = rTask.getThrowable();
+ throw new InterruptedRuntimeException(ie);
}
+ final Throwable throwable = rTask.getThrowable();
if(null!=throwable) {
if(throwable instanceof NativeWindowException) {
throw (NativeWindowException)throwable;
@@ -268,13 +271,13 @@ public class DefaultEDTUtil implements EDTUtil {
return false;
}
synchronized(_edt.tasks) {
- while(_edt.isRunning && _edt.tasks.size()>0) {
- try {
+ try {
+ while(_edt.isRunning && _edt.tasks.size()>0) {
_edt.tasks.notifyAll();
_edt.tasks.wait();
- } catch (final InterruptedException e) {
- e.printStackTrace();
}
+ } catch (final InterruptedException e) {
+ throw new InterruptedRuntimeException(e);
}
return true;
}
@@ -284,12 +287,12 @@ public class DefaultEDTUtil implements EDTUtil {
final public boolean waitUntilStopped() {
synchronized(edtLock) {
if(edt.isRunning && edt != Thread.currentThread() ) {
- while( edt.isRunning ) {
- try {
+ try {
+ while( edt.isRunning ) {
edtLock.wait();
- } catch (final InterruptedException e) {
- e.printStackTrace();
}
+ } catch (final InterruptedException e) {
+ throw new InterruptedRuntimeException(e);
}
return true;
} else {
@@ -298,13 +301,13 @@ public class DefaultEDTUtil implements EDTUtil {
}
}
- class NEDT extends Thread {
+ class NEDT extends InterruptSource.Thread {
volatile boolean shouldStop = false;
volatile boolean isRunning = false;
final ArrayList<RunnableTask> tasks = new ArrayList<RunnableTask>(); // one shot tasks
public NEDT(final ThreadGroup tg, final String name) {
- super(tg, name);
+ super(tg, null, name);
}
final public boolean isRunning() {
@@ -347,11 +350,11 @@ public class DefaultEDTUtil implements EDTUtil {
RunnableTask task = null;
synchronized(tasks) {
// wait for tasks
- if(!shouldStop && tasks.size()==0) {
+ if( !shouldStop && tasks.size()==0 ) {
try {
tasks.wait(pollPeriod);
} catch (final InterruptedException e) {
- e.printStackTrace();
+ throw new InterruptedRuntimeException(e);
}
}
// execute one task, if available
@@ -375,7 +378,7 @@ public class DefaultEDTUtil implements EDTUtil {
}
if(!task.hasWaiter() && null != task.getThrowable()) {
// at least dump stack-trace in case nobody waits for result
- System.err.println("DefaultEDT.run(): Caught exception occured on thread "+Thread.currentThread().getName()+": "+task.toString());
+ System.err.println("DefaultEDT.run(): Caught exception occured on thread "+java.lang.Thread.currentThread().getName()+": "+task.toString());
task.getThrowable().printStackTrace();
}
}
diff --git a/src/newt/classes/jogamp/newt/DisplayImpl.java b/src/newt/classes/jogamp/newt/DisplayImpl.java
index cc1f3d8e0..61a39c133 100644
--- a/src/newt/classes/jogamp/newt/DisplayImpl.java
+++ b/src/newt/classes/jogamp/newt/DisplayImpl.java
@@ -37,6 +37,7 @@ package jogamp.newt;
import com.jogamp.common.ExceptionUtils;
import com.jogamp.common.nio.Buffers;
import com.jogamp.common.util.IOUtil;
+import com.jogamp.common.util.InterruptedRuntimeException;
import com.jogamp.common.util.ReflectionUtil;
import com.jogamp.newt.Display;
import com.jogamp.newt.NewtFactory;
@@ -117,6 +118,8 @@ public abstract class DisplayImpl extends Display {
return null;
}
final PointerIconImpl[] res = { null };
+ final Exception[] ex = { null };
+ final String exStr = "Could not resolve "+pngResource.resourcePaths[0];
runOnEDTIfAvail(true, new Runnable() {
public void run() {
try {
@@ -125,7 +128,7 @@ public abstract class DisplayImpl extends Display {
}
final URLConnection urlConn = pngResource.resolve(0);
if( null == urlConn ) {
- throw new IOException("Could not resolve "+pngResource.resourcePaths[0]);
+ throw new IOException(exStr);
}
final PNGPixelRect image = PNGPixelRect.read(urlConn.getInputStream(),
getNativePointerIconPixelFormat(),
@@ -137,20 +140,32 @@ public abstract class DisplayImpl extends Display {
if( DEBUG_POINTER_ICON ) {
System.err.println("createPointerIconPNG.0: "+image+", handle: "+toHexString(handle)+", hot "+hotspot);
}
- if( 0 != handle ) {
- res[0] = new PointerIconImpl(DisplayImpl.this, image, hotspot, handle);
- if( DEBUG_POINTER_ICON ) {
- System.err.println("createPointerIconPNG.0: "+res[0]);
- }
+ if( 0 == handle ) {
+ throw new IOException(exStr);
+ }
+ res[0] = new PointerIconImpl(DisplayImpl.this, image, hotspot, handle);
+ if( DEBUG_POINTER_ICON ) {
+ System.err.println("createPointerIconPNG.0: "+res[0]);
}
} catch (final Exception e) {
- e.printStackTrace();
+ ex[0] = e;
}
} } );
- if( null != res[0] ) {
- synchronized(pointerIconList) {
- pointerIconList.add(res[0]);
+ if( null != ex[0] ) {
+ final Exception e = ex[0];
+ if( e instanceof IllegalArgumentException) {
+ throw new IllegalArgumentException(e);
}
+ if( e instanceof IllegalStateException) {
+ throw new IllegalStateException(e);
+ }
+ throw new IOException(e);
+ }
+ if( null == res[0] ) {
+ throw new IOException(exStr);
+ }
+ synchronized(pointerIconList) {
+ pointerIconList.add(res[0]);
}
return res[0];
}
@@ -697,8 +712,9 @@ public abstract class DisplayImpl extends Display {
} else {
throw re;
}
+ } finally {
+ eventTask.notifyCaller();
}
- eventTask.notifyCaller();
}
@Override
@@ -725,7 +741,10 @@ public abstract class DisplayImpl extends Display {
}
if( null != _events ) {
for (int i=0; i < _events.size(); i++) {
- dispatchMessage(_events.get(i));
+ final NEWTEventTask e = _events.get(i);
+ if( !e.isDispatched() ) {
+ dispatchMessage(e);
+ }
}
}
}
@@ -759,11 +778,12 @@ public abstract class DisplayImpl extends Display {
haveEvents = true;
eventsLock.notifyAll();
}
- if( wait ) {
+ while( wait && !eTask.isDispatched() ) {
try {
lock.wait();
} catch (final InterruptedException ie) {
- throw new RuntimeException(ie);
+ eTask.setDispatched(); // Cancels NEWTEvent ..
+ throw new InterruptedRuntimeException(ie);
}
if( null != eTask.getException() ) {
throw eTask.getException();
diff --git a/src/newt/classes/jogamp/newt/OffscreenWindow.java b/src/newt/classes/jogamp/newt/OffscreenWindow.java
index 09e318957..f4b8ecd42 100644
--- a/src/newt/classes/jogamp/newt/OffscreenWindow.java
+++ b/src/newt/classes/jogamp/newt/OffscreenWindow.java
@@ -42,7 +42,6 @@ import com.jogamp.nativewindow.GraphicsConfigurationFactory;
import com.jogamp.nativewindow.MutableSurface;
import com.jogamp.nativewindow.NativeWindowException;
import com.jogamp.nativewindow.VisualIDHolder;
-import com.jogamp.nativewindow.util.Insets;
import com.jogamp.nativewindow.util.Point;
import com.jogamp.newt.MonitorDevice;
@@ -116,6 +115,10 @@ public class OffscreenWindow extends WindowImpl implements MutableSurface {
return false; // nop
}
+ @Override
+ protected final int getSupportedReconfigMaskImpl() {
+ return minimumReconfigStateMask;
+ }
@Override
protected boolean reconfigureWindowImpl(final int x, final int y, final int width, final int height, final int flags) {
@@ -147,10 +150,5 @@ public class OffscreenWindow extends WindowImpl implements MutableSurface {
protected Point getLocationOnScreenImpl(final int x, final int y) {
return new Point(x,y);
}
-
- @Override
- protected void updateInsetsImpl(final Insets insets) {
- // nop ..
- }
}
diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java
index 241192c6c..0d395b970 100644
--- a/src/newt/classes/jogamp/newt/WindowImpl.java
+++ b/src/newt/classes/jogamp/newt/WindowImpl.java
@@ -73,6 +73,7 @@ import com.jogamp.common.util.locks.RecursiveLock;
import com.jogamp.newt.Display;
import com.jogamp.newt.Display.PointerIcon;
import com.jogamp.newt.MonitorDevice;
+import com.jogamp.newt.MonitorMode;
import com.jogamp.newt.NewtFactory;
import com.jogamp.newt.Screen;
import com.jogamp.newt.Window;
@@ -95,11 +96,12 @@ import com.jogamp.newt.event.WindowUpdateEvent;
public abstract class WindowImpl implements Window, NEWTEventConsumer
{
public static final boolean DEBUG_TEST_REPARENT_INCOMPATIBLE;
+ private static final boolean DEBUG_FREEZE_AT_VISIBILITY_FAILURE;
static {
Debug.initSingleton();
DEBUG_TEST_REPARENT_INCOMPATIBLE = PropertyAccess.isPropertyDefined("newt.test.Window.reparent.incompatible", true);
-
+ DEBUG_FREEZE_AT_VISIBILITY_FAILURE = PropertyAccess.isPropertyDefined("newt.debug.Window.visibility.failure.freeze", true);
ScreenImpl.initSingleton();
}
@@ -147,7 +149,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
private static final PointerType[] constMousePointerTypes = new PointerType[] { PointerType.Mouse };
//
- // Volatile: Multithread Mutable Access
+ // Volatile: Multithreaded Mutable Access
//
private volatile long windowHandle = 0; // lifecycle critical
private volatile int pixWidth = 128, pixHeight = 128; // client-area size w/o insets in pixel units, default: may be overwritten by user
@@ -173,8 +175,6 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
protected CapabilitiesChooser capabilitiesChooser = null; // default null -> default
private List<MonitorDevice> fullscreenMonitors = null;
- private final RectangleImmutable undefSize = new Rectangle(0, 0, 0, 0);
- private final Rectangle minmax_size = new Rectangle(undefSize); // current min/max size or undef
private int nfs_width, nfs_height, nfs_x, nfs_y; // non fullscreen client-area size/pos w/o insets
private NativeWindow nfs_parent = null; // non fullscreen parent, in case explicit reparenting is performed (offscreen)
private String title = "Newt Window";
@@ -182,6 +182,25 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
private LifecycleHook lifecycleHook = null;
//
+ // Quirks
+ //
+
+ /**
+ * Bug 1249 and Bug 1250: Visibility issues on X11
+ * <ul>
+ * <li>setVisible(false) IconicState not listening to _NET_WM_STATE_HIDDEN</li>
+ * <li>setVisible(true) not restoring from _NET_WM_STATE_HIDDEN</li>
+ * </ul>
+ * <p>
+ * If {@code true} fall back to traditional visibility state,
+ * i.e. {@code fast=true}.
+ * </p>
+ */
+ protected static final int QUIRK_BIT_VISIBILITY = 0;
+ /** Quirk mask */
+ protected static final Bitfield quirks = Bitfield.Factory.synchronize(Bitfield.Factory.create(32));
+
+ //
// State Mask
//
@@ -189,50 +208,60 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
* Number of all public state bits, {@value}.
* <p>Defaults to {@code false}.</p>
* @see #getStateMask()
+ * @since 2.3.2
*/
- protected static final int STATE_BIT_COUNT_ALL_PUBLIC = 15;
+ protected static final int STATE_BIT_COUNT_ALL_PUBLIC = STATE_BIT_POINTERCONFINED + 1;
/** Bitmask for {@link #STATE_BIT_COUNT_ALL_PUBLIC} */
protected static final int STATE_MASK_ALL_PUBLIC = ( 1 << STATE_BIT_COUNT_ALL_PUBLIC ) - 1;
//
- // Additional private state-mask bits and mask values
+ // Additional private reconfigure state-mask bits and mask values
//
- /**
- * <p>Bit number {@value}.</p>
- * <p>Defaults to {@code false}.</p>
- * @see #getStateMask()
- */
- /* pp */ static final int STATE_BIT_FULLSCREEN_SPAN = 12;
- /* pp */ static final int PSTATE_BIT_MINMAXSIZE_SET = 27;
- /* pp */ static final int PSTATE_BIT_FOCUS_CHANGE_BROKEN = 28;
- /* pp */ static final int PSTATE_BIT_FULLSCREEN_MAINMONITOR = 29; // true
- /* pp */ static final int PSTATE_BIT_FULLSCREEN_NFS_ALWAYSONTOP = 30; // non fullscreen alwaysOnTop setting
- /* pp */ static final int PSTATE_BIT_FULLSCREEN_NFS_RESIZABLE = 31; // non fullscreen resizable setting
+ protected static final int STATE_BIT_FULLSCREEN_SPAN = STATE_BIT_COUNT_ALL_PUBLIC;
+
+ protected static final int STATE_BIT_COUNT_ALL_RECONFIG = STATE_BIT_FULLSCREEN_SPAN + 1;
+ /** Bitmask for {@link #STATE_BIT_COUNT_ALL_RECONFIG} */
+ protected static final int STATE_MASK_ALL_RECONFIG = ( 1 << STATE_BIT_COUNT_ALL_RECONFIG ) - 1;
+
+ protected static final int STATE_MASK_ALL_PUBLIC_SUPPORTED = STATE_MASK_ALL_PUBLIC & ~STATE_MASK_AUTOPOSITION;
+
+ //
+ // Additional private non-reconfigure state-mask bits and mask values
+ //
+
+ /* pp */ static final int PSTATE_BIT_FOCUS_CHANGE_BROKEN = 30;
+ /* pp */ static final int PSTATE_BIT_FULLSCREEN_MAINMONITOR = 31; // true
/** Bitmask for {@link #STATE_BIT_FULLSCREEN_SPAN}, {@value}. */
/* pp */ static final int STATE_MASK_FULLSCREEN_SPAN = 1 << STATE_BIT_FULLSCREEN_SPAN;
+
/* pp */ static final int PSTATE_MASK_FOCUS_CHANGE_BROKEN = 1 << PSTATE_BIT_FOCUS_CHANGE_BROKEN;
/* pp */ static final int PSTATE_MASK_FULLSCREEN_MAINMONITOR = 1 << PSTATE_BIT_FULLSCREEN_MAINMONITOR;
- /* pp */ static final int PSTATE_MASK_FULLSCREEN_NFS_ALWAYSONTOP = 1 << PSTATE_BIT_FULLSCREEN_NFS_ALWAYSONTOP;
- /* pp */ static final int PSTATE_MASK_FULLSCREEN_NFS_RESIZABLE = 1 << PSTATE_BIT_FULLSCREEN_NFS_RESIZABLE;
+
+ /**
+ * Mask covering all preserved non-fullscreen (NFS) states
+ * while in fullscreen mode.
+ */
+ private static final int STATE_MASK_FULLSCREEN_NFS = STATE_MASK_ALWAYSONTOP |
+ STATE_MASK_RESIZABLE |
+ STATE_MASK_MAXIMIZED_VERT |
+ STATE_MASK_MAXIMIZED_HORZ;
/**
* Reconfig mask for createNativeImpl(..) taking out from {@link #getStateMask()}:
* <ul>
- * <li>{@link #STATE_MASK_VISIBLE}</li>
* <li>{@link #STATE_MASK_FULLSCREEN}</li>
* <li>{@link #STATE_MASK_POINTERVISIBLE}</li>
* <li>{@link #STATE_MASK_POINTERCONFINED}</li>
* </ul>
* Above taken out states are achieved from caller createNative() 'manually'.
+ * @since 2.3.2
*/
- protected final int STATE_MASK_CREATENATIVE = STATE_MASK_UNDECORATED |
- STATE_MASK_ALWAYSONTOP |
- STATE_MASK_ALWAYSONBOTTOM |
- STATE_MASK_STICKY |
- STATE_MASK_RESIZABLE |
- STATE_MASK_MAXIMIZED_VERT |
- STATE_MASK_MAXIMIZED_HORZ;
+ protected static final int STATE_MASK_CREATENATIVE = STATE_MASK_ALL_PUBLIC &
+ ~( STATE_MASK_FULLSCREEN |
+ STATE_MASK_POINTERVISIBLE |
+ STATE_MASK_POINTERCONFINED
+ );
//
// Additional private state-mask mask values for reconfiguration only
// (keep in sync w/ src/newt/native/Window.h)
@@ -249,15 +278,28 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
protected static final int CHANGE_MASK_MAXIMIZED_HORZ = 1 << 22;
protected static final int CHANGE_MASK_FULLSCREEN = 1 << 21;
+ /** Regular state mask */
/* pp */ final Bitfield stateMask = Bitfield.Factory.synchronize(Bitfield.Factory.create(32));
+ /** Non fullscreen state mask */
+ private final Bitfield stateMaskNFS = Bitfield.Factory.synchronize(Bitfield.Factory.create(32));
+
+ /** Default is all but {@link #STATE_MASK_FULLSCREEN_SPAN}. */
+ protected int supportedReconfigStateMask = 0;
+ /** See {@link #getSupportedStateMask()}, i.e. {@link #STATE_MASK_VISIBLE} | {@link #STATE_MASK_FOCUSED} | {@link STATE_MASK_FULLSCREEN}. */
+ protected static final int minimumReconfigStateMask = STATE_MASK_VISIBLE | STATE_MASK_FOCUSED | STATE_MASK_FULLSCREEN;
+
/* pp */ final void resetStateMask() {
stateMask.clearField(false);
- stateMask.set(STATE_BIT_AUTOPOSITION);
- stateMask.put(STATE_BIT_CHILDWIN, null != parentWindow);
- stateMask.set(STATE_BIT_RESIZABLE);
- stateMask.set(STATE_BIT_POINTERVISIBLE);
- stateMask.set(PSTATE_BIT_FULLSCREEN_NFS_RESIZABLE);
- stateMask.set(PSTATE_BIT_FULLSCREEN_MAINMONITOR);
+ stateMask.put32(0, 32,
+ STATE_MASK_AUTOPOSITION |
+ ( null != parentWindow ? STATE_MASK_CHILDWIN : 0 ) |
+ STATE_MASK_RESIZABLE |
+ STATE_MASK_POINTERVISIBLE |
+ PSTATE_MASK_FULLSCREEN_MAINMONITOR);
+ stateMaskNFS.clearField(false);
+ normPosSizeStored[0] = false;
+ normPosSizeStored[1] = false;
+ supportedReconfigStateMask = STATE_MASK_ALL_RECONFIG;
}
@Override
@@ -273,16 +315,29 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
public final int getStateMask() {
return stateMask.get32(0, STATE_BIT_COUNT_ALL_PUBLIC);
}
+
@Override
public final String getStateMaskString() {
return appendStateBits(new StringBuilder(), stateMask.get32(0, STATE_BIT_COUNT_ALL_PUBLIC), false).toString();
}
+ @Override
+ public final int getSupportedStateMask() {
+ return supportedReconfigStateMask & STATE_MASK_ALL_PUBLIC_SUPPORTED;
+ }
+
+ @Override
+ public final String getSupportedStateMaskString() {
+ return appendStateBits(new StringBuilder(), getSupportedStateMask(), true).toString();
+ }
+
protected static StringBuilder appendStateBits(final StringBuilder sb, final int mask, final boolean showChangeFlags) {
sb.append("[");
- if( showChangeFlags && 0 != ( CHANGE_MASK_VISIBILITY & mask) ) {
- sb.append("*");
+ if( showChangeFlags ) {
+ if( 0 != ( CHANGE_MASK_VISIBILITY & mask) ) {
+ sb.append("*");
+ }
if( 0 != ( CHANGE_MASK_VISIBILITY_FAST & mask) ) {
sb.append("*");
}
@@ -292,9 +347,11 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
sb.append((0 != ( STATE_MASK_AUTOPOSITION & mask))?"autopos, ":"");
- if( showChangeFlags && 0 != ( CHANGE_MASK_PARENTING & mask) ) {
- sb.append("*");
- sb.append((0 != ( STATE_MASK_CHILDWIN & mask))?"child":"top");
+ if( showChangeFlags ) {
+ if( 0 != ( CHANGE_MASK_PARENTING & mask) ) {
+ sb.append("*");
+ }
+ sb.append((0 != ( STATE_MASK_CHILDWIN & mask))?"child":"toplevel");
sb.append(", ");
} else if( 0 != ( STATE_MASK_CHILDWIN & mask) ) {
sb.append("child");
@@ -303,8 +360,10 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
sb.append((0 != ( STATE_MASK_FOCUSED & mask))?"focused, ":"");
- if( showChangeFlags && 0 != ( CHANGE_MASK_DECORATION & mask) ) {
- sb.append("*");
+ if( showChangeFlags ) {
+ if( 0 != ( CHANGE_MASK_DECORATION & mask) ) {
+ sb.append("*");
+ }
sb.append((0 != ( STATE_MASK_UNDECORATED & mask))?"undecor":"decor");
sb.append(", ");
} else if( 0 != ( STATE_MASK_UNDECORATED & mask) ) {
@@ -312,8 +371,10 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
sb.append(", ");
}
- if( showChangeFlags && 0 != ( CHANGE_MASK_ALWAYSONTOP & mask) ) {
- sb.append("*");
+ if( showChangeFlags ) {
+ if( 0 != ( CHANGE_MASK_ALWAYSONTOP & mask) ) {
+ sb.append("*");
+ }
sb.append((0 != ( STATE_MASK_ALWAYSONTOP & mask))?"aontop":"!aontop");
sb.append(", ");
} else if( 0 != ( STATE_MASK_ALWAYSONTOP & mask) ) {
@@ -321,8 +382,10 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
sb.append(", ");
}
- if( showChangeFlags && 0 != ( CHANGE_MASK_ALWAYSONBOTTOM & mask) ) {
- sb.append("*");
+ if( showChangeFlags ) {
+ if( 0 != ( CHANGE_MASK_ALWAYSONBOTTOM & mask) ) {
+ sb.append("*");
+ }
sb.append((0 != ( STATE_MASK_ALWAYSONBOTTOM & mask))?"aonbottom":"!aonbottom");
sb.append(", ");
} else if( 0 != ( STATE_MASK_ALWAYSONBOTTOM & mask) ) {
@@ -330,8 +393,10 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
sb.append(", ");
}
- if( showChangeFlags && 0 != ( CHANGE_MASK_STICKY & mask) ) {
- sb.append("*");
+ if( showChangeFlags ) {
+ if( 0 != ( CHANGE_MASK_STICKY & mask) ) {
+ sb.append("*");
+ }
sb.append((0 != ( STATE_MASK_STICKY & mask))?"sticky":"unsticky");
sb.append(", ");
} else if( 0 != ( STATE_MASK_STICKY & mask) ) {
@@ -339,8 +404,10 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
sb.append(", ");
}
- if( showChangeFlags && 0 != ( CHANGE_MASK_RESIZABLE & mask) ) {
- sb.append("*");
+ if( showChangeFlags ) {
+ if( 0 != ( CHANGE_MASK_RESIZABLE & mask) ) {
+ sb.append("*");
+ }
sb.append((0 != ( STATE_MASK_RESIZABLE & mask))?"resizable":"unresizable");
sb.append(", ");
} else if( 0 == ( STATE_MASK_RESIZABLE & mask) ) {
@@ -348,21 +415,23 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
sb.append(", ");
}
- if( showChangeFlags && 0 != ( ( CHANGE_MASK_MAXIMIZED_HORZ | CHANGE_MASK_MAXIMIZED_VERT ) & mask) ) {
+ if( showChangeFlags ) {
sb.append("max[");
- if( 0 != ( STATE_MASK_MAXIMIZED_HORZ & mask) ) {
- if( 0 != ( CHANGE_MASK_MAXIMIZED_HORZ & mask) ) {
- sb.append("*");
- }
- sb.append("h");
- sb.append(", ");
+ if( 0 != ( CHANGE_MASK_MAXIMIZED_HORZ & mask) ) {
+ sb.append("*");
}
- if( 0 != ( STATE_MASK_MAXIMIZED_VERT & mask) ) {
- if( 0 != ( CHANGE_MASK_MAXIMIZED_VERT & mask) ) {
- sb.append("*");
- }
- sb.append("v");
+ if( 0 == ( STATE_MASK_MAXIMIZED_HORZ & mask) ) {
+ sb.append("!");
+ }
+ sb.append("h");
+ sb.append(", ");
+ if( 0 != ( CHANGE_MASK_MAXIMIZED_VERT & mask) ) {
+ sb.append("*");
+ }
+ if( 0 == ( STATE_MASK_MAXIMIZED_VERT & mask) ) {
+ sb.append("!");
}
+ sb.append("v");
sb.append("], ");
} else if( 0 != ( ( STATE_MASK_MAXIMIZED_HORZ | STATE_MASK_MAXIMIZED_VERT ) & mask) ) {
sb.append("max[");
@@ -375,28 +444,47 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
sb.append("], ");
}
- if( showChangeFlags && 0 != ( CHANGE_MASK_FULLSCREEN & mask) ) {
- sb.append("*");
- sb.append((0 != ( STATE_MASK_FULLSCREEN & mask))?"fullscreen":"window");
- sb.append((0 != ( STATE_MASK_FULLSCREEN_SPAN & mask))?"[span]":"[]");
- sb.append(", ");
+ if( showChangeFlags ) {
+ if( 0 != ( CHANGE_MASK_FULLSCREEN & mask) ) {
+ sb.append("*");
+ }
+ sb.append("fullscreen[");
+ sb.append(0 != ( STATE_MASK_FULLSCREEN & mask));
+ sb.append((0 != ( STATE_MASK_FULLSCREEN_SPAN & mask))?", span":"");
+ sb.append("], ");
} else if( 0 != ( STATE_MASK_FULLSCREEN & mask) ) {
sb.append("fullscreen");
sb.append(", ");
}
- if( 0 == ( STATE_MASK_POINTERVISIBLE & mask) ||
- 0 != ( STATE_MASK_POINTERCONFINED & mask) )
- {
- sb.append("pointer[");
- if( 0 == ( STATE_MASK_POINTERVISIBLE & mask) ) {
- sb.append("invisible");
+ if( showChangeFlags ) {
+ sb.append("pointer[");
+ if( 0 == ( STATE_MASK_POINTERVISIBLE & mask) ) {
+ sb.append("invisible");
+ } else {
+ sb.append("visible");
+ }
sb.append(", ");
+ if( 0 != ( STATE_MASK_POINTERCONFINED & mask) ) {
+ sb.append("confined");
+ } else {
+ sb.append("free");
+ }
+ sb.append("]");
+ } else {
+ if( 0 == ( STATE_MASK_POINTERVISIBLE & mask) ||
+ 0 != ( STATE_MASK_POINTERCONFINED & mask) )
+ {
+ sb.append("pointer[");
+ if( 0 == ( STATE_MASK_POINTERVISIBLE & mask) ) {
+ sb.append("invisible");
+ sb.append(", ");
+ }
+ if( 0 != ( STATE_MASK_POINTERCONFINED & mask) ) {
+ sb.append("confined");
+ }
+ sb.append("]");
}
- if( 0 != ( STATE_MASK_POINTERCONFINED & mask) ) {
- sb.append("confined");
- }
- sb.append("]");
}
sb.append("]");
return sb;
@@ -661,15 +749,37 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
final long t0 = System.currentTimeMillis();
createNativeImpl();
+ supportedReconfigStateMask = getSupportedReconfigMaskImpl() & STATE_MASK_ALL_RECONFIG;
+ if( DEBUG_IMPLEMENTATION) {
+ final boolean minimumOK = minimumReconfigStateMask == ( minimumReconfigStateMask & supportedReconfigStateMask );
+ System.err.println("Supported Reconfig (minimum-ok "+minimumOK+"): "+appendStateBits(new StringBuilder(), supportedReconfigStateMask, true).toString());
+ }
screen.addMonitorModeListener(monitorModeListenerImpl);
setTitleImpl(title);
setPointerIconIntern(pointerIcon);
- setPointerVisibleIntern(stateMask.get(STATE_BIT_POINTERVISIBLE));
- confinePointerImpl(stateMask.get(STATE_BIT_POINTERCONFINED));
+ if( !stateMask.get(STATE_BIT_POINTERVISIBLE) ) {
+ // non default action
+ if( isReconfigureMaskSupported(STATE_MASK_POINTERVISIBLE) ) {
+ setPointerVisibleIntern(stateMask.get(STATE_BIT_POINTERVISIBLE));
+ } else {
+ stateMask.set(STATE_BIT_POINTERVISIBLE);
+ }
+ }
+ if( stateMask.get(STATE_BIT_POINTERCONFINED) ) {
+ // non default action
+ if( isReconfigureMaskSupported(STATE_MASK_POINTERCONFINED) ) {
+ confinePointerImpl(true);
+ } else {
+ stateMask.clear(STATE_BIT_POINTERCONFINED);
+ }
+ }
setKeyboardVisible(keyboardVisible);
final long remainingV = waitForVisible(true, false);
if( 0 <= remainingV ) {
- if(isFullscreen()) {
+ if( stateMask.get(STATE_BIT_FULLSCREEN) && !isReconfigureMaskSupported(STATE_MASK_FULLSCREEN) ) {
+ stateMask.clear(STATE_BIT_FULLSCREEN);
+ }
+ if( stateMask.get(STATE_BIT_FULLSCREEN) ) {
synchronized(fullScreenAction) {
stateMask.clear(STATE_BIT_FULLSCREEN); // trigger a state change
fullScreenAction.init(true);
@@ -838,6 +948,17 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
protected abstract void requestFocusImpl(boolean force);
/**
+ * Returns the reconfigure state-mask supported by the implementation.
+ * <p>
+ * Default value is {@link #STATE_MASK_VISIBLE} | {@link #STATE_MASK_FOCUSED},
+ * i.e. the <b>minimum requirement</b> for all implementations.
+ * </p>
+ * @see #getSupportedStateMask()
+ * @see #reconfigureWindowImpl(int, int, int, int, int)
+ */
+ protected abstract int getSupportedReconfigMaskImpl();
+
+ /**
* The native implementation should invoke the referenced java state callbacks
* to notify this Java object of state changes.
*
@@ -852,33 +973,33 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
* @param height client-area size in window units, or <=0 if unchanged
* @param flags bitfield of change and status flags
*
+ * @see #getSupportedReconfigMaskImpl()
* @see #sizeChanged(int,int)
* @see #positionChanged(boolean,int, int)
*/
protected abstract boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags);
/**
- * Tests whether a single reconfigure flag is supported by implementation.
- * <p>
- * Default is all but {@link #STATE_MASK_FULLSCREEN_SPAN}
- * </p>
+ * Tests whether the given reconfigure state-mask is supported by implementation.
*/
- protected boolean isReconfigureMaskSupported(final int changeFlags) {
- return 0 == ( changeFlags & STATE_MASK_FULLSCREEN_SPAN );
+ protected final boolean isReconfigureMaskSupported(final int reconfigMask) {
+ return reconfigMask == ( reconfigMask & supportedReconfigStateMask );
}
protected int getReconfigureMask(final int changeFlags, final boolean visible) {
- final int smask = stateMask.get32(0, STATE_BIT_COUNT_ALL_PUBLIC);
+ final int smask = stateMask.get32(0, STATE_BIT_COUNT_ALL_RECONFIG);
return changeFlags
- | ( smask & ~STATE_MASK_VISIBLE )
+ | ( smask & ~(STATE_MASK_VISIBLE | STATE_MASK_UNDECORATED | STATE_MASK_CHILDWIN) )
| ( visible ? STATE_MASK_VISIBLE : 0 )
| ( isUndecorated(smask) ? STATE_MASK_UNDECORATED : 0 )
+ | ( 0 != getParentWindowHandle() ? STATE_MASK_CHILDWIN : 0 )
;
}
protected static String getReconfigStateMaskString(final int flags) {
return appendStateBits(new StringBuilder(), flags, true).toString();
}
+
protected void setTitleImpl(final String title) {}
/**
@@ -896,16 +1017,6 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
*/
protected abstract Point getLocationOnScreenImpl(int x, int y);
- /**
- * Triggered by user via {@link #getInsets()}.<br>
- * Implementations may implement this hook to update the insets.<br>
- * However, they may prefer the event driven path via {@link #insetsChanged(boolean, int, int, int, int)}.
- *
- * @see #getInsets()
- * @see #insetsChanged(boolean, int, int, int, int)
- */
- protected abstract void updateInsetsImpl(Insets insets);
-
protected boolean setPointerVisibleImpl(final boolean pointerVisible) { return false; }
protected boolean confinePointerImpl(final boolean confine) { return false; }
protected void warpPointerImpl(final int x, final int y) { }
@@ -1114,9 +1225,10 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
reconfigureWindowImpl(x, y, width, height, mask);
}
+
final void setVisibleActionImpl(final boolean visible) {
boolean nativeWindowCreated = false;
- boolean madeVisible = false;
+ int madeVisible = -1;
final RecursiveLock _lock = windowLock;
_lock.lock();
@@ -1134,16 +1246,31 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
if(!isNativeValid() && visible) {
if( 0<getWidth()*getHeight() ) {
nativeWindowCreated = createNative();
- madeVisible = nativeWindowCreated;
+ madeVisible = nativeWindowCreated ? 1 : -1;
}
// always flag visible, allowing a retry ..
stateMask.set(STATE_BIT_VISIBLE);
} else if(stateMask.get(STATE_BIT_VISIBLE) != visible) {
if(isNativeValid()) {
// Skip WM if child-window!
- setVisibleImpl(visible /* visible */, isChildWindow() /* fast */, getX(), getY(), getWidth(), getHeight());
- WindowImpl.this.waitForVisible(visible, false);
- madeVisible = visible;
+ final boolean hasVisibilityQuirk = quirks.get(QUIRK_BIT_VISIBILITY);
+ setVisibleImpl(visible /* visible */, hasVisibilityQuirk || isChildWindow() /* fast */,
+ getX(), getY(), getWidth(), getHeight());
+ if( 0 > WindowImpl.this.waitForVisible(visible, false) ) {
+ if( !hasVisibilityQuirk ) {
+ quirks.set(QUIRK_BIT_VISIBILITY);
+ if( DEBUG_IMPLEMENTATION ) {
+ System.err.println("Setting VISIBILITY QUIRK, due to setVisible("+visible+") failure");
+ }
+ setVisibleImpl(visible /* visible */, true /* fast */,
+ getX(), getY(), getWidth(), getHeight());
+ if( 0 <= WindowImpl.this.waitForVisible(visible, false) ) {
+ madeVisible = visible ? 1 : 0;
+ } // else: still not working .. bail out
+ } // else: no other remedy known .. bail out
+ } else {
+ madeVisible = visible ? 1 : 0;
+ }
} else {
stateMask.set(STATE_BIT_VISIBLE);
}
@@ -1175,7 +1302,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
_lock.unlock();
}
- if( nativeWindowCreated || madeVisible ) {
+ if( nativeWindowCreated || 1==madeVisible ) {
sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener
}
}
@@ -1194,6 +1321,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
@Override
public final void setVisible(final boolean wait, final boolean visible) {
+ if( !isReconfigureMaskSupported(STATE_MASK_VISIBLE) && isNativeValid() ) {
+ return;
+ }
if(DEBUG_IMPLEMENTATION) {
System.err.println("Window setVisible: START ("+getThreadName()+") "+getX()+"/"+getY()+" "+getWidth()+"x"+getHeight()+", windowHandle "+toHexString(windowHandle)+", state "+getStateMaskString()+" -> visible "+visible+", parentWindowHandle "+toHexString(parentWindowHandle)+", parentWindow "+(null!=parentWindow));
}
@@ -1270,7 +1400,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
@Override
public final void setTopLevelSize(final int width, final int height) {
- setSize(width - getInsets().getTotalWidth(), height - getInsets().getTotalHeight());
+ final InsetsImmutable insets = getInsets();
+ setSize(width - insets.getTotalWidth(), height - insets.getTotalHeight());
}
private final Runnable destroyAction = new Runnable() {
@@ -1782,6 +1913,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
@Override
public final ReparentOperation reparentWindow(final NativeWindow newParent, final int x, final int y, final int hints) {
+ if( !isReconfigureMaskSupported(STATE_MASK_CHILDWIN) && isNativeValid() ) {
+ return ReparentOperation.ACTION_INVALID;
+ }
final ReparentAction reparentAction = new ReparentAction(newParent, x, y, hints);
runOnEDTIfAvail(true, reparentAction);
return reparentAction.getOp();
@@ -1843,6 +1977,15 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
@Override
public final void setUndecorated(final boolean value) {
+ if( isNativeValid() ) {
+ if( !isReconfigureMaskSupported(STATE_MASK_UNDECORATED) ) {
+ return;
+ }
+ if( isFullscreen() ) {
+ stateMaskNFS.put(STATE_MASK_UNDECORATED, value);
+ return;
+ }
+ }
runOnEDTIfAvail(true, new DecorationAction(value));
}
@Override
@@ -1866,7 +2009,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
_lock.lock();
try {
if( stateMask.put(STATE_BIT_ALWAYSONTOP, alwaysOnTop) != alwaysOnTop ) {
- if( isNativeValid() ) {
+ if( isNativeValid() && !isFullscreen() ) {
// Mirror pos/size so native change notification can get overwritten
final int x = getX();
final int y = getY();
@@ -1890,17 +2033,22 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
if( isChildWindow() ) {
return; // ignore for child windows
}
- if( isFullscreen() ) {
- if( value && isAlwaysOnBottom() ) {
- setAlwaysOnBottom(false);
+ if( isNativeValid() ) {
+ if( !isReconfigureMaskSupported(STATE_MASK_ALWAYSONTOP) ) {
+ return;
}
- stateMask.put(PSTATE_BIT_FULLSCREEN_NFS_ALWAYSONTOP, value);
- } else {
- if( value && isAlwaysOnBottom() ) {
- setAlwaysOnBottom(false);
+ if( isFullscreen() ) {
+ if( value && isAlwaysOnBottom() ) {
+ setAlwaysOnBottom(false);
+ }
+ stateMaskNFS.put(STATE_BIT_ALWAYSONTOP, value);
+ return;
}
- runOnEDTIfAvail(true, new AlwaysOnTopAction(value));
}
+ if( value && isAlwaysOnBottom() ) {
+ setAlwaysOnBottom(false);
+ }
+ runOnEDTIfAvail(true, new AlwaysOnTopAction(value));
}
@Override
public final boolean isAlwaysOnTop() {
@@ -1944,6 +2092,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
if( isChildWindow() ) {
return; // ignore for child windows
}
+ if( !isReconfigureMaskSupported(STATE_MASK_ALWAYSONBOTTOM) && isNativeValid() ) {
+ return;
+ }
if( value && isAlwaysOnTop() ) {
setAlwaysOnTop(false);
}
@@ -1991,11 +2142,16 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
if( isChildWindow() ) {
return; // ignore for child windows
}
- if( isFullscreen() ) {
- stateMask.put(PSTATE_BIT_FULLSCREEN_NFS_RESIZABLE, value);
- } else {
- runOnEDTIfAvail(true, new ResizableAction(value));
+ if( isNativeValid() ) {
+ if( !isReconfigureMaskSupported(STATE_MASK_RESIZABLE) ) {
+ return;
+ }
+ if( isFullscreen() ) {
+ stateMaskNFS.put(STATE_BIT_RESIZABLE, value);
+ return;
+ }
}
+ runOnEDTIfAvail(true, new ResizableAction(value));
}
@Override
public final boolean isResizable() {
@@ -2039,6 +2195,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
if( isChildWindow() ) {
return; // ignore for child windows
}
+ if( !isReconfigureMaskSupported(STATE_MASK_STICKY) && isNativeValid() ) {
+ return;
+ }
runOnEDTIfAvail(true, new StickyAction(value));
}
@Override
@@ -2068,6 +2227,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
if( 0 != cmask ) {
if( isNativeValid() ) {
+ final boolean focused = hasFocus();
// Mirror pos/size so native change notification can get overwritten
final int x = getX();
final int y = getY();
@@ -2079,6 +2239,10 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
reconfigureWindowImpl(x, y, width, height, getReconfigureMask(cmask, isVisible()));
display.dispatchMessagesNative(); // status up2date
+
+ if(focused) {
+ requestFocusInt( 0 == parentWindowHandle /* skipFocusAction if top-level */);
+ }
}
}
} finally {
@@ -2088,11 +2252,24 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
}
@Override
- public final void setMaximized(final boolean horz, final boolean vert) {
- if( isChildWindow() || isFullscreen() ) {
+ public final void setMaximized(boolean horz, boolean vert) {
+ if( isNativeValid() ) {
+ if( horz && !isReconfigureMaskSupported(STATE_MASK_MAXIMIZED_HORZ) ) {
+ horz = false;
+ }
+ if( vert && !isReconfigureMaskSupported(STATE_MASK_MAXIMIZED_VERT) ) {
+ vert = false;
+ }
+ }
+ if( isChildWindow() ) {
return; // ignore for child windows
}
- runOnEDTIfAvail(true, new MaximizeAction(horz, vert));
+ if( isFullscreen() ) {
+ stateMaskNFS.put(STATE_BIT_MAXIMIZED_HORZ, horz);
+ stateMaskNFS.put(STATE_BIT_MAXIMIZED_VERT, vert);
+ } else {
+ runOnEDTIfAvail(true, new MaximizeAction(horz, vert));
+ }
}
@Override
public final boolean isMaximizedVert() {
@@ -2102,6 +2279,93 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
public final boolean isMaximizedHorz() {
return stateMask.get(STATE_BIT_MAXIMIZED_HORZ);
}
+ /** Triggered by implementation's WM events to update maximized window state. */
+ protected final void maximizedChanged(final boolean newMaxHorz, final boolean newMaxVert) {
+ if( !isFullscreen() ) {
+ final String stateMask0 = DEBUG_IMPLEMENTATION ? getStateMaskString() : null;
+ final boolean changedHorz = stateMask.put(STATE_BIT_MAXIMIZED_HORZ, newMaxHorz) != newMaxHorz;
+ final boolean changedVert = stateMask.put(STATE_BIT_MAXIMIZED_VERT, newMaxVert) != newMaxVert;
+ if ( DEBUG_IMPLEMENTATION ) {
+ if( changedHorz || changedVert ) {
+ System.err.println("Window.maximizedChanged.accepted: "+stateMask0+" -> "+getStateMaskString());
+ }
+ }
+ } else if( DEBUG_IMPLEMENTATION ) {
+ final String stateMask0 = DEBUG_IMPLEMENTATION ? getStateMaskString() : null;
+ final boolean changedHorz = stateMask.get(STATE_BIT_MAXIMIZED_HORZ) != newMaxHorz;
+ final boolean changedVert = stateMask.get(STATE_BIT_MAXIMIZED_VERT) != newMaxVert;
+ if( changedHorz || changedVert ) {
+ System.err.println("Window.maximizedChanged.ignored: "+stateMask0+" -> max["+(newMaxHorz?"":"!")+"h, "+(newMaxVert?"":"!")+"v]");
+ }
+ }
+ }
+ /**
+ * Manually calculate maximized and de-maximized position and size
+ * not regarding a fixed taskbar etc.
+ * <p>
+ * Use only if:
+ * <code>
+ * 0 != ( ( CHANGE_MASK_MAXIMIZED_HORZ | CHANGE_MASK_MAXIMIZED_VERT ) & flags )
+ * </code>
+ * </p>
+ * @param flags
+ * @param posSize
+ */
+ protected void reconfigMaximizedManual(final int flags, final int posSize[], final InsetsImmutable insets) {
+ //if( 0 != ( ( CHANGE_MASK_MAXIMIZED_HORZ | CHANGE_MASK_MAXIMIZED_VERT ) & flags ) ) {
+ final MonitorMode mm = getMainMonitor().getCurrentMode();
+ // FIXME HiDPI: Shortcut, may need to adjust if we change scaling methodology
+ final int mmWidth = SurfaceScaleUtils.scaleInv(mm.getRotatedWidth(), getPixelScaleX());
+ final int mmHeight = SurfaceScaleUtils.scaleInv(mm.getRotatedHeight(), getPixelScaleY());
+
+ if( 0 != ( CHANGE_MASK_MAXIMIZED_HORZ & flags ) ) {
+ if( 0 != ( STATE_MASK_MAXIMIZED_HORZ & flags ) ) {
+ // max-h on
+ normPosSizeStored[0] = true;
+ normPosSize[0] = posSize[0];
+ normPosSize[2] = posSize[2];
+ posSize[0] = insets.getLeftWidth();
+ posSize[2] = mmWidth - insets.getTotalWidth();
+ } else {
+ // max-h off
+ normPosSizeStored[0] = false;
+ posSize[0] = normPosSize[0];
+ posSize[2] = normPosSize[2];
+ }
+ }
+ if( 0 != ( CHANGE_MASK_MAXIMIZED_VERT & flags ) ) {
+ if( 0 != ( STATE_MASK_MAXIMIZED_VERT & flags ) ) {
+ // max-v on
+ normPosSizeStored[1] = true;
+ normPosSize[1] = posSize[1];
+ normPosSize[3] = posSize[3];
+ posSize[1] = insets.getTopHeight();
+ posSize[3] = mmHeight - insets.getTotalHeight();
+ } else {
+ // max-v off
+ normPosSizeStored[1] = false;
+ posSize[1] = normPosSize[1];
+ posSize[3] = normPosSize[3];
+ }
+ }
+ //}
+ }
+ protected void resetMaximizedManual(final int posSize[]) {
+ if( normPosSizeStored[0] ) {
+ // max-h off
+ normPosSizeStored[0] = false;
+ posSize[0] = normPosSize[0];
+ posSize[2] = normPosSize[2];
+ }
+ if( normPosSizeStored[1] ) {
+ // max-v off
+ normPosSizeStored[1] = false;
+ posSize[1] = normPosSize[1];
+ posSize[3] = normPosSize[3];
+ }
+ }
+ private final int[] normPosSize = { 0, 0, 0, 0 };
+ private final boolean[] normPosSizeStored = { false, false };
@Override
public final String getTitle() {
@@ -2124,6 +2388,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
@Override
public final void setPointerVisible(final boolean pointerVisible) {
+ if( !isReconfigureMaskSupported(STATE_MASK_POINTERVISIBLE) && isNativeValid() ) {
+ return;
+ }
if(stateMask.get(STATE_BIT_POINTERVISIBLE) != pointerVisible) {
boolean setVal = 0 == getWindowHandle();
if(!setVal) {
@@ -2234,6 +2501,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
@Override
public final void confinePointer(final boolean confine) {
+ if( !isReconfigureMaskSupported(STATE_MASK_POINTERCONFINED) && isNativeValid() ) {
+ return;
+ }
if(stateMask.get(STATE_BIT_POINTERCONFINED) != confine) {
boolean setVal = 0 == getWindowHandle();
if(!setVal) {
@@ -2265,11 +2535,11 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
@Override
public final InsetsImmutable getInsets() {
- if(isUndecorated()) {
+ if( isUndecorated() ) {
return Insets.getZero();
+ } else {
+ return insets;
}
- updateInsetsImpl(insets);
- return insets;
}
@Override
@@ -2558,6 +2828,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
/** Internally forcing request focus on current thread */
private void requestFocusInt(final boolean skipFocusAction) {
if( skipFocusAction || !focusAction() ) {
+ if( !isReconfigureMaskSupported(STATE_MASK_FOCUSED) ) {
+ return;
+ }
if(DEBUG_IMPLEMENTATION) {
System.err.println("Window.RequestFocusInt: forcing - ("+getThreadName()+"): skipFocusAction "+
skipFocusAction+", state "+getStateMaskString()+" -> focus true - windowHandle "+
@@ -2640,7 +2913,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
@Override
public final void setTopLevelPosition(final int x, final int y) {
- setPosition(x + getInsets().getLeftWidth(), y + getInsets().getTopHeight());
+ final InsetsImmutable insets = getInsets();
+ setPosition(x + insets.getLeftWidth(), y + insets.getTopHeight());
}
private class FullScreenAction implements Runnable {
@@ -2648,8 +2922,12 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
private boolean init(final boolean fullscreen) {
if(isNativeValid()) {
- this._fullscreen = fullscreen;
- return isFullscreen() != fullscreen;
+ if( !isReconfigureMaskSupported(STATE_MASK_FULLSCREEN) ) {
+ return false;
+ } else {
+ this._fullscreen = fullscreen;
+ return isFullscreen() != fullscreen;
+ }
} else {
stateMask.put(STATE_BIT_FULLSCREEN, fullscreen); // set current state for createNative(..)
return false;
@@ -2668,11 +2946,12 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
final int oldWidth = getWidth();
final int oldHeight = getHeight();
- int x,y,w,h;
+ final int x,y,w,h;
final RectangleImmutable sviewport = screen.getViewportInWindowUnits(); // window units
final RectangleImmutable viewport; // window units
final boolean alwaysOnTopChange, resizableChange;
+
if(_fullscreen) {
if( null == fullscreenMonitors ) {
if( stateMask.get(PSTATE_BIT_FULLSCREEN_MAINMONITOR) ) {
@@ -2697,32 +2976,28 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
nfs_y = oldY;
nfs_width = oldWidth;
nfs_height = oldHeight;
- stateMask.copy(STATE_BIT_ALWAYSONTOP, PSTATE_BIT_FULLSCREEN_NFS_ALWAYSONTOP);
- stateMask.copy(STATE_BIT_RESIZABLE, PSTATE_BIT_FULLSCREEN_NFS_RESIZABLE);
+ stateMaskNFS.put32(0, 32, stateMask.get32(0, 32) & STATE_MASK_FULLSCREEN_NFS);
x = viewport.getX();
y = viewport.getY();
w = viewport.getWidth();
h = viewport.getHeight();
stateMask.clear(STATE_BIT_ALWAYSONTOP); // special aontop handling for fullscreen
stateMask.set(STATE_BIT_RESIZABLE); // allow fullscreen to resize to max
- alwaysOnTopChange = stateMask.get(PSTATE_BIT_FULLSCREEN_NFS_ALWAYSONTOP);
- resizableChange = !stateMask.get(PSTATE_BIT_FULLSCREEN_NFS_RESIZABLE);
+ alwaysOnTopChange = stateMaskNFS.get(STATE_BIT_ALWAYSONTOP);
+ resizableChange = !stateMaskNFS.get(STATE_BIT_RESIZABLE);
} else {
+ int _x,_y,_w,_h;
stateMask.set(PSTATE_BIT_FULLSCREEN_MAINMONITOR);
fullscreenMonitors = null;
stateMask.clear(STATE_BIT_FULLSCREEN_SPAN);
viewport = null;
- x = nfs_x;
- y = nfs_y;
- w = nfs_width;
- h = nfs_height;
- alwaysOnTopChange = stateMask.get(PSTATE_BIT_FULLSCREEN_NFS_ALWAYSONTOP) != stateMask.get(STATE_BIT_ALWAYSONTOP);
- // alwaysOnBottomChange = stateMask.get(PSTATE_BIT_FULLSCREEN_NFS_ALWAYSONBOTTOM) != stateMask.get(STATE_BIT_ALWAYSONBOTTOM);
- resizableChange = stateMask.get(PSTATE_BIT_FULLSCREEN_NFS_RESIZABLE) != stateMask.get(STATE_BIT_RESIZABLE);
- stateMask.copy(PSTATE_BIT_FULLSCREEN_NFS_ALWAYSONTOP, STATE_BIT_ALWAYSONTOP);
- stateMask.copy(PSTATE_BIT_FULLSCREEN_NFS_RESIZABLE, STATE_BIT_RESIZABLE);
- stateMask.clear(PSTATE_BIT_FULLSCREEN_NFS_ALWAYSONTOP);
- stateMask.set(PSTATE_BIT_FULLSCREEN_NFS_RESIZABLE);
+ _x = nfs_x;
+ _y = nfs_y;
+ _w = nfs_width;
+ _h = nfs_height;
+ alwaysOnTopChange = stateMaskNFS.get(STATE_BIT_ALWAYSONTOP) != stateMask.get(STATE_BIT_ALWAYSONTOP);
+ resizableChange = stateMaskNFS.get(STATE_BIT_RESIZABLE) != stateMask.get(STATE_BIT_RESIZABLE);
+ stateMask.put32(0, 32, stateMaskNFS.get32(0, 32) | ( stateMask.get32(0, 32) & ~STATE_MASK_FULLSCREEN_NFS ) );
if(null!=parentWindow) {
// reset position to 0/0 within parent space
@@ -2730,12 +3005,21 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
y = 0;
// refit if size is bigger than parent
- if( w > parentWindow.getWidth() ) {
+ if( _w > parentWindow.getWidth() ) {
w = parentWindow.getWidth();
+ } else {
+ w = _w;
}
- if( h > parentWindow.getHeight() ) {
+ if( _h > parentWindow.getHeight() ) {
h = parentWindow.getHeight();
+ } else {
+ h = _h;
}
+ } else {
+ x = _x;
+ y = _y;
+ w = _w;
+ h = _h;
}
}
@@ -2774,7 +3058,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
final int changeMask;
try {
{
- // Enter fullscreen - Disable alwaysOnTop/alwaysOnBottom/resizableChange
+ // Enter fullscreen - Disable alwaysOnTop/resizableChange
int cm = 0;
if( alwaysOnTopChange ) {
cm = CHANGE_MASK_ALWAYSONTOP;
@@ -2785,11 +3069,13 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
changeMask = cm;
}
if( _fullscreen && 0 != changeMask ) {
- // Enter fullscreen - Disable alwaysOnTop/alwaysOnBottom/resizableChange
+ // Enter fullscreen - Disable alwaysOnTop/resizableChange
reconfigureWindowImpl(oldX, oldY, oldWidth, oldHeight, getReconfigureMask(changeMask, isVisible()));
}
stateMask.put(STATE_BIT_FULLSCREEN, _fullscreen);
+ // Note CHANGE_MASK_PARENTING: STATE_MASK_CHILDWIN is refined in getReconfigureMask()
+ // Note CHANGE_MASK_DECORATION: STATE_MASK_UNDECORATED is refined in getReconfigureMask()
reconfigureWindowImpl(x, y, w, h,
getReconfigureMask( ( ( null != parentWindowLocked ) ? CHANGE_MASK_PARENTING : 0 ) |
CHANGE_MASK_FULLSCREEN | CHANGE_MASK_DECORATION, isVisible()) );
@@ -2989,6 +3275,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener
if(animatorPaused) {
lifecycleHook.resumeRenderingAction();
+ animatorPaused = false;
}
if( hadFocus ) {
requestFocus(true);
@@ -3103,9 +3390,10 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
//
public final void sendMouseEvent(final short eventType, final int modifiers,
- final int x, final int y, final short button, final float rotation) {
+ final int x, final int y, final short button, final float rotation) {
doMouseEvent(false, false, eventType, modifiers, x, y, button, MouseEvent.getRotationXYZ(rotation, modifiers), 1f);
}
+
public final void enqueueMouseEvent(final boolean wait, final short eventType, final int modifiers,
final int x, final int y, final short button, final float rotation) {
doMouseEvent(true, wait, eventType, modifiers, x, y, button, MouseEvent.getRotationXYZ(rotation, modifiers), 1f);
@@ -4121,20 +4409,6 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
}
- /** Triggered by implementation's WM events to update the position. */
- protected final void minMaxSizeChanged(final int min_width, final int min_height, final int max_width, final int max_height) {
- if( 0 <= min_width && 0 <= min_height && 0 <= max_width && 0 <= max_height) {
- final RectangleImmutable sz = new Rectangle(min_width, min_height, max_width, max_height);
- if( !minmax_size.equals(sz) ) {
- stateMask.put(PSTATE_BIT_MINMAXSIZE_SET, !sz.equals(undefSize));
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window.minMaxSizeChanged: ("+getThreadName()+"): Current "+minmax_size+" -> "+sz);
- }
- minmax_size.set(sz);
- }
- }
- }
-
/** Triggered by implementation's WM events to update the focus state. */
protected void focusChanged(final boolean defer, final boolean focusGained) {
if( stateMask.get(PSTATE_BIT_FOCUS_CHANGE_BROKEN) ||
@@ -4183,14 +4457,31 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
if( visible != _visible ) {
final String msg = "Visibility not reached as requested within "+timeOut+"ms : requested "+visible+", is "+_visible;
- if(failFast) {
+ if(DEBUG_FREEZE_AT_VISIBILITY_FAILURE) {
+ System.err.println("XXXX: "+msg);
+ System.err.println("XXXX: FREEZE");
+ try {
+ while(true) {
+ Thread.sleep(100);
+ display.dispatchMessagesNative(); // status up2date
+ }
+ } catch (final InterruptedException e) {
+ ExceptionUtils.dumpThrowable("", e);
+ Thread.currentThread().interrupt(); // keep state
+ }
throw new NativeWindowException(msg);
- } else if (DEBUG_IMPLEMENTATION) {
- System.err.println(msg);
- ExceptionUtils.dumpStack(System.err);
+ } else {
+ if(failFast) {
+ throw new NativeWindowException(msg);
+ } else {
+ if (DEBUG_IMPLEMENTATION) {
+ System.err.println(msg);
+ ExceptionUtils.dumpStack(System.err);
+ }
+ return -1;
+ }
}
- return -1;
- } else if( 0 < remaining ){
+ } else if( 0 < remaining ) {
return remaining;
} else {
return 0;
@@ -4320,18 +4611,27 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
/**
* Triggered by implementation's WM events to update the insets.
*
+ * @param defer
+ * @param left insets, -1 ignored
+ * @param right insets, -1 ignored
+ * @param top insets, -1 ignored
+ * @param bottom insets, -1 ignored
+ *
* @see #getInsets()
* @see #updateInsetsImpl(Insets)
*/
protected void insetsChanged(final boolean defer, final int left, final int right, final int top, final int bottom) {
if ( left >= 0 && right >= 0 && top >= 0 && bottom >= 0 ) {
+ final boolean changed = left != insets.getLeftWidth() || right != insets.getRightWidth() ||
+ top != insets.getTopHeight() || bottom != insets.getBottomHeight();
+
if( blockInsetsChange || isUndecorated() ) {
if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window.insetsChanged (defer: "+defer+"): Skip insets change "+insets+" -> "+new Insets(left, right, top, bottom)+" (blocked "+blockInsetsChange+", undecoration "+isUndecorated()+")");
+ if( changed ) {
+ System.err.println("Window.insetsChanged (defer: "+defer+"): Skip insets change "+insets+" -> "+new Insets(left, right, top, bottom)+" (blocked "+blockInsetsChange+", undecoration "+isUndecorated()+")");
+ }
}
- } else if ( (left != insets.getLeftWidth() || right != insets.getRightWidth() ||
- top != insets.getTopHeight() || bottom != insets.getBottomHeight() )
- ) {
+ } else if ( changed ) {
if(DEBUG_IMPLEMENTATION) {
System.err.println("Window.insetsChanged (defer: "+defer+"): Changed "+insets+" -> "+new Insets(left, right, top, bottom));
}
@@ -4418,6 +4718,162 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
//
+ // Accumulated actions
+ //
+
+ /** Triggered by implementation. */
+ protected final void sendMouseEventRequestFocus(final short eventType, final int modifiers,
+ final int x, final int y, final short button, final float rotation) {
+ sendMouseEvent(eventType, modifiers, x, y, button, rotation);
+ requestFocus(false /* wait */);
+ }
+ /**
+ * Triggered by implementation's WM events to update the visibility state and send- or enqueue one mouse event
+ *
+ * @param defer
+ * @param visibleChange -1 ignored, 0 invisible, > 0 visible
+ * @param entranceChange -1 ignored, 0 exit, > 0 enter
+ * @param eventType 0 ignored, > 0 [send|enqueue]MouseEvent
+ * @param modifiers
+ * @param x
+ * @param y
+ * @param button
+ * @param rotation
+ */
+ protected final void visibleChangedSendMouseEvent(final boolean defer, final int visibleChange,
+ final short eventType, final int modifiers,
+ final int x, final int y, final short button, final float rotation) {
+ if( 0 <= visibleChange ) { // ignore visible < 0
+ visibleChanged(defer, 0 < visibleChange);
+ }
+ if( 0 < eventType ) {
+ if( defer ) {
+ enqueueMouseEvent(false /* wait */, eventType, modifiers, x, y, button, rotation);
+ } else {
+ sendMouseEvent(eventType, modifiers, x, y, button, rotation);
+ }
+ }
+ }
+ /**
+ * Triggered by implementation's WM events to update the content
+ * @param defer if true sent event later, otherwise wait until processed.
+ * @param visibleChange -1 ignored, 0 invisible, > 0 visible
+ * @param x dirty-region y-pos in pixel units
+ * @param y dirty-region x-pos in pixel units
+ * @param width dirty-region width in pixel units
+ * @param height dirty-region height in pixel units
+ */
+ protected final void visibleChangedWindowRepaint(final boolean defer, final int visibleChange,
+ final int x, final int y, final int width, final int height) {
+ if( 0 <= visibleChange ) { // ignore visible < 0
+ visibleChanged(defer, 0 < visibleChange);
+ }
+ windowRepaint(defer, x, y, width, height);
+ }
+ /**
+ * Triggered by implementation's WM events to update the focus and visibility state
+ *
+ * @param defer
+ * @param focusChange -1 ignored, 0 unfocused, > 0 focused
+ * @param visibleChange -1 ignored, 0 invisible, > 0 visible
+ */
+ protected final void focusVisibleChanged(final boolean defer,
+ final int focusChange,
+ final int visibleChange) {
+ if( 0 <= focusChange ) { // ignore focus < 0
+ focusChanged(defer, 0 < focusChange);
+ }
+ if( 0 <= visibleChange ) { // ignore visible < 0
+ visibleChanged(defer, 0 < visibleChange);
+ }
+ }
+ /**
+ * Triggered by implementation's WM events to update the client-area position, size, insets and maximized flags.
+ *
+ * @param defer
+ * @param left insets, -1 ignored
+ * @param right insets, -1 ignored
+ * @param top insets, -1 ignored
+ * @param bottom insets, -1 ignored
+ * @param visibleChange -1 ignored, 0 invisible, > 0 visible
+ */
+ protected final void insetsVisibleChanged(final boolean defer,
+ final int left, final int right, final int top, final int bottom,
+ final int visibleChange) {
+ insetsChanged(defer, left, right, top, bottom);
+ if( 0 <= visibleChange ) { // ignore visible < 0
+ visibleChanged(defer, 0 < visibleChange);
+ }
+ }
+ /**
+ * Triggered by implementation's WM events to update the client-area position, size, insets and maximized flags.
+ *
+ * @param defer
+ * @param newX
+ * @param newY
+ * @param newWidth
+ * @param newHeight
+ * @param left insets, -1 ignored
+ * @param right insets, -1 ignored
+ * @param top insets, -1 ignored
+ * @param bottom insets, -1 ignored
+ * @param focusChange -1 ignored, 0 unfocused, > 0 focused
+ * @param visibleChange -1 ignored, 0 invisible, > 0 visible
+ * @param force
+ */
+ protected final void sizePosInsetsFocusVisibleChanged(final boolean defer,
+ final int newX, final int newY,
+ final int newWidth, final int newHeight,
+ final int left, final int right, final int top, final int bottom,
+ final int focusChange,
+ final int visibleChange,
+ final boolean force) {
+ sizeChanged(defer, newWidth, newHeight, force);
+ positionChanged(defer, newX, newY);
+ insetsChanged(defer, left, right, top, bottom);
+ if( 0 <= focusChange ) { // ignore focus < 0
+ focusChanged(defer, 0 < focusChange);
+ }
+ if( 0 <= visibleChange ) { // ignore visible < 0
+ visibleChanged(defer, 0 < visibleChange);
+ }
+ }
+ /**
+ * Triggered by implementation's WM events to update the client-area position, size, insets and maximized flags.
+ *
+ * @param defer
+ * @param newX
+ * @param newY
+ * @param newWidth
+ * @param newHeight
+ * @param maxHorzChange -1 ignored, 0 !maximized, > 0 maximized
+ * @param maxVertChange -1 ignored, 0 !maximized, > 0 maximized
+ * @param left insets, -1 ignored
+ * @param right insets, -1 ignored
+ * @param top insets, -1 ignored
+ * @param bottom insets, -1 ignored
+ * @param visibleChange -1 ignored, 0 invisible, > 0 visible
+ * @param force
+ */
+ protected final void sizePosMaxInsetsVisibleChanged(final boolean defer,
+ final int newX, final int newY,
+ final int newWidth, final int newHeight,
+ final int maxHorzChange, final int maxVertChange,
+ final int left, final int right, final int top, final int bottom,
+ final int visibleChange,
+ final boolean force) {
+ sizeChanged(defer, newWidth, newHeight, force);
+ positionChanged(defer, newX, newY);
+ if( 0 <= maxHorzChange && 0 <= maxVertChange ) {
+ maximizedChanged(0 < maxHorzChange, 0 < maxVertChange);
+ }
+ insetsChanged(defer, left, right, top, bottom);
+ if( 0 <= visibleChange ) { // ignore visible < 0
+ visibleChanged(defer, 0 < visibleChange);
+ }
+ }
+
+ //
// Reflection helper ..
//
diff --git a/src/newt/classes/jogamp/newt/awt/NewtFactoryAWT.java b/src/newt/classes/jogamp/newt/awt/NewtFactoryAWT.java
index cc71fb559..4e9273e83 100644
--- a/src/newt/classes/jogamp/newt/awt/NewtFactoryAWT.java
+++ b/src/newt/classes/jogamp/newt/awt/NewtFactoryAWT.java
@@ -55,41 +55,6 @@ public class NewtFactoryAWT extends NewtFactory {
public static final boolean DEBUG_IMPLEMENTATION = Debug.debug("Window");
/**
- * @deprecated Use {@link #getNativeWindow(java.awt.Component, AWTGraphicsConfiguration)}
- *
- * Wraps an AWT component into a {@link com.jogamp.nativewindow.NativeWindow} utilizing the {@link com.jogamp.nativewindow.NativeWindowFactory},<br>
- * using a configuration agnostic dummy {@link com.jogamp.nativewindow.DefaultGraphicsConfiguration}.<br>
- * <p>
- * The actual wrapping implementation is {@link com.jogamp.nativewindow.awt.JAWTWindow}.<br></p>
- * <p>
- * Purpose of this wrapping is to access the AWT window handle,<br>
- * not to actually render into it.<br>
- * Hence the dummy configuration only.</p>
- *
- * @param awtCompObject must be of type java.awt.Component
- */
- public static JAWTWindow getNativeWindow(final Object awtCompObject, final CapabilitiesImmutable capsRequested) {
- if(null==awtCompObject) {
- throw new NativeWindowException("Null AWT Component");
- }
- if( ! (awtCompObject instanceof java.awt.Component) ) {
- throw new NativeWindowException("AWT Component not a java.awt.Component");
- }
- return getNativeWindow( (java.awt.Component) awtCompObject, capsRequested );
- }
-
- /**
- * @deprecated Use {@link #getNativeWindow(java.awt.Component, AWTGraphicsConfiguration)}
- * @param awtComp
- * @param capsRequested
- * @return
- */
- public static JAWTWindow getNativeWindow(final java.awt.Component awtComp, final CapabilitiesImmutable capsRequested) {
- final AWTGraphicsConfiguration awtConfig = AWTGraphicsConfiguration.create(awtComp, null, capsRequested);
- return getNativeWindow(awtComp, awtConfig);
- }
-
- /**
* Wraps an AWT component into a {@link com.jogamp.nativewindow.NativeWindow} utilizing the {@link com.jogamp.nativewindow.NativeWindowFactory},<br>
* using the given {@link AWTGraphicsConfiguration}.
* <p>
diff --git a/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java
index 83832eeb4..af5d08da0 100644
--- a/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java
@@ -38,7 +38,6 @@ import com.jogamp.nativewindow.CapabilitiesImmutable;
import com.jogamp.nativewindow.DefaultGraphicsScreen;
import com.jogamp.nativewindow.NativeWindowException;
import com.jogamp.nativewindow.VisualIDHolder;
-import com.jogamp.nativewindow.util.Insets;
import com.jogamp.nativewindow.util.Point;
import com.jogamp.nativewindow.util.RectangleImmutable;
import com.jogamp.opengl.GLCapabilitiesChooser;
@@ -455,6 +454,11 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 {
}
@Override
+ protected final int getSupportedReconfigMaskImpl() {
+ return minimumReconfigStateMask;
+ }
+
+ @Override
protected final boolean reconfigureWindowImpl(final int x, final int y, final int width, final int height, final int flags) {
boolean res = true;
@@ -489,11 +493,6 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 {
return new Point(x,y);
}
- @Override
- protected final void updateInsetsImpl(final Insets insets) {
- // nop ..
- }
-
//----------------------------------------------------------------------
// Virtual On-Screen Keyboard / SoftInput
//
diff --git a/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java b/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java
index 40e3bf85a..bdf78386a 100644
--- a/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java
+++ b/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java
@@ -60,13 +60,14 @@ import com.jogamp.newt.Window;
@SuppressWarnings("serial")
public class AWTCanvas extends Canvas {
- private GraphicsDevice device;
- private GraphicsConfiguration chosen;
- private AWTGraphicsConfiguration awtConfig;
- private volatile JAWTWindow jawtWindow=null; // the JAWTWindow presentation of this AWT Canvas, bound to the 'drawable' lifecycle
- private CapabilitiesChooser chooser=null;
+ private final WindowDriver driver;
private final CapabilitiesImmutable capabilities;
+ private final CapabilitiesChooser chooser;
private final UpstreamScalable upstreamScale;
+ private GraphicsConfiguration chosen;
+ private volatile GraphicsDevice device;
+ private volatile AWTGraphicsConfiguration awtConfig;
+ private volatile JAWTWindow jawtWindow=null; // the JAWTWindow presentation of this AWT Canvas, bound to the 'drawable' lifecycle
public static interface UpstreamScalable {
float[] getReqPixelScale();
@@ -75,12 +76,15 @@ public class AWTCanvas extends Canvas {
private boolean displayConfigChanged=false;
- public AWTCanvas(final CapabilitiesImmutable capabilities, final CapabilitiesChooser chooser, final UpstreamScalable upstreamScale) {
+ public AWTCanvas(final WindowDriver driver, final CapabilitiesImmutable capabilities, final CapabilitiesChooser chooser, final UpstreamScalable upstreamScale) {
super();
-
if(null==capabilities) {
throw new NativeWindowException("Capabilities null");
}
+ if(null==driver) {
+ throw new NativeWindowException("driver null");
+ }
+ this.driver = driver;
this.capabilities=capabilities;
this.chooser=chooser;
this.upstreamScale = upstreamScale;
@@ -117,6 +121,9 @@ public class AWTCanvas extends Canvas {
@Override
public void addNotify() {
+ // before native peer is valid: X11
+ disableBackgroundErase();
+
/**
* 'super.addNotify()' determines the GraphicsConfiguration,
* while calling this class's overriden 'getGraphicsConfiguration()' method
@@ -134,8 +141,7 @@ public class AWTCanvas extends Canvas {
}
chosen = awtConfig.getAWTGraphicsConfiguration();
- // before native peer is valid: X11
- disableBackgroundErase();
+ setAWTGraphicsConfiguration(awtConfig);
// issues getGraphicsConfiguration() and creates the native peer
super.addNotify();
@@ -146,16 +152,20 @@ public class AWTCanvas extends Canvas {
{
jawtWindow = (JAWTWindow) NativeWindowFactory.getNativeWindow(this, awtConfig);
// trigger initialization cycle
- jawtWindow.setSurfaceScale(upstreamScale.getReqPixelScale() );
jawtWindow.lockSurface();
- upstreamScale.setHasPixelScale(jawtWindow.getCurrentSurfaceScale(new float[2]));
- jawtWindow.unlockSurface();
+ try {
+ jawtWindow.setSurfaceScale(upstreamScale.getReqPixelScale() );
+ upstreamScale.setHasPixelScale(jawtWindow.getCurrentSurfaceScale(new float[2]));
+ } finally {
+ jawtWindow.unlockSurface();
+ }
}
final GraphicsConfiguration gc = super.getGraphicsConfiguration();
if(null!=gc) {
device = gc.getDevice();
}
+ driver.localCreate();
if(Window.DEBUG_IMPLEMENTATION) {
System.err.println(getThreadName()+": AWTCanvas.addNotify.X");
}
@@ -170,16 +180,28 @@ public class AWTCanvas extends Canvas {
return null != jawtWindow ? jawtWindow.isOffscreenLayerSurfaceEnabled() : false;
}
+ private void setAWTGraphicsConfiguration(final AWTGraphicsConfiguration config) {
+ // Cache awtConfig
+ awtConfig = config;
+ if( null != jawtWindow ) {
+ // Notify JAWTWindow ..
+ jawtWindow.setAWTGraphicsConfiguration(config);
+ }
+ }
+
@Override
public void removeNotify() {
+ if(Window.DEBUG_IMPLEMENTATION) {
+ System.err.println(getThreadName()+": AWTCanvas.removeNotify.0: Created Config: "+awtConfig);
+ }
try {
- dispose();
+ driver.localDestroy();
} finally {
super.removeNotify();
}
}
- private void dispose() {
+ void dispose() {
if( null != jawtWindow ) {
jawtWindow.destroy();
if(Window.DEBUG_IMPLEMENTATION) {
@@ -198,6 +220,7 @@ public class AWTCanvas extends Canvas {
System.err.println(getThreadName()+": AWTCanvas.dispose(): closed GraphicsDevice: "+adeviceMsg+", result: "+closed);
}
}
+ awtConfig = null;
}
private String getThreadName() { return Thread.currentThread().getName(); }
@@ -255,9 +278,9 @@ public class AWTCanvas extends Canvas {
* block, both devices should have the same visual list, and the
* same configuration should be selected here.
*/
- final AWTGraphicsConfiguration config = chooseGraphicsConfiguration(
+ final AWTGraphicsConfiguration newConfig = chooseGraphicsConfiguration(
awtConfig.getChosenCapabilities(), awtConfig.getRequestedCapabilities(), chooser, gc.getDevice());
- final GraphicsConfiguration compatible = (null!=config)?config.getAWTGraphicsConfiguration():null;
+ final GraphicsConfiguration compatible = (null!=newConfig)?newConfig.getAWTGraphicsConfiguration():null;
if(Window.DEBUG_IMPLEMENTATION) {
final Exception e = new Exception("Info: Call Stack: "+Thread.currentThread().getName());
e.printStackTrace();
@@ -265,8 +288,8 @@ public class AWTCanvas extends Canvas {
System.err.println("Created Config (n): THIS GC "+gc);
System.err.println("Created Config (n): Choosen GC "+compatible);
System.err.println("Created Config (n): HAVE CF "+awtConfig);
- System.err.println("Created Config (n): Choosen CF "+config);
- System.err.println("Created Config (n): EQUALS CAPS "+config.getChosenCapabilities().equals(awtConfig.getChosenCapabilities()));
+ System.err.println("Created Config (n): Choosen CF "+newConfig);
+ System.err.println("Created Config (n): EQUALS CAPS "+newConfig.getChosenCapabilities().equals(awtConfig.getChosenCapabilities()));
}
if (compatible != null) {
@@ -275,10 +298,10 @@ public class AWTCanvas extends Canvas {
* any outside callers of this method.
*/
chosen = compatible;
- if( !config.getChosenCapabilities().equals(awtConfig.getChosenCapabilities())) {
+ if( !newConfig.getChosenCapabilities().equals(awtConfig.getChosenCapabilities())) {
displayConfigChanged=true;
}
- awtConfig = config;
+ setAWTGraphicsConfiguration(newConfig);
}
}
diff --git a/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java b/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java
index 9d3121635..3d9073769 100644
--- a/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java
+++ b/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java
@@ -33,6 +33,8 @@ import java.awt.EventQueue;
import com.jogamp.nativewindow.NativeWindowException;
import com.jogamp.common.ExceptionUtils;
+import com.jogamp.common.util.InterruptSource;
+import com.jogamp.common.util.InterruptedRuntimeException;
import com.jogamp.common.util.RunnableTask;
import com.jogamp.common.util.awt.AWTEDTExecutor;
import com.jogamp.newt.util.EDTUtil;
@@ -54,7 +56,7 @@ public class AWTEDTUtil implements EDTUtil {
this.threadGroup = tg;
this.name=Thread.currentThread().getName()+"-"+name+"-EDT-";
this.dispatchMessages=dispatchMessages;
- this.nedt = new NEDT(threadGroup, name);
+ this.nedt = new NEDT(threadGroup, this.name);
this.nedt.setDaemon(true); // don't stop JVM from shutdown ..
}
@@ -132,8 +134,7 @@ public class AWTEDTUtil implements EDTUtil {
}
private final boolean invokeImpl(boolean wait, final Runnable task, final boolean stop) {
- Throwable throwable = null;
- RunnableTask rTask = null;
+ final RunnableTask rTask;
final Object rTaskLock = new Object();
synchronized(rTaskLock) { // lock the optional task execution
synchronized(edtLock) { // lock the EDT status
@@ -150,6 +151,7 @@ public class AWTEDTUtil implements EDTUtil {
task.run();
}
wait = false; // running in same thread (EDT) -> no wait
+ rTask = null;
if(stop) {
nedt.shouldStop = true;
}
@@ -182,18 +184,21 @@ public class AWTEDTUtil implements EDTUtil {
true /* always catch and report Exceptions, don't disturb EDT */,
wait ? null : System.err);
AWTEDTExecutor.singleton.invoke(false, rTask);
+ } else {
+ wait = false;
+ rTask = null;
}
}
}
if( wait ) {
try {
- rTaskLock.wait(); // free lock, allow execution of rTask
+ while( rTask.isInQueue() ) {
+ rTaskLock.wait(); // free lock, allow execution of rTask
+ }
} catch (final InterruptedException ie) {
- throwable = ie;
- }
- if(null==throwable) {
- throwable = rTask.getThrowable();
+ throw new InterruptedRuntimeException(ie);
}
+ final Throwable throwable = rTask.getThrowable();
if(null!=throwable) {
if(throwable instanceof NativeWindowException) {
throw (NativeWindowException)throwable;
@@ -227,12 +232,12 @@ public class AWTEDTUtil implements EDTUtil {
final public boolean waitUntilStopped() {
synchronized(edtLock) {
if( nedt.isRunning && nedt != Thread.currentThread() && !EventQueue.isDispatchThread() ) {
- while( nedt.isRunning ) {
- try {
+ try {
+ while( nedt.isRunning ) {
edtLock.wait();
- } catch (final InterruptedException e) {
- e.printStackTrace();
}
+ } catch (final InterruptedException e) {
+ throw new InterruptedRuntimeException(e);
}
return true;
} else {
@@ -241,13 +246,13 @@ public class AWTEDTUtil implements EDTUtil {
}
}
- class NEDT extends Thread {
+ class NEDT extends InterruptSource.Thread {
volatile boolean shouldStop = false;
volatile boolean isRunning = false;
Object sync = new Object();
public NEDT(final ThreadGroup tg, final String name) {
- super(tg, name);
+ super(tg, null, name);
}
final public boolean isRunning() {
@@ -286,7 +291,7 @@ public class AWTEDTUtil implements EDTUtil {
try {
sync.wait(pollPeriod);
} catch (final InterruptedException e) {
- e.printStackTrace();
+ throw new InterruptedRuntimeException(e);
}
}
}
diff --git a/src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java
index edc884366..aa93dd9aa 100644
--- a/src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java
@@ -74,6 +74,8 @@ public class WindowDriver extends WindowImpl {
public WindowDriver(final Container container) {
super();
+ this.withinLocalDispose = false;
+ this.addWindowListener(0, new NEWTWindowListener());
this.awtContainer = container;
if(container instanceof Frame) {
awtFrame = (Frame) container;
@@ -85,6 +87,7 @@ public class WindowDriver extends WindowImpl {
/** same instance as container, just for impl. convenience */
private Frame awtFrame = null;
private AWTCanvas awtCanvas;
+ private volatile boolean withinLocalDispose;
@Override
protected void requestFocusImpl(final boolean reparented) {
@@ -112,64 +115,98 @@ public class WindowDriver extends WindowImpl {
@Override
protected void createNativeImpl() {
- if(0!=getParentWindowHandle()) {
- throw new RuntimeException("Window parenting not supported in AWT, use AWTWindow(Frame) cstr for wrapping instead");
- }
-
- if(null==awtContainer) {
- awtFrame = new Frame();
- awtContainer = awtFrame;
- owningFrame=true;
+ if( withinLocalDispose ) {
+ setupHandleAndGC();
+ definePosition(getX(), getY()); // clear AUTOPOS
+ visibleChanged(false, true);
+ withinLocalDispose = false;
} else {
- owningFrame=false;
- defineSize(awtContainer.getWidth(), awtContainer.getHeight());
- definePosition(awtContainer.getX(), awtContainer.getY());
- }
- if(null!=awtFrame) {
- awtFrame.setTitle(getTitle());
- }
- awtContainer.setLayout(new BorderLayout());
+ if(0!=getParentWindowHandle()) {
+ throw new RuntimeException("Window parenting not supported in AWT, use AWTWindow(Frame) cstr for wrapping instead");
+ }
+
+ if(null==awtContainer) {
+ awtFrame = new Frame();
+ awtContainer = awtFrame;
+ owningFrame=true;
+ } else {
+ owningFrame=false;
+ defineSize(awtContainer.getWidth(), awtContainer.getHeight());
+ definePosition(awtContainer.getX(), awtContainer.getY());
+ }
+ if(null!=awtFrame) {
+ awtFrame.setTitle(getTitle());
+ }
+ awtContainer.setLayout(new BorderLayout());
- if( null == awtCanvas ) {
- awtCanvas = new AWTCanvas(capsRequested, WindowDriver.this.capabilitiesChooser, upstreamScalable);
+ if( null == awtCanvas ) {
+ awtCanvas = new AWTCanvas(this, capsRequested, WindowDriver.this.capabilitiesChooser, upstreamScalable);
- // canvas.addComponentListener(listener);
- awtContainer.add(awtCanvas, BorderLayout.CENTER);
+ // canvas.addComponentListener(listener);
+ awtContainer.add(awtCanvas, BorderLayout.CENTER);
- // via EDT ..
- new AWTMouseAdapter(this).addTo(awtCanvas); // fwd all AWT Mouse events to here
- new AWTKeyAdapter(this).addTo(awtCanvas); // fwd all AWT Key events to here
+ // via EDT ..
+ new AWTMouseAdapter(this).addTo(awtCanvas); // fwd all AWT Mouse events to here
+ new AWTKeyAdapter(this).addTo(awtCanvas); // fwd all AWT Key events to here
- // direct w/o EDT
- new AWTWindowAdapter(new LocalWindowListener(), this).addTo(awtCanvas); // fwd all AWT Window events to here
+ // direct w/o EDT
+ new AWTWindowAdapter(new AWTWindowListener(), this).addTo(awtCanvas); // fwd all AWT Window events to here
+ } else {
+ awtContainer.add(awtCanvas, BorderLayout.CENTER);
+ }
+ reconfigureWindowImpl(getX(), getY(), getWidth(), getHeight(), getReconfigureMask(CHANGE_MASK_VISIBILITY | CHANGE_MASK_DECORATION, true));
+ // throws exception if failed ..
+ // AWTCanvas -> localCreate -> setupHandleAndGC();
}
+ }
- reconfigureWindowImpl(getX(), getY(), getWidth(), getHeight(), getReconfigureMask(CHANGE_MASK_VISIBILITY | CHANGE_MASK_DECORATION, true));
- // throws exception if failed ..
+ private void setupHandleAndGC() {
+ // reconfigureWindowImpl(getX(), getY(), getWidth(), getHeight(), getReconfigureMask(CHANGE_MASK_VISIBILITY | CHANGE_MASK_DECORATION, true));
+ if( null != awtCanvas ) {
+ final NativeWindow nw = awtCanvas.getNativeWindow();
+ if( null != nw ) {
+ setGraphicsConfiguration( awtCanvas.getAWTGraphicsConfiguration() );
+ setWindowHandle( nw.getWindowHandle() );
+ }
+ }
+ }
- final NativeWindow nw = awtCanvas.getNativeWindow();
- if( null != nw ) {
- setGraphicsConfiguration( awtCanvas.getAWTGraphicsConfiguration() );
- setWindowHandle( nw.getWindowHandle() );
+ void localCreate() {
+ if( withinLocalDispose ) {
+ setVisible(true);
+ } else {
+ setupHandleAndGC();
}
}
+ void localDestroy() {
+ this.withinLocalDispose = true;
+ super.destroy();
+ }
+
@Override
protected void closeNativeImpl() {
setWindowHandle(0);
- if(null!=awtContainer) {
- awtContainer.setVisible(false);
- awtContainer.remove(awtCanvas);
- awtContainer.setEnabled(false);
- awtCanvas.setEnabled(false);
- }
- if(owningFrame && null!=awtFrame) {
- awtFrame.dispose();
- owningFrame=false;
+ if( this.withinLocalDispose ) {
+ if(null!=awtCanvas) {
+ awtCanvas.dispose();
+ }
+ } else {
+ if(null!=awtContainer) {
+ awtContainer.setVisible(false);
+ awtContainer.remove(awtCanvas);
+ awtContainer.setEnabled(false);
+ awtCanvas.setEnabled(false);
+ awtCanvas.dispose();
+ }
+ if(owningFrame && null!=awtFrame) {
+ awtFrame.dispose();
+ owningFrame=false;
+ }
+ awtCanvas = null;
+ awtFrame = null;
+ awtContainer = null;
}
- awtCanvas = null;
- awtFrame = null;
- awtContainer = null;
}
@Override
@@ -191,12 +228,6 @@ public class WindowDriver extends WindowImpl {
return res;
}
- @Override
- protected void updateInsetsImpl(final com.jogamp.nativewindow.util.Insets insets) {
- final Insets contInsets = awtContainer.getInsets();
- insets.set(contInsets.left, contInsets.right, contInsets.top, contInsets.bottom);
- }
-
private void setCanvasSizeImpl(final int width, final int height) {
final Dimension szClient = new Dimension(width, height);
final java.awt.Window awtWindow = AWTMisc.getWindow(awtCanvas);
@@ -231,6 +262,11 @@ public class WindowDriver extends WindowImpl {
}
@Override
+ protected final int getSupportedReconfigMaskImpl() {
+ return minimumReconfigStateMask;
+ }
+
+ @Override
protected boolean reconfigureWindowImpl(final int x, final int y, final int width, final int height, final int flags) {
if(DEBUG_IMPLEMENTATION) {
System.err.println("AWTWindow reconfig: "+x+"/"+y+" "+width+"x"+height+", "+
@@ -250,6 +286,8 @@ public class WindowDriver extends WindowImpl {
if( 0 != ( STATE_MASK_VISIBLE & flags) ) {
setCanvasSizeImpl(width, height);
awtContainer.setVisible( true );
+ final Insets contInsets = awtContainer.getInsets();
+ insetsChanged(false, contInsets.left, contInsets.right, contInsets.top, contInsets.bottom);
} else {
awtContainer.setVisible( false );
}
@@ -265,6 +303,7 @@ public class WindowDriver extends WindowImpl {
if( awtContainer.getX() != x || awtContainer.getY() != y ) {
awtContainer.setLocation(x, y);
}
+ definePosition(x, y);
if( 0 != ( CHANGE_MASK_VISIBILITY & flags) ) {
if( 0 != ( STATE_MASK_VISIBLE & flags ) ) {
@@ -279,6 +318,9 @@ public class WindowDriver extends WindowImpl {
}
visibleChanged(false, 0 != ( STATE_MASK_VISIBLE & flags));
}
+ if( isVisible() ) {
+ windowRepaint(false, 0, 0, getSurfaceWidth(), getSurfaceHeight());
+ }
return true;
}
@@ -295,7 +337,7 @@ public class WindowDriver extends WindowImpl {
return ( null != awtCanvas ) ? awtCanvas.getNativeWindow() : null;
}
- class LocalWindowListener implements com.jogamp.newt.event.WindowListener {
+ class AWTWindowListener implements com.jogamp.newt.event.WindowListener {
@Override
public void windowMoved(final com.jogamp.newt.event.WindowEvent e) {
if(null!=awtContainer) {
@@ -338,4 +380,28 @@ public class WindowDriver extends WindowImpl {
}
}
}
+ class NEWTWindowListener implements com.jogamp.newt.event.WindowListener {
+ @Override
+ public void windowMoved(final com.jogamp.newt.event.WindowEvent e) { }
+ @Override
+ public void windowResized(final com.jogamp.newt.event.WindowEvent e) { }
+ @Override
+ public void windowDestroyNotify(final WindowEvent e) {
+ if( withinLocalDispose ) {
+ e.setConsumed(true);
+ }
+ }
+ @Override
+ public void windowDestroyed(final WindowEvent e) {
+ if( withinLocalDispose ) {
+ e.setConsumed(true);
+ }
+ }
+ @Override
+ public void windowGainedFocus(final WindowEvent e) { }
+ @Override
+ public void windowLostFocus(final WindowEvent e) { }
+ @Override
+ public void windowRepaint(final WindowUpdateEvent e) { }
+ }
}
diff --git a/src/newt/classes/jogamp/newt/driver/bcm/egl/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/bcm/egl/WindowDriver.java
index f20f938b6..d19618bd1 100644
--- a/src/newt/classes/jogamp/newt/driver/bcm/egl/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/bcm/egl/WindowDriver.java
@@ -38,7 +38,6 @@ import com.jogamp.nativewindow.AbstractGraphicsConfiguration;
import com.jogamp.nativewindow.GraphicsConfigurationFactory;
import com.jogamp.nativewindow.NativeWindowException;
import com.jogamp.nativewindow.VisualIDHolder;
-import com.jogamp.nativewindow.util.Insets;
import com.jogamp.nativewindow.util.Point;
import com.jogamp.opengl.GLCapabilitiesImmutable;
@@ -94,6 +93,11 @@ public class WindowDriver extends jogamp.newt.WindowImpl {
}
@Override
+ protected final int getSupportedReconfigMaskImpl() {
+ return minimumReconfigStateMask;
+ }
+
+ @Override
protected boolean reconfigureWindowImpl(final int x, final int y, final int width, final int height, final int flags) {
if(0!=getWindowHandle()) {
if(0 != ( CHANGE_MASK_FULLSCREEN & flags)) {
@@ -128,11 +132,6 @@ public class WindowDriver extends jogamp.newt.WindowImpl {
}
@Override
- protected void updateInsetsImpl(final Insets insets) {
- // nop ..
- }
-
- @Override
public boolean surfaceSwap() {
SwapWindow(getDisplayHandle(), getWindowHandle());
return true;
diff --git a/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/DisplayDriver.java
index d111e850e..d4af1b972 100644
--- a/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/DisplayDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/DisplayDriver.java
@@ -67,10 +67,12 @@ public class DisplayDriver extends DisplayImpl {
PNGPixelRect image = null;
if( DisplayImpl.isPNGUtilAvailable() ) {
- final IOUtil.ClassResources res = new IOUtil.ClassResources(DisplayDriver.class, new String[] { "newt/data/pointer-grey-alpha-16x24.png" } );
+ final IOUtil.ClassResources res = new IOUtil.ClassResources(new String[] { "newt/data/pointer-grey-alpha-16x24.png" }, DisplayDriver.class.getClassLoader(), null);
try {
final URLConnection urlConn = res.resolve(0);
- image = PNGPixelRect.read(urlConn.getInputStream(), PixelFormat.BGRA8888, false /* directBuffer */, 0 /* destMinStrideInBytes */, false /* destIsGLOriented */);
+ if( null != urlConn ) {
+ image = PNGPixelRect.read(urlConn.getInputStream(), PixelFormat.BGRA8888, false /* directBuffer */, 0 /* destMinStrideInBytes */, false /* destIsGLOriented */);
+ }
} catch (final Exception e) {
e.printStackTrace();
}
@@ -96,7 +98,11 @@ public class DisplayDriver extends DisplayImpl {
aDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(EGL.EGL_DEFAULT_DISPLAY, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
aDevice.open();
- defaultPointerIcon = (PointerIconImpl) createPointerIcon(defaultPointerIconImage, 0, 0);
+ if( null != defaultPointerIconImage ) {
+ defaultPointerIcon = (PointerIconImpl) createPointerIcon(defaultPointerIconImage, 0, 0);
+ } else {
+ defaultPointerIcon = null;
+ }
if( DEBUG_POINTER_ICON ) {
System.err.println("Display.PointerIcon.createDefault: "+defaultPointerIcon);
}
diff --git a/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/WindowDriver.java
index 34212d012..b0a4ee34a 100644
--- a/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/WindowDriver.java
@@ -36,7 +36,6 @@ import com.jogamp.nativewindow.GraphicsConfigurationFactory;
import com.jogamp.nativewindow.NativeWindowException;
import com.jogamp.nativewindow.VisualIDHolder;
-import com.jogamp.nativewindow.util.Insets;
import com.jogamp.nativewindow.util.Point;
import com.jogamp.nativewindow.util.Rectangle;
import com.jogamp.nativewindow.util.RectangleImmutable;
@@ -249,6 +248,20 @@ public class WindowDriver extends WindowImpl {
}
@Override
+ protected final int getSupportedReconfigMaskImpl() {
+ return minimumReconfigStateMask |
+ // STATE_MASK_UNDECORATED |
+ // STATE_MASK_ALWAYSONTOP |
+ // STATE_MASK_ALWAYSONBOTTOM |
+ // STATE_MASK_STICKY |
+ // STATE_MASK_RESIZABLE |
+ // STATE_MASK_MAXIMIZED_VERT |
+ // STATE_MASK_MAXIMIZED_HORZ |
+ STATE_MASK_POINTERVISIBLE |
+ STATE_MASK_POINTERCONFINED;
+ }
+
+ @Override
protected boolean reconfigureWindowImpl(final int x, final int y, final int width, final int height, final int flags) {
final RectangleImmutable rect = clampRect((ScreenDriver) getScreen(), new Rectangle(x, y, width, height), false);
// reconfigure0 will issue position/size changed events if required
@@ -263,11 +276,6 @@ public class WindowDriver extends WindowImpl {
}
@Override
- protected void updateInsetsImpl(final Insets insets) {
- // nop ..
- }
-
- @Override
protected final void doMouseEvent(final boolean enqueue, final boolean wait, final short eventType, final int modifiers,
final int x, final int y, final short button, final float[] rotationXYZ, final float rotationScale) {
if( MouseEvent.EVENT_MOUSE_MOVED == eventType || MouseEvent.EVENT_MOUSE_DRAGGED == eventType ) {
diff --git a/src/newt/classes/jogamp/newt/driver/intel/gdl/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/intel/gdl/WindowDriver.java
index a083f420f..b01928449 100644
--- a/src/newt/classes/jogamp/newt/driver/intel/gdl/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/intel/gdl/WindowDriver.java
@@ -35,7 +35,6 @@
package jogamp.newt.driver.intel.gdl;
import com.jogamp.nativewindow.*;
-import com.jogamp.nativewindow.util.Insets;
import com.jogamp.nativewindow.util.Point;
public class WindowDriver extends jogamp.newt.WindowImpl {
@@ -86,6 +85,11 @@ public class WindowDriver extends jogamp.newt.WindowImpl {
}
@Override
+ protected final int getSupportedReconfigMaskImpl() {
+ return minimumReconfigStateMask;
+ }
+
+ @Override
protected boolean reconfigureWindowImpl(int x, int y, int width, int height, final int flags) {
final ScreenDriver screen = (ScreenDriver) getScreen();
@@ -132,11 +136,6 @@ public class WindowDriver extends jogamp.newt.WindowImpl {
return new Point(x,y);
}
- @Override
- protected void updateInsetsImpl(final Insets insets) {
- // nop ..
- }
-
//----------------------------------------------------------------------
// Internals only
//
diff --git a/src/newt/classes/jogamp/newt/driver/kd/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/kd/WindowDriver.java
index 242f644f6..ce5d208db 100644
--- a/src/newt/classes/jogamp/newt/driver/kd/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/kd/WindowDriver.java
@@ -39,7 +39,6 @@ import com.jogamp.nativewindow.GraphicsConfigurationFactory;
import com.jogamp.nativewindow.NativeWindowException;
import com.jogamp.nativewindow.VisualIDHolder;
import com.jogamp.nativewindow.VisualIDHolder.VIDType;
-import com.jogamp.nativewindow.util.Insets;
import com.jogamp.nativewindow.util.Point;
import com.jogamp.opengl.GLCapabilitiesImmutable;
@@ -96,6 +95,11 @@ public class WindowDriver extends WindowImpl {
protected void requestFocusImpl(final boolean reparented) { }
@Override
+ protected final int getSupportedReconfigMaskImpl() {
+ return minimumReconfigStateMask;
+ }
+
+ @Override
protected boolean reconfigureWindowImpl(final int x, final int y, int width, int height, final int flags) {
if( 0 != ( CHANGE_MASK_VISIBILITY & flags) ) {
setVisible0(eglWindowHandle, 0 != ( STATE_MASK_VISIBLE & flags));
@@ -134,11 +138,6 @@ public class WindowDriver extends WindowImpl {
return new Point(x,y);
}
- @Override
- protected void updateInsetsImpl(final Insets insets) {
- // nop ..
- }
-
//----------------------------------------------------------------------
// Internals only
//
diff --git a/src/newt/classes/jogamp/newt/driver/linux/LinuxEventDeviceTracker.java b/src/newt/classes/jogamp/newt/driver/linux/LinuxEventDeviceTracker.java
index bc0bfaa16..c3b7bff36 100644
--- a/src/newt/classes/jogamp/newt/driver/linux/LinuxEventDeviceTracker.java
+++ b/src/newt/classes/jogamp/newt/driver/linux/LinuxEventDeviceTracker.java
@@ -43,6 +43,7 @@ import jogamp.newt.WindowImpl;
import jogamp.newt.driver.KeyTracker;
import com.jogamp.common.nio.StructAccessor;
+import com.jogamp.common.util.InterruptSource;
import com.jogamp.newt.Window;
import com.jogamp.newt.event.InputEvent;
import com.jogamp.newt.event.WindowEvent;
@@ -63,7 +64,7 @@ public class LinuxEventDeviceTracker implements WindowListener, KeyTracker {
static {
ledt = new LinuxEventDeviceTracker();
- final Thread t = new Thread(ledt.eventDeviceManager, "NEWT-LinuxEventDeviceManager");
+ final Thread t = new InterruptSource.Thread(null, ledt.eventDeviceManager, "NEWT-LinuxEventDeviceManager");
t.setDaemon(true);
t.start();
}
@@ -153,7 +154,7 @@ public class LinuxEventDeviceTracker implements WindowListener, KeyTracker {
if(number<32&&number>=0) {
if(eventDevicePollers[number]==null){
eventDevicePollers[number] = new EventDevicePoller(number);
- final Thread t = new Thread(eventDevicePollers[number], "NEWT-LinuxEventDeviceTracker-event"+number);
+ final Thread t = new InterruptSource.Thread(null, eventDevicePollers[number], "NEWT-LinuxEventDeviceTracker-event"+number);
t.setDaemon(true);
t.start();
} else if(eventDevicePollers[number].stop) {
diff --git a/src/newt/classes/jogamp/newt/driver/linux/LinuxMouseTracker.java b/src/newt/classes/jogamp/newt/driver/linux/LinuxMouseTracker.java
index f40728da0..53bb9c3a5 100644
--- a/src/newt/classes/jogamp/newt/driver/linux/LinuxMouseTracker.java
+++ b/src/newt/classes/jogamp/newt/driver/linux/LinuxMouseTracker.java
@@ -37,6 +37,7 @@ import java.io.InputStream;
import jogamp.newt.WindowImpl;
import jogamp.newt.driver.MouseTracker;
+import com.jogamp.common.util.InterruptSource;
import com.jogamp.newt.Screen;
import com.jogamp.newt.Window;
import com.jogamp.newt.event.MouseEvent;
@@ -55,7 +56,7 @@ public class LinuxMouseTracker implements WindowListener, MouseTracker {
static {
lmt = new LinuxMouseTracker();
- final Thread t = new Thread(lmt.mouseDevicePoller, "NEWT-LinuxMouseTracker");
+ final Thread t = new InterruptSource.Thread(null, lmt.mouseDevicePoller, "NEWT-LinuxMouseTracker");
t.setDaemon(true);
t.start();
}
diff --git a/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java
index c8146b85d..8ff37872b 100644
--- a/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java
@@ -70,7 +70,9 @@ public class DisplayDriver extends DisplayImpl {
// NOTE: MUST BE DIRECT BUFFER, since NSBitmapImageRep uses buffer directly!
final IOUtil.ClassResources iconRes = NewtFactory.getWindowIcons();
final URLConnection urlConn = iconRes.resolve(iconRes.resourceCount()-1);
- image = PNGPixelRect.read(urlConn.getInputStream(), PixelFormat.RGBA8888, true /* directBuffer */, 0 /* destMinStrideInBytes */, false /* destIsGLOriented */);
+ if( null != urlConn ) {
+ image = PNGPixelRect.read(urlConn.getInputStream(), PixelFormat.RGBA8888, true /* directBuffer */, 0 /* destMinStrideInBytes */, false /* destIsGLOriented */);
+ }
} catch (final Exception e) {
e.printStackTrace();
}
diff --git a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java
index 0d144775a..46c86d2c1 100644
--- a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java
@@ -34,6 +34,7 @@
package jogamp.newt.driver.macosx;
+import com.jogamp.common.util.InterruptSource;
import com.jogamp.nativewindow.AbstractGraphicsConfiguration;
import com.jogamp.nativewindow.GraphicsConfigurationFactory;
import com.jogamp.nativewindow.NativeWindow;
@@ -41,8 +42,6 @@ import com.jogamp.nativewindow.NativeWindowException;
import com.jogamp.nativewindow.MutableSurface;
import com.jogamp.nativewindow.ScalableSurface;
import com.jogamp.nativewindow.VisualIDHolder;
-import com.jogamp.nativewindow.util.Insets;
-import com.jogamp.nativewindow.util.InsetsImmutable;
import com.jogamp.nativewindow.util.Point;
import com.jogamp.nativewindow.util.PointImmutable;
@@ -54,7 +53,6 @@ import jogamp.newt.WindowImpl;
import jogamp.newt.driver.DriverClearFocus;
import jogamp.newt.driver.DriverUpdatePosition;
-import com.jogamp.newt.MonitorMode;
import com.jogamp.newt.event.InputEvent;
import com.jogamp.newt.event.KeyEvent;
import com.jogamp.newt.event.MonitorEvent;
@@ -121,11 +119,10 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
/** Called from native code */
protected void updatePixelScale(final boolean defer, final float newPixelScaleRaw, final float maxPixelScaleRaw) {
- final long handle = getWindowHandle();
if( DEBUG_IMPLEMENTATION ) {
- System.err.println("WindowDriver.updatePixelScale.3: "+hasPixelScale[0]+" (has) -> "+newPixelScaleRaw+" (new), "+maxPixelScaleRaw+" (max), drop "+(0==handle));
+ System.err.println("WindowDriver.updatePixelScale.3: "+hasPixelScale[0]+" (has) -> "+newPixelScaleRaw+" (new), "+maxPixelScaleRaw+" (max), drop "+!isNativeValid());
}
- if( 0 != handle ) {
+ if( isNativeValid() ) {
updatePixelScale(true /* sendEvent*/, defer, true /*offthread */, newPixelScaleRaw, maxPixelScaleRaw);
}
}
@@ -199,7 +196,7 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
}
setGraphicsConfiguration(cfg);
reconfigureWindowImpl(getX(), getY(), getWidth(), getHeight(), getReconfigureMask(CHANGE_MASK_VISIBILITY, true));
- if (0 == getWindowHandle()) {
+ if ( !isNativeValid() ) {
throw new NativeWindowException("Error creating window");
}
}
@@ -214,6 +211,7 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
surfaceHandle = 0;
sscSurfaceHandle = 0;
isOffscreenInstance = false;
+ resizeAnimatorPaused = false;
if (0 != handle) {
OSXUtil.RunOnMainThread(false, true /* kickNSApp */, new Runnable() {
@Override
@@ -271,7 +269,7 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
System.err.println("MacWindow.setSurfaceHandle(): 0x"+Long.toHexString(surfaceHandle));
}
sscSurfaceHandle = surfaceHandle;
- if (isNativeValid()) {
+ if ( isNativeValid() ) {
if (0 != sscSurfaceHandle) {
OSXUtil.RunOnMainThread(false, false, new Runnable() {
@Override
@@ -343,15 +341,20 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
if( 0 != handle && !isOffscreenInstance ) {
final NativeWindow parent = getParent();
final boolean useParent = useParent(parent);
- final int pX=parent.getX(), pY=parent.getY();
- final Point p0S = getLocationOnScreenImpl(x, y, parent, useParent);
+ final Point p0S;
+ if( useParent ) {
+ p0S = getLocationOnScreenByParent(x, y, parent);
+ } else {
+ p0S = (Point) getLocationOnScreen0(handle, x, y);
+ }
if(DEBUG_IMPLEMENTATION) {
+ final int pX=parent.getX(), pY=parent.getY();
System.err.println("MacWindow: updatePosition() parent["+useParent+" "+pX+"/"+pY+"] "+x+"/"+y+" -> "+x+"/"+y+" rel-client-pos, "+p0S+" screen-client-pos");
}
OSXUtil.RunOnMainThread(false, false, new Runnable() {
@Override
public void run() {
- setWindowClientTopLeftPoint0(handle, p0S.getX(), p0S.getY(), isVisible());
+ setWindowClientTopLeftPoint0(getWindowHandle(), p0S.getX(), p0S.getY(), isVisible());
} } );
// no native event (fullscreen, some reparenting)
positionChanged(true, x, y);
@@ -359,39 +362,20 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
}
@Override
- protected void sizeChanged(final boolean defer, final int newWidth, final int newHeight, final boolean force) {
- final long handle = getWindowHandle();
- if( 0 != handle && !isOffscreenInstance ) {
- final NativeWindow parent = getParent();
- final boolean useParent = useParent(parent);
- if( useParent && ( getWidth() != newWidth || getHeight() != newHeight ) ) {
- final int x=getX(), y=getY();
- final Point p0S = getLocationOnScreenImpl(x, y, parent, useParent);
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("MacWindow: sizeChanged() parent["+useParent+" "+x+"/"+y+"] "+getX()+"/"+getY()+" "+newWidth+"x"+newHeight+" -> "+p0S+" screen-client-pos");
- }
- OSXUtil.RunOnMainThread(false, false, new Runnable() {
- @Override
- public void run() {
- setWindowClientTopLeftPoint0(getWindowHandle(), p0S.getX(), p0S.getY(), isVisible());
- } } );
- }
- }
- superSizeChangedOffThread(defer, newWidth, newHeight, force);
- }
- private void superSizeChangedOffThread(final boolean defer, final int newWidth, final int newHeight, final boolean force) {
- if( defer ) {
- new Thread() {
- public void run() {
- WindowDriver.super.sizeChanged(false /* defer */, newWidth, newHeight, force);
- } }.start();
- } else {
- WindowDriver.super.sizeChanged(false /* defer */, newWidth, newHeight, force);
- }
+ protected final int getSupportedReconfigMaskImpl() {
+ return minimumReconfigStateMask |
+ STATE_MASK_CHILDWIN |
+ STATE_MASK_UNDECORATED |
+ STATE_MASK_ALWAYSONTOP |
+ STATE_MASK_ALWAYSONBOTTOM |
+ STATE_MASK_STICKY |
+ STATE_MASK_RESIZABLE |
+ STATE_MASK_MAXIMIZED_VERT |
+ STATE_MASK_MAXIMIZED_HORZ |
+ STATE_MASK_POINTERVISIBLE |
+ STATE_MASK_POINTERCONFINED;
}
- private final int[] normPosSize = { 0, 0, 0, 0 };
-
@Override
protected boolean reconfigureWindowImpl(int _x, int _y, int _width, int _height, final int flags) {
final boolean _isOffscreenInstance = isOffscreenInstance(this, this.getParent());
@@ -402,43 +386,16 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
pClientLevelOnSreen = new Point(0, 0);
} else {
final NativeWindow parent = getParent();
- final boolean useParent = useParent(parent);
- if( useParent ) {
- pClientLevelOnSreen = getLocationOnScreenImpl(_x, _y, parent, useParent);
+ if( useParent(parent) ) {
+ pClientLevelOnSreen = getLocationOnScreenByParent(_x, _y, parent);
} else {
if( 0 != ( ( CHANGE_MASK_MAXIMIZED_HORZ | CHANGE_MASK_MAXIMIZED_VERT ) & flags ) ) {
- final InsetsImmutable insets = getInsets();
- final MonitorMode mm = getMainMonitor().getCurrentMode();
- // FIXME HiDPI: Shortcut, may need to adjust if we change scaling methodology
- final int mmWidth = SurfaceScaleUtils.scaleInv(mm.getRotatedWidth(), getPixelScaleX());
- final int mmHeight = SurfaceScaleUtils.scaleInv(mm.getRotatedHeight(), getPixelScaleY());
-
- if( 0 != ( CHANGE_MASK_MAXIMIZED_HORZ & flags ) ) {
- if( 0 != ( STATE_MASK_MAXIMIZED_HORZ & flags ) ) {
- // max-h on
- normPosSize[0] = _x;
- normPosSize[2] = _width;
- _x = insets.getLeftWidth();
- _width = mmWidth - insets.getTotalWidth();
- } else {
- // max-h off
- _x = normPosSize[0];
- _width = normPosSize[2];
- }
- }
- if( 0 != ( CHANGE_MASK_MAXIMIZED_VERT & flags ) ) {
- if( 0 != ( STATE_MASK_MAXIMIZED_VERT & flags ) ) {
- // max-v on
- normPosSize[1] = _y;
- normPosSize[3] = _height;
- _y = insets.getTopHeight();
- _height = mmHeight - insets.getTotalHeight();
- } else {
- // max-h off
- _y = normPosSize[1];
- _height = normPosSize[3];
- }
- }
+ final int[] posSize = { _x, _y, _width, _height };
+ reconfigMaximizedManual(flags, posSize, getInsets());
+ _x = posSize[0];
+ _y = posSize[1];
+ _width = posSize[2];
+ _height = posSize[3];
}
pClientLevelOnSreen = new Point(_x, _y);
}
@@ -452,7 +409,7 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
final AbstractGraphicsConfiguration cWinCfg = this.getGraphicsConfiguration();
final NativeWindow pWin = getParent();
final AbstractGraphicsConfiguration pWinCfg = null != pWin ? pWin.getGraphicsConfiguration() : null;
- System.err.println("MacWindow reconfig.0: "+x+"/"+y+" -> clientPos "+pClientLevelOnSreen+" - "+width+"x"+height+
+ System.err.println("MacWindow reconfig.0: "+x+"/"+y+" -> clientPosOnScreen "+pClientLevelOnSreen+" - "+width+"x"+height+
", "+getReconfigStateMaskString(flags)+
",\n\t parent type "+(null != pWin ? pWin.getClass().getName() : null)+
",\n\t this-chosenCaps "+(null != cWinCfg ? cWinCfg.getChosenCapabilities() : null)+
@@ -477,38 +434,47 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
visibleChanged(true, false);
}
}
- if( ( 0 == getWindowHandle() && 0 != ( STATE_MASK_VISIBLE & flags) ) ||
+ final long oldWindowHandle = getWindowHandle();
+ if( ( 0 == oldWindowHandle && 0 != ( STATE_MASK_VISIBLE & flags) ) ||
0 != ( CHANGE_MASK_PARENTING & flags) ||
0 != ( CHANGE_MASK_DECORATION & flags) ||
+ 0 != ( CHANGE_MASK_ALWAYSONTOP & flags) ||
+ 0 != ( CHANGE_MASK_ALWAYSONBOTTOM & flags) ||
0 != ( CHANGE_MASK_RESIZABLE & flags) ||
0 != ( CHANGE_MASK_FULLSCREEN & flags) ) {
if(isOffscreenInstance) {
- createWindow(true, 0 != getWindowHandle(), pClientLevelOnSreen, 64, 64, flags);
+ createWindow(true, 0 != oldWindowHandle, pClientLevelOnSreen, 64, 64, flags);
} else {
- createWindow(false, 0 != getWindowHandle(), pClientLevelOnSreen, width, height, flags);
+ createWindow(false, 0 != oldWindowHandle, pClientLevelOnSreen, width, height, flags);
}
// no native event (fullscreen, some reparenting)
- positionChanged(false, x, y);
updatePixelScaleByWindowHandle(false /* sendEvent */);
- super.sizeChanged(false, width, height, true);
+ if( isOffscreenInstance) {
+ super.sizeChanged(false, width, height, true);
+ positionChanged(false, x, y);
+ } else {
+ updateSizePosInsets0(getWindowHandle(), false);
+ }
visibleChanged(false, 0 != ( STATE_MASK_VISIBLE & flags));
if( hasFocus ) {
requestFocusImpl(true);
}
- } else {
+ } else if( 0 != oldWindowHandle ) {
if( width>0 && height>0 ) {
if( !isOffscreenInstance ) {
OSXUtil.RunOnMainThread(true, false, new Runnable() {
@Override
public void run() {
- setWindowClientTopLeftPointAndSize0(getWindowHandle(),
+ setWindowClientTopLeftPointAndSize0(oldWindowHandle,
pClientLevelOnSreen.getX(), pClientLevelOnSreen.getY(),
width, height, 0 != ( STATE_MASK_VISIBLE & flags));
} } );
- } // else offscreen size is realized via recreation
- // no native event (fullscreen, some reparenting)
- positionChanged(true, x, y);
- super.sizeChanged(true, width, height, false);
+ updateSizePosInsets0(oldWindowHandle, false);
+ } else { // else offscreen size is realized via recreation
+ // no native event (fullscreen, some reparenting)
+ super.sizeChanged(false, width, height, false);
+ positionChanged(false, x, y);
+ }
}
if( 0 != ( CHANGE_MASK_VISIBILITY & flags) &&
0 != ( STATE_MASK_VISIBLE & flags) )
@@ -524,13 +490,11 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
visibleChanged(true, true);
}
}
- if( !isOffscreenInstance ) {
- setAlwaysOnTop0(getWindowHandle(), 0 != ( STATE_MASK_ALWAYSONTOP & flags));
- setAlwaysOnBottom0(getWindowHandle(), 0 != ( STATE_MASK_ALWAYSONBOTTOM & flags));
- }
+ } else {
+ throw new InternalError("Null windowHandle but no re-creation triggered, check visibility: "+getStateMaskString());
}
if(DEBUG_IMPLEMENTATION) {
- System.err.println("MaxWindow reconfig.X: "+getLocationOnScreenImpl(0, 0)+" "+getWidth()+"x"+getHeight()+", insets "+getInsets()+", "+getStateMaskString());
+ System.err.println("MacWindow reconfig.X: "+getLocationOnScreenImpl(0, 0)+" "+getWidth()+"x"+getHeight()+", insets "+getInsets()+", "+getStateMaskString());
}
return true;
}
@@ -538,46 +502,50 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
@Override
protected Point getLocationOnScreenImpl(final int x, final int y) {
final NativeWindow parent = getParent();
- final boolean useParent = useParent(parent);
- return getLocationOnScreenImpl(x, y, parent, useParent);
- }
-
- private Point getLocationOnScreenImpl(final int x, final int y, final NativeWindow parent, final boolean useParent) {
- if( !useParent && !isOffscreenInstance && 0 != surfaceHandle) {
- return OSXUtil.GetLocationOnScreen(surfaceHandle, x, y);
- }
-
- final Point p = new Point(x, y);
- if( useParent ) {
- p.translate( parent.getLocationOnScreen(null) );
+ if( useParent(parent) ) {
+ return getLocationOnScreenByParent(x, y, parent);
+ } else {
+ final long windowHandle = getWindowHandle();
+ if( !isOffscreenInstance && 0 != windowHandle ) {
+ return (Point) getLocationOnScreen0(windowHandle, x, y);
+ } else {
+ return new Point(x, y);
+ }
}
- return p;
}
- @Override
- protected void updateInsetsImpl(final Insets insets) {
- // nop - using event driven insetsChange(..)
+ private Point getLocationOnScreenByParent(final int x, final int y, final NativeWindow parent) {
+ return new Point(x, y).translate( parent.getLocationOnScreen(null) );
}
/** Callback for native screen position change event of the client area. */
protected void screenPositionChanged(final boolean defer, final int newX, final int newY) {
// passed coordinates are in screen position of the client area
- if(getWindowHandle()!=0) {
+ if( isNativeValid() ) {
final NativeWindow parent = getParent();
- if( null == parent || isOffscreenInstance ) {
+ if( !useParent(parent) || isOffscreenInstance ) {
if(DEBUG_IMPLEMENTATION) {
System.err.println("MacWindow.positionChanged.0 (Screen Pos - TOP): ("+getThreadName()+"): (defer: "+defer+") "+getX()+"/"+getY()+" -> "+newX+"/"+newY);
}
positionChanged(defer, newX, newY);
} else {
- // screen position -> rel child window position
- final Point absPos = new Point(newX, newY);
- final Point parentOnScreen = parent.getLocationOnScreen(null);
- absPos.translate( parentOnScreen.scale(-1, -1) );
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("MacWindow.positionChanged.1 (Screen Pos - CHILD): ("+getThreadName()+"): (defer: "+defer+") "+getX()+"/"+getY()+" -> absPos "+newX+"/"+newY+", parentOnScreen "+parentOnScreen+" -> "+absPos);
+ final Runnable action = new Runnable() {
+ public void run() {
+ // screen position -> rel child window position
+ final Point absPos = new Point(newX, newY);
+ final Point parentOnScreen = parent.getLocationOnScreen(null);
+ absPos.translate( parentOnScreen.scale(-1, -1) );
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("MacWindow.positionChanged.1 (Screen Pos - CHILD): ("+getThreadName()+"): (defer: "+defer+") "+getX()+"/"+getY()+" -> absPos "+newX+"/"+newY+", parentOnScreen "+parentOnScreen+" -> "+absPos);
+ }
+ positionChanged(false, absPos.getX(), absPos.getY());
+ } };
+ if( defer ) {
+ new InterruptSource.Thread(null, action).start();
+ } else {
+ action.run();
}
- positionChanged(defer, absPos.getX(), absPos.getY());
+
}
} else if(DEBUG_IMPLEMENTATION) {
System.err.println("MacWindow.positionChanged.2 (Screen Pos - IGN): ("+getThreadName()+"): (defer: "+defer+") "+getX()+"/"+getY()+" -> "+newX+"/"+newY);
@@ -585,6 +553,65 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
}
@Override
+ protected void sizeChanged(final boolean defer, final int newWidth, final int newHeight, final boolean force) {
+ if(force || getWidth() != newWidth || getHeight() != newHeight) {
+ if( isNativeValid() && !isOffscreenInstance ) {
+ final NativeWindow parent = getParent();
+ final boolean useParent = useParent(parent);
+ if( useParent ) {
+ final int x=getX(), y=getY();
+ final Point p0S = getLocationOnScreenByParent(x, y, parent);
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("MacWindow: sizeChanged() parent["+useParent+" "+x+"/"+y+"] "+getX()+"/"+getY()+" "+newWidth+"x"+newHeight+" -> "+p0S+" screen-client-pos");
+ }
+ OSXUtil.RunOnMainThread(false, false, new Runnable() {
+ @Override
+ public void run() {
+ setWindowClientTopLeftPoint0(getWindowHandle(), p0S.getX(), p0S.getY(), isVisible());
+ } } );
+ }
+ }
+ superSizeChangedOffThread(defer, newWidth, newHeight, force);
+ }
+ }
+ private void superSizeChangedOffThread(final boolean defer, final int newWidth, final int newHeight, final boolean force) {
+ if( defer ) {
+ new InterruptSource.Thread() {
+ public void run() {
+ WindowDriver.super.sizeChanged(false /* defer */, newWidth, newHeight, force);
+ } }.start();
+ } else {
+ WindowDriver.super.sizeChanged(false /* defer */, newWidth, newHeight, force);
+ }
+ }
+
+ //
+ // Accumulated actions
+ //
+
+ /** Triggered by implementation's WM events to update the client-area position, size and insets. */
+ protected void sizeScreenPosInsetsChanged(final boolean defer,
+ final int newX, final int newY,
+ final int newWidth, final int newHeight,
+ final int left, final int right, final int top, final int bottom,
+ final boolean force,
+ final boolean withinLiveResize) {
+ final LifecycleHook lh = getLifecycleHook();
+ if( withinLiveResize && !resizeAnimatorPaused && null!=lh ) {
+ resizeAnimatorPaused = lh.pauseRenderingAction();
+ }
+ sizeChanged(defer, newWidth, newHeight, force);
+ screenPositionChanged(defer, newX, newY);
+ insetsChanged(defer, left, right, top, bottom);
+ if( !withinLiveResize && resizeAnimatorPaused ) {
+ resizeAnimatorPaused = false;
+ if( null!=lh ) {
+ lh.resumeRenderingAction();
+ }
+ }
+ }
+
+ @Override
protected void setPointerIconImpl(final PointerIconImpl pi) {
if( !isOffscreenInstance ) {
final long piHandle = null != pi ? pi.validatedHandle() : 0;
@@ -688,10 +715,7 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
protected int getDisplayID() {
if( !isOffscreenInstance ) {
- final long whandle = getWindowHandle();
- if(0 != whandle) {
- return getDisplayID0(whandle);
- }
+ return getDisplayID0(getWindowHandle());
}
return 0;
}
@@ -767,14 +791,14 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
public void run() {
initWindow0( parentWinHandle, newWin, pS.getX(), pS.getY(), width, height, reqPixelScale[0] /* HiDPI uniformPixelScale */,
isOpaque,
+ !offscreenInstance && 0 != ( STATE_MASK_ALWAYSONTOP & flags),
+ !offscreenInstance && 0 != ( STATE_MASK_ALWAYSONBOTTOM & flags),
!offscreenInstance && 0 != ( STATE_MASK_VISIBLE & flags),
surfaceHandle);
if( offscreenInstance ) {
orderOut0(0!=parentWinHandle ? parentWinHandle : newWin);
} else {
setTitle0(newWin, getTitle());
- setAlwaysOnTop0(getWindowHandle(), 0 != ( STATE_MASK_ALWAYSONTOP & flags));
- setAlwaysOnBottom0(getWindowHandle(), 0 != ( STATE_MASK_ALWAYSONBOTTOM & flags));
}
} });
} catch (final Exception ie) {
@@ -787,7 +811,8 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
private native long createWindow0(int x, int y, int w, int h, boolean fullscreen, int windowStyle, int backingStoreType, long view);
/** Must be called on Main-Thread */
private native void initWindow0(long parentWindow, long window, int x, int y, int w, int h, float reqPixelScale,
- boolean opaque, boolean visible, long view);
+ boolean opaque, boolean atop, boolean abottom, boolean visible, long view);
+
private native int getDisplayID0(long window);
private native void setPixelScale0(long window, long view, float reqPixelScale);
private native boolean lockSurface0(long window, long view);
@@ -811,10 +836,8 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
private native void setWindowClientTopLeftPointAndSize0(long window, int x, int y, int w, int h, boolean display);
/** Must be called on Main-Thread */
private native void setWindowClientTopLeftPoint0(long window, int x, int y, boolean display);
- /** Must be called on Main-Thread */
- private native void setAlwaysOnTop0(long window, boolean atop);
- /** Must be called on Main-Thread */
- private native void setAlwaysOnBottom0(long window, boolean abottom);
+ /** Triggers {@link #sizeScreenPosInsetsChanged(boolean, int, int, int, int, int, int, int, int, boolean)} */
+ private native void updateSizePosInsets0(long window, boolean defer);
private static native Object getLocationOnScreen0(long windowHandle, int src_x, int src_y);
private static native void setPointerIcon0(long windowHandle, long handle);
private static native void setPointerVisible0(long windowHandle, boolean hasFocus, boolean visible);
@@ -836,5 +859,5 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
private volatile long surfaceHandle = 0;
private long sscSurfaceHandle = 0;
private boolean isOffscreenInstance = false;
-
+ private boolean resizeAnimatorPaused = false;
}
diff --git a/src/newt/classes/jogamp/newt/driver/opengl/JoglUtilPNGIcon.java b/src/newt/classes/jogamp/newt/driver/opengl/JoglUtilPNGIcon.java
index f9f1f13ad..f7d6b9f25 100644
--- a/src/newt/classes/jogamp/newt/driver/opengl/JoglUtilPNGIcon.java
+++ b/src/newt/classes/jogamp/newt/driver/opengl/JoglUtilPNGIcon.java
@@ -46,9 +46,17 @@ public class JoglUtilPNGIcon {
data_size[0] = 0;
for(int i=0; i<resources.resourceCount(); i++) {
final URLConnection urlConn = resources.resolve(i);
- final PNGPixelRect image = PNGPixelRect.read(urlConn.getInputStream(), PixelFormat.BGRA8888, false /* directBuffer */, 0 /* destMinStrideInBytes */, false /* destIsGLOriented */);
- data_size[0] += 2 + image.getSize().getWidth() * image.getSize().getHeight();
- images[i] = image;
+ if( null != urlConn ) {
+ final PNGPixelRect image = PNGPixelRect.read(urlConn.getInputStream(), PixelFormat.BGRA8888, false /* directBuffer */, 0 /* destMinStrideInBytes */, false /* destIsGLOriented */);
+ data_size[0] += 2 + image.getSize().getWidth() * image.getSize().getHeight();
+ images[i] = image;
+ } else {
+ images[i] = null;
+ }
+ }
+ if( 0 == data_size[0] ) {
+ // no image, abort
+ return null;
}
final boolean is64Bit = Platform.is64Bit();
elem_bytesize[0] = is64Bit ? Buffers.SIZEOF_LONG : Buffers.SIZEOF_INT;
@@ -56,29 +64,31 @@ public class JoglUtilPNGIcon {
for(int i=0; i<images.length; i++) {
final PNGPixelRect image1 = images[i];
- final int width = image1.getSize().getWidth();
- final int height = image1.getSize().getHeight();
- if( is64Bit ) {
- buffer.putLong(width);
- buffer.putLong(height);
- } else {
- buffer.putInt(width);
- buffer.putInt(height);
- }
- final ByteBuffer bb = image1.getPixels();
- final int stride = image1.getStride();
- for(int y=0; y<height; y++) {
- int bbOff = y * stride;
- for(int x=0; x<width; x++) {
- long pixel;
- pixel = ( 0xffL & bb.get(bbOff++) ); // B
- pixel |= ( 0xffL & bb.get(bbOff++) ) << 8; // G
- pixel |= ( 0xffL & bb.get(bbOff++) ) << 16; // R
- pixel |= ( 0xffL & bb.get(bbOff++) ) << 24; // A
- if( is64Bit ) {
- buffer.putLong(pixel);
- } else {
- buffer.putInt((int)pixel);
+ if( null != image1 ) {
+ final int width = image1.getSize().getWidth();
+ final int height = image1.getSize().getHeight();
+ if( is64Bit ) {
+ buffer.putLong(width);
+ buffer.putLong(height);
+ } else {
+ buffer.putInt(width);
+ buffer.putInt(height);
+ }
+ final ByteBuffer bb = image1.getPixels();
+ final int stride = image1.getStride();
+ for(int y=0; y<height; y++) {
+ int bbOff = y * stride;
+ for(int x=0; x<width; x++) {
+ long pixel;
+ pixel = ( 0xffL & bb.get(bbOff++) ); // B
+ pixel |= ( 0xffL & bb.get(bbOff++) ) << 8; // G
+ pixel |= ( 0xffL & bb.get(bbOff++) ) << 16; // R
+ pixel |= ( 0xffL & bb.get(bbOff++) ) << 24; // A
+ if( is64Bit ) {
+ buffer.putLong(pixel);
+ } else {
+ buffer.putInt((int)pixel);
+ }
}
}
}
diff --git a/src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java
index c44aa39f4..0bd7c5b2a 100644
--- a/src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java
@@ -68,19 +68,23 @@ public class DisplayDriver extends DisplayImpl {
final IOUtil.ClassResources iconRes = NewtFactory.getWindowIcons();
{
final URLConnection urlConn = iconRes.resolve(0);
- final PNGPixelRect image = PNGPixelRect.read(urlConn.getInputStream(), PixelFormat.BGRA8888, false /* directBuffer */, 0 /* destMinStrideInBytes */, false /* destIsGLOriented */);
- _defaultIconHandle[0] = DisplayDriver.createBGRA8888Icon0(image.getPixels(), image.getSize().getWidth(), image.getSize().getHeight(), false, 0, 0);
+ if( null != urlConn ) {
+ final PNGPixelRect image = PNGPixelRect.read(urlConn.getInputStream(), PixelFormat.BGRA8888, false /* directBuffer */, 0 /* destMinStrideInBytes */, false /* destIsGLOriented */);
+ _defaultIconHandle[0] = DisplayDriver.createBGRA8888Icon0(image.getPixels(), image.getSize().getWidth(), image.getSize().getHeight(), false, 0, 0);
+ }
}
{
final URLConnection urlConn = iconRes.resolve(iconRes.resourceCount()-1);
- final PNGPixelRect image = PNGPixelRect.read(urlConn.getInputStream(), PixelFormat.BGRA8888, false /* directBuffer */, 0 /* destMinStrideInBytes */, false /* destIsGLOriented */);
- _defaultIconHandle[1] = DisplayDriver.createBGRA8888Icon0(image.getPixels(), image.getSize().getWidth(), image.getSize().getHeight(), false, 0, 0);
+ if( null != urlConn ) {
+ final PNGPixelRect image = PNGPixelRect.read(urlConn.getInputStream(), PixelFormat.BGRA8888, false /* directBuffer */, 0 /* destMinStrideInBytes */, false /* destIsGLOriented */);
+ _defaultIconHandle[1] = DisplayDriver.createBGRA8888Icon0(image.getPixels(), image.getSize().getWidth(), image.getSize().getHeight(), false, 0, 0);
+ }
}
} catch (final Exception e) {
e.printStackTrace();
}
}
- defaultIconHandles = _defaultIconHandle;
+ defaultIconHandles = _defaultIconHandle; // null is a valid value for an icon handle
}
sharedClassFactory = new RegisteredClassFactory(newtClassBaseName, WindowDriver.getNewtWndProc0(),
false /* useDummyDispatchThread */, defaultIconHandles[0], defaultIconHandles[1]);
diff --git a/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java
index 6f2660358..af5dad3ac 100644
--- a/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java
@@ -45,7 +45,6 @@ import com.jogamp.nativewindow.AbstractGraphicsConfiguration;
import com.jogamp.nativewindow.GraphicsConfigurationFactory;
import com.jogamp.nativewindow.NativeWindowException;
import com.jogamp.nativewindow.VisualIDHolder;
-import com.jogamp.nativewindow.util.Insets;
import com.jogamp.nativewindow.util.InsetsImmutable;
import com.jogamp.nativewindow.util.Point;
@@ -141,17 +140,34 @@ public class WindowDriver extends WindowImpl {
}
setGraphicsConfiguration(cfg);
final VersionNumber winVer = Platform.getOSVersionNumber();
- final int flags = getReconfigureMask(0, true) & STATE_MASK_CREATENATIVE;
+ int flags = getReconfigureMask(0, true) & STATE_MASK_CREATENATIVE;
+ int maxCount = 0;
+ if( 0 != ( STATE_MASK_MAXIMIZED_HORZ & flags ) ) {
+ flags |= CHANGE_MASK_MAXIMIZED_HORZ;
+ maxCount++;
+ }
+ if( 0 != ( STATE_MASK_MAXIMIZED_VERT & flags ) ) {
+ flags |= CHANGE_MASK_MAXIMIZED_VERT;
+ maxCount++;
+ }
final long _windowHandle = CreateWindow0(DisplayDriver.getHInstance(), display.getWindowClassName(), display.getWindowClassName(),
winVer.getMajor(), winVer.getMinor(),
getParentWindowHandle(),
- getX(), getY(), getWidth(), getHeight(), autoPosition(), flags);
+ getX(), getY(), getWidth(), getHeight(), flags);
if ( 0 == _windowHandle ) {
throw new NativeWindowException("Error creating window");
}
+ if( !cfg.getChosenCapabilities().isBackgroundOpaque() ) {
+ GDIUtil.DwmSetupTranslucency(_windowHandle, true);
+ }
+ InitWindow0(_windowHandle, flags);
setWindowHandle(_windowHandle);
windowHandleClose = _windowHandle;
+ if( 0 == ( STATE_MASK_CHILDWIN & flags ) && 1 == maxCount ) {
+ reconfigureWindowImpl(getX(), getY(), getWidth(), getHeight(), flags);
+ }
+
if(DEBUG_IMPLEMENTATION) {
final Exception e = new Exception("Info: Window new window handle "+Thread.currentThread().getName()+
" (Parent HWND "+toHexString(getParentWindowHandle())+
@@ -188,26 +204,51 @@ public class WindowDriver extends WindowImpl {
}
@Override
+ protected final int getSupportedReconfigMaskImpl() {
+ return minimumReconfigStateMask |
+ STATE_MASK_CHILDWIN |
+ STATE_MASK_UNDECORATED |
+ STATE_MASK_ALWAYSONTOP |
+ STATE_MASK_ALWAYSONBOTTOM |
+ // STATE_MASK_STICKY |
+ STATE_MASK_RESIZABLE |
+ STATE_MASK_MAXIMIZED_VERT |
+ STATE_MASK_MAXIMIZED_HORZ |
+ STATE_MASK_POINTERVISIBLE |
+ STATE_MASK_POINTERCONFINED;
+ }
+
+ @Override
protected boolean reconfigureWindowImpl(int x, int y, int width, int height, final int flags) {
if(DEBUG_IMPLEMENTATION) {
System.err.println("WindowsWindow reconfig.0: "+x+"/"+y+" "+width+"x"+height+
", "+getReconfigStateMaskString(flags));
}
-
- if(0 == ( STATE_MASK_UNDECORATED & flags)) {
- final InsetsImmutable i = getInsets();
-
- // client position -> top-level window position
- x -= i.getLeftWidth() ;
- y -= i.getTopHeight() ;
-
- if(0<width && 0<height) {
- // client size -> top-level window size
- width += i.getTotalWidth();
- height += i.getTotalHeight();
+ final InsetsImmutable insets = getInsets();
+
+ if( 0 == ( STATE_MASK_CHILDWIN & flags ) &&
+ 0 != ( ( CHANGE_MASK_MAXIMIZED_HORZ | CHANGE_MASK_MAXIMIZED_VERT ) & flags ) ) {
+ final int[] posSize = { x, y, width, height };
+ if( ( 0 != ( STATE_MASK_MAXIMIZED_HORZ & flags ) ) == ( 0 != ( STATE_MASK_MAXIMIZED_VERT & flags ) ) ) {
+ resetMaximizedManual(posSize); // reset before native maximize/reset
+ } else {
+ reconfigMaximizedManual(flags, posSize, insets);
}
+ x = posSize[0];
+ y = posSize[1];
+ width = posSize[2];
+ height = posSize[3];
+ }
+
+ final boolean changeDecoration = 0 != ( CHANGE_MASK_DECORATION & flags);
+ final boolean isTranslucent = !getChosenCapabilities().isBackgroundOpaque();
+ if( changeDecoration && isTranslucent ) {
+ GDIUtil.DwmSetupTranslucency(getWindowHandle(), false);
}
reconfigureWindow0( getParentWindowHandle(), getWindowHandle(), x, y, width, height, flags);
+ if( changeDecoration && isTranslucent ) {
+ GDIUtil.DwmSetupTranslucency(getWindowHandle(), true);
+ }
if( 0 != ( CHANGE_MASK_VISIBILITY & flags) ) {
visibleChanged(false, 0 != ( STATE_MASK_VISIBLE & flags));
@@ -279,11 +320,6 @@ public class WindowDriver extends WindowImpl {
return GDIUtil.GetRelativeLocation( getWindowHandle(), 0 /*root win*/, x, y);
}
- @Override
- protected void updateInsetsImpl(final Insets insets) {
- // nop - using event driven insetsChange(..)
- }
-
//
// PointerEvent Handling
//
@@ -372,7 +408,8 @@ public class WindowDriver extends WindowImpl {
protected static native boolean initIDs0(long hInstance);
private native long CreateWindow0(long hInstance, String wndClassName, String wndName, int winMajor, int winMinor,
- long parentWindowHandle, int x, int y, int width, int height, boolean autoPosition, int flags);
+ long parentWindowHandle, int x, int y, int width, int height, int flags);
+ private native void InitWindow0(long windowHandle, int flags);
private native long MonitorFromWindow0(long windowHandle);
private native void reconfigureWindow0(long parentWindowHandle, long windowHandle,
int x, int y, int width, int height, int flags);
diff --git a/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java
index d0026deaf..9e1d2869b 100644
--- a/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java
@@ -46,7 +46,6 @@ import jogamp.newt.driver.PNGIcon;
import com.jogamp.nativewindow.*;
import com.jogamp.nativewindow.VisualIDHolder.VIDType;
-import com.jogamp.nativewindow.util.Insets;
import com.jogamp.nativewindow.util.InsetsImmutable;
import com.jogamp.nativewindow.util.Point;
@@ -134,7 +133,7 @@ public class WindowDriver extends WindowImpl {
if (null == handles || 2 != handles.length || 0 == handles[0] || 0 == handles[1] ) {
throw new NativeWindowException("Error creating window");
}
- if(DEBUG_IMPLEMENTATION) { // FIXME
+ if(DEBUG_IMPLEMENTATION) {
System.err.println("X11Window.createNativeImpl() handles "+toHexString(handles[0])+", "+toHexString(handles[1]));
}
setWindowHandle(handles[0]);
@@ -169,15 +168,9 @@ public class WindowDriver extends WindowImpl {
}
}
- /**
- * <p>
- * X11 Window supports {@link #FLAG_IS_FULLSCREEN_SPAN}
- * </p>
- * {@inheritDoc}
- */
@Override
- protected boolean isReconfigureMaskSupported(final int changeFlags) {
- return true; // all flags!
+ protected final int getSupportedReconfigMaskImpl() {
+ return ( minimumReconfigStateMask | GetSupportedReconfigMask0(javaWindowHandle) ) & STATE_MASK_ALL_RECONFIG;
}
@Override
@@ -347,11 +340,6 @@ public class WindowDriver extends WindowImpl {
}
@Override
- protected void updateInsetsImpl(final Insets insets) {
- // nop - using event driven insetsChange(..)
- }
-
- @Override
protected final void doMouseEvent(final boolean enqueue, final boolean wait, short eventType, int modifiers,
final int x, final int y, short button, final float[] rotationXYZ, final float rotationScale) {
switch(eventType) {
@@ -458,12 +446,12 @@ public class WindowDriver extends WindowImpl {
int x, int y, int width, int height, int flags,
int pixelDataSize, Object pixels, int pixels_byte_offset, boolean pixels_is_direct,
boolean verbose);
- private native long GetNativeWindowHandle0(long javaWindowHandle);
+ private static native int GetSupportedReconfigMask0(long javaWindowHandle);
private native void CloseWindow0(long display, long javaWindowHandle /*, long kbdHandle*/, // XKB disabled for now
final int randr_event_base, final int randr_error_base);
- private native void reconfigureWindow0(long display, int screen_index, long parentWindowHandle, long javaWindowHandle,
- int x, int y, int width, int height, int flags);
- private native void requestFocus0(long display, long javaWindowHandle, boolean force);
+ private static native void reconfigureWindow0(long display, int screen_index, long parentWindowHandle, long javaWindowHandle,
+ int x, int y, int width, int height, int flags);
+ private static native void requestFocus0(long display, long javaWindowHandle, boolean force);
private static native void setTitle0(long display, long javaWindowHandle, String title);
diff --git a/src/newt/classes/jogamp/newt/driver/x11/X11UnderlayTracker.java b/src/newt/classes/jogamp/newt/driver/x11/X11UnderlayTracker.java
index 6e64e7025..1be6dcea8 100644
--- a/src/newt/classes/jogamp/newt/driver/x11/X11UnderlayTracker.java
+++ b/src/newt/classes/jogamp/newt/driver/x11/X11UnderlayTracker.java
@@ -38,6 +38,7 @@ import com.jogamp.common.util.ReflectionUtil;
import com.jogamp.nativewindow.Capabilities;
import com.jogamp.nativewindow.GraphicsConfigurationFactory;
import com.jogamp.nativewindow.NativeWindowFactory;
+import com.jogamp.nativewindow.util.Point;
import com.jogamp.newt.Display;
import com.jogamp.newt.NewtFactory;
import com.jogamp.newt.Screen;
@@ -135,19 +136,52 @@ public class X11UnderlayTracker implements WindowListener, KeyListener, MouseLis
if (underlayWindowMap.containsKey(s)) {
WindowImpl underlayWindow = (WindowImpl)s;
WindowImpl overlayWindow = underlayWindowMap.get(s);
- if(overlayWindow.getX()!=underlayWindow.getX() ||
- overlayWindow.getY()!=underlayWindow.getY()) {
- overlayWindow.setPosition(underlayWindow.getX(), underlayWindow.getY());
+ Point overlayOnScreen = new Point();
+ Point underlayOnScreen = new Point();
+ overlayWindow.getLocationOnScreen(overlayOnScreen);
+ underlayWindow.getLocationOnScreen(underlayOnScreen);
+ if(overlayOnScreen.getX()!=underlayOnScreen.getX() ||
+ overlayOnScreen.getY()!=underlayOnScreen.getY()) {
+ overlayWindow.setPosition(underlayOnScreen.getX(), underlayOnScreen.getY());
}
} else if (overlayWindowMap.containsKey(s)) {
WindowImpl overlayWindow = (WindowImpl)s;
WindowImpl underlayWindow = overlayWindowMap.get(s);
- if(overlayWindow.getX()!=underlayWindow.getX() ||
- overlayWindow.getY()!=underlayWindow.getY()) {
- //FIXME: Pressing Maximize on the underlay X11
- //with this line enabled locks-up the NEWT EDT while using the BCM.VC.IV
- //underlayWindow.setPosition(overlayWindow.getX(), overlayWindow.getY());
+ // FIXME: Pressing Maximize on the underlay X11
+ // with these lines enabled locks-up the NEWT EDT
+ /*
+ Point overlayOnScreen = new Point();
+ Point underlayOnScreen = new Point();
+ overlayWindow.getLocationOnScreen(overlayOnScreen);
+ underlayWindow.getLocationOnScreen(underlayOnScreen);
+ if(overlayOnScreen.getX()!=underlayOnScreen.getX() ||
+ overlayOnScreen.getY()!=underlayOnScreen.getY()) {
+ underlayWindow.setPosition(overlayOnScreen.getX(), overlayOnScreen.getY());
}
+ */
+ /* it locks up like this
+ Caused by: java.lang.RuntimeException: Waited 5000ms for: <5ccc078, 45700941>[count 1, qsz 0, owner <main-Display-.x11_:0-1-EDT-1>] - <main-Display-.x11_:0-2-EDT-1>
+ at jogamp.common.util.locks.RecursiveLockImpl01Unfairish.lock(RecursiveLockImpl01Unfairish.java:198)
+ at jogamp.nativewindow.ResourceToolkitLock.lock(ResourceToolkitLock.java:56)
+ at com.jogamp.nativewindow.DefaultGraphicsDevice.lock(DefaultGraphicsDevice.java:126)
+ at jogamp.newt.DisplayImpl.runWithLockedDevice(DisplayImpl.java:780)
+ at jogamp.newt.DisplayImpl.runWithLockedDisplayDevice(DisplayImpl.java:793)
+ at jogamp.newt.driver.x11.WindowDriver.runWithLockedDisplayDevice(WindowDriver.java:425)
+ at jogamp.newt.driver.x11.WindowDriver.getLocationOnScreenImpl(WindowDriver.java:334)
+ at jogamp.newt.WindowImpl.getLocationOnScreen(WindowImpl.java:1113)
+ at jogamp.newt.driver.x11.X11UnderlayTracker.windowMoved(X11UnderlayTracker.java:153)
+ at jogamp.newt.WindowImpl.consumeWindowEvent(WindowImpl.java:4243)
+ at jogamp.newt.WindowImpl.sendWindowEvent(WindowImpl.java:4174)
+ at jogamp.newt.WindowImpl.positionChanged(WindowImpl.java:4403)
+ at jogamp.newt.WindowImpl.sizePosMaxInsetsChanged(WindowImpl.java:4567)
+ at jogamp.newt.driver.x11.DisplayDriver.DispatchMessages0(Native Method)
+ at jogamp.newt.driver.x11.DisplayDriver.dispatchMessagesNative(DisplayDriver.java:112)
+ at jogamp.newt.WindowImpl.waitForPosition(WindowImpl.java:4438)
+ at jogamp.newt.WindowImpl.access$2200(WindowImpl.java:96)
+ at jogamp.newt.WindowImpl$SetPositionAction.run(WindowImpl.java:2765)
+ at com.jogamp.common.util.RunnableTask.run(RunnableTask.java:150)
+ at jogamp.newt.DefaultEDTUtil$NEDT.run(DefaultEDTUtil.java:372)
+ */
}
}
@@ -366,20 +400,16 @@ public class X11UnderlayTracker implements WindowListener, KeyListener, MouseLis
@Override
public void keyPressed(KeyEvent e) {
if (focusedWindow != null) {
- // e.setConsumed(false);
- // focusedWindow.consumeEvent(e);
focusedWindow.sendKeyEvent(e.getEventType(), e.getModifiers(),
- e.getKeyCode(), e.getKeyCode(), (char) e.getKeySymbol());
+ e.getKeyCode(), e.getKeySymbol(), e.getKeyChar());
}
}
@Override
public void keyReleased(KeyEvent e) {
if (focusedWindow != null) {
- // e.setConsumed(false);
- // focusedWindow.consumeEvent(e);
focusedWindow.sendKeyEvent(e.getEventType(), e.getModifiers(),
- e.getKeyCode(), e.getKeyCode(), (char) e.getKeySymbol());
+ e.getKeyCode(), e.getKeySymbol(), e.getKeyChar());
}
}
diff --git a/src/newt/classes/jogamp/newt/event/NEWTEventTask.java b/src/newt/classes/jogamp/newt/event/NEWTEventTask.java
index 2bdab2796..260a1beb4 100644
--- a/src/newt/classes/jogamp/newt/event/NEWTEventTask.java
+++ b/src/newt/classes/jogamp/newt/event/NEWTEventTask.java
@@ -38,19 +38,27 @@ public class NEWTEventTask {
private final NEWTEvent event;
private final Object notifyObject;
private RuntimeException exception;
+ private volatile boolean dispatched;
public NEWTEventTask(final NEWTEvent event, final Object notifyObject) {
this.event = event ;
this.notifyObject = notifyObject ;
this.exception = null;
+ this.dispatched = false;
}
public final NEWTEvent get() { return event; }
public final void setException(final RuntimeException e) { exception = e; }
public final RuntimeException getException() { return exception; }
public final boolean isCallerWaiting() { return null != notifyObject; }
+ public final boolean isDispatched() { return dispatched; }
+ public final void setDispatched() { dispatched = true; }
+ /**
+ * Notifies caller after {@link #setDispatched()}.
+ */
public void notifyCaller() {
+ setDispatched();
if(null != notifyObject) {
synchronized (notifyObject) {
notifyObject.notifyAll();
diff --git a/src/newt/classes/jogamp/newt/javafx/JFXEDTUtil.java b/src/newt/classes/jogamp/newt/javafx/JFXEDTUtil.java
new file mode 100644
index 000000000..4ee15b43d
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/javafx/JFXEDTUtil.java
@@ -0,0 +1,358 @@
+/**
+ * Copyright 2019 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.javafx;
+
+import com.jogamp.nativewindow.NativeWindowException;
+import com.jogamp.nativewindow.javafx.JFXAccessor;
+
+import jogamp.newt.Debug;
+
+import com.jogamp.common.ExceptionUtils;
+import com.jogamp.common.util.InterruptSource;
+import com.jogamp.common.util.InterruptedRuntimeException;
+import com.jogamp.common.util.RunnableTask;
+import com.jogamp.newt.util.EDTUtil;
+
+import javafx.application.Platform;
+
+/**
+ * Simple {@link EDTUtil} implementation utilizing the JFX UI thread
+ * of the given {@link Display}.
+ */
+public class JFXEDTUtil implements EDTUtil {
+ 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 NEDT nedt = null;
+ private int start_iter=0;
+ private static long pollPeriod = EDTUtil.defaultEDTPollPeriod;
+
+ public JFXEDTUtil(final com.jogamp.newt.Display newtDisplay) {
+ this.threadGroup = Thread.currentThread().getThreadGroup();
+ this.name=Thread.currentThread().getName()+"-JFXDisplay-"+newtDisplay.getFQName()+"-EDT-";
+ this.dispatchMessages = new Runnable() {
+ @Override
+ public void run() {
+ ((jogamp.newt.DisplayImpl) newtDisplay).dispatchMessages();
+ } };
+ this.nedt = new NEDT(threadGroup, name);
+ this.nedt.setDaemon(true); // don't stop JVM from shutdown ..
+ }
+
+ @Override
+ public long getPollPeriod() {
+ return pollPeriod;
+ }
+
+ @Override
+ public void setPollPeriod(final long ms) {
+ pollPeriod = ms; // writing to static field is intended
+ }
+
+ @Override
+ public final void start() throws IllegalStateException {
+ synchronized(edtLock) {
+ if( nedt.isRunning() ) {
+ final Thread curT = Thread.currentThread();
+ final boolean onJFXEDT = JFXAccessor.isJFXThread();
+ throw new IllegalStateException("EDT still running and not subject to stop. Curr "+curT.getName()+
+ ", NEDT "+nedt.getName()+", isRunning "+nedt.isRunning+", shouldStop "+nedt.shouldStop+", JFX-EDT "+JFXAccessor.getJFXThreadName()+", on JFX-EDT "+onJFXEDT);
+ }
+ if(DEBUG) {
+ System.err.println(Thread.currentThread()+": JFX-EDT reset - edt: "+nedt);
+ }
+ if( !JFXAccessor.hasJFXThreadStopped() ) {
+ if( nedt.getState() != Thread.State.NEW ) {
+ nedt = new NEDT(threadGroup, name);
+ nedt.setDaemon(true); // don't stop JVM from shutdown ..
+ }
+ startImpl();
+ }
+ }
+ if( !JFXAccessor.hasJFXThreadStopped() ) {
+ if( !nedt.isRunning() ) {
+ throw new RuntimeException("EDT could not be started: "+nedt);
+ }
+ } else {
+ // FIXME: Throw exception ?
+ }
+ }
+
+ private final void startImpl() {
+ if(nedt.isAlive()) {
+ throw new RuntimeException("JFX-EDT Thread.isAlive(): true, isRunning: "+nedt.isRunning+", shouldStop "+nedt.shouldStop+", edt: "+nedt);
+ }
+ start_iter++;
+ nedt.setName(name+start_iter);
+ if(DEBUG) {
+ System.err.println(Thread.currentThread()+": JFX-EDT START - edt: "+nedt+", jfxThread "+JFXAccessor.getJFXThreadName());
+ // Thread.dumpStack();
+ }
+ nedt.start();
+ }
+
+ @Override
+ public boolean isCurrentThreadEDT() {
+ return JFXAccessor.isJFXThread();
+ }
+
+ @Override
+ public final boolean isCurrentThreadNEDT() {
+ return nedt == Thread.currentThread();
+ }
+
+ @Override
+ public final boolean isCurrentThreadEDTorNEDT() {
+ return JFXAccessor.isJFXThread() || Thread.currentThread() == nedt ;
+ }
+
+ @Override
+ public boolean isRunning() {
+ return nedt.isRunning();
+ }
+
+ @Override
+ public final boolean invokeStop(final boolean wait, final Runnable task) {
+ return invokeImpl(wait, task, true);
+ }
+
+ @Override
+ public final boolean invoke(final boolean wait, final Runnable task) {
+ return invokeImpl(wait, task, false);
+ }
+
+ private static Runnable nullTask = new Runnable() {
+ @Override
+ public void run() { }
+ };
+
+ private final boolean invokeImpl(boolean wait, final Runnable task, boolean stop) {
+ final RunnableTask rTask;
+ final Object rTaskLock = new Object();
+ synchronized(rTaskLock) { // lock the optional task execution
+ synchronized(edtLock) { // lock the EDT status
+ if( nedt.shouldStop ) {
+ // drop task ..
+ if(DEBUG) {
+ System.err.println(Thread.currentThread()+": Warning: JFX-EDT about (1) to stop, won't enqueue new task: "+nedt+", isRunning "+nedt.isRunning+", shouldStop "+nedt.shouldStop);
+ ExceptionUtils.dumpStack(System.err);
+ }
+ return false;
+ }
+ final boolean hasJFXThreadStopped = JFXAccessor.hasJFXThreadStopped();
+
+ if( hasJFXThreadStopped ) {
+ stop = true;
+ }
+
+ if( isCurrentThreadEDT() ) {
+ if(null != task) {
+ task.run();
+ }
+ wait = false; // running in same thread (EDT) -> no wait
+ rTask = null;
+ if( stop ) {
+ nedt.shouldStop = true;
+ }
+ } else {
+ if( !nedt.isRunning && !hasJFXThreadStopped ) {
+ if( null != task ) {
+ if( stop ) {
+ System.err.println(Thread.currentThread()+": Warning: JFX-EDT is about (3) to stop and stopped already, dropping task. NEDT "+nedt);
+ } else {
+ System.err.println(Thread.currentThread()+": Warning: JFX-EDT is not running, dropping task. NEDT "+nedt);
+ }
+ if(DEBUG) {
+ ExceptionUtils.dumpStack(System.err);
+ }
+ }
+ return false;
+ } else if( stop ) {
+ if( nedt.isRunning ) {
+ if(DEBUG) {
+ System.err.println(Thread.currentThread()+": JFX-EDT signal STOP (on edt: "+isCurrentThreadEDT()+") - "+nedt+", isRunning "+nedt.isRunning+", shouldStop "+nedt.shouldStop);
+ }
+ synchronized(nedt.sync) {
+ nedt.shouldStop = true;
+ nedt.sync.notifyAll(); // stop immediate if waiting (poll freq)
+ }
+ }
+ if( JFXAccessor.hasJFXThreadStopped() ) {
+ System.err.println(Thread.currentThread()+": Warning: JFX-EDT is about (3) to stop and stopped already, dropping task. "+nedt);
+ if(DEBUG) {
+ ExceptionUtils.dumpStack(System.err);
+ }
+ return false;
+ }
+ }
+
+ if( null != task ) {
+ rTask = new RunnableTask(task,
+ wait ? rTaskLock : null,
+ true /* always catch and report Exceptions, don't disturb EDT */,
+ wait ? null : System.err);
+ Platform.runLater(rTask);
+ } else {
+ wait = false;
+ rTask = null;
+ }
+ }
+ }
+ if( wait ) {
+ try {
+ while( rTask.isInQueue() ) {
+ rTaskLock.wait(); // free lock, allow execution of rTask
+ }
+ } catch (final InterruptedException ie) {
+ throw new InterruptedRuntimeException(ie);
+ }
+ final Throwable throwable = rTask.getThrowable();
+ if(null!=throwable) {
+ if(throwable instanceof NativeWindowException) {
+ throw (NativeWindowException)throwable;
+ }
+ throw new RuntimeException(throwable);
+ }
+ }
+ return true;
+ }
+ }
+
+ @Override
+ final public boolean waitUntilIdle() {
+ final NEDT _nedt;
+ synchronized(edtLock) {
+ _nedt = nedt;
+ }
+ if( !_nedt.isRunning || Thread.currentThread() == _nedt || JFXAccessor.hasJFXThreadStopped() || JFXAccessor.isJFXThread() ) {
+ return false;
+ }
+ JFXAccessor.runOnJFXThread(true, nullTask);
+ return true;
+ }
+
+ @Override
+ final public boolean waitUntilStopped() {
+ synchronized(edtLock) {
+ final Thread curT = Thread.currentThread();
+ final boolean onJFXEDT = JFXAccessor.isJFXThread();
+ if( nedt.isRunning && nedt != curT && !onJFXEDT ) {
+ try {
+ while( nedt.isRunning ) {
+ edtLock.wait();
+ }
+ } catch (final InterruptedException e) {
+ throw new InterruptedRuntimeException(e);
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+
+ class NEDT extends InterruptSource.Thread {
+ volatile boolean shouldStop = false;
+ volatile boolean isRunning = false;
+ Object sync = new Object();
+
+ public NEDT(final ThreadGroup tg, final String name) {
+ super(tg, null, name);
+ }
+
+ final public boolean isRunning() {
+ return isRunning && !shouldStop;
+ }
+
+ @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()+": JFX-EDT run() START "+ getName());
+ }
+ RuntimeException error = null;
+ try {
+ do {
+ // event dispatch
+ if(!shouldStop) {
+ // EDT invoke thread is JFX-EDT,
+ // hence dispatching is required to run on JFX-EDT as well.
+ // Otherwise a deadlock may happen due to dispatched event's
+ // triggering a locking action.
+ JFXAccessor.runOnJFXThread(true, dispatchMessages);
+ }
+ // wait
+ synchronized(sync) {
+ if(!shouldStop) {
+ try {
+ sync.wait(pollPeriod);
+ } catch (final InterruptedException e) {
+ throw new InterruptedRuntimeException(e);
+ }
+ }
+ }
+ } while(!shouldStop) ;
+ } catch (final Throwable t) {
+ // handle errors ..
+ shouldStop = true;
+ if(t instanceof RuntimeException) {
+ error = (RuntimeException) t;
+ } else {
+ error = new RuntimeException("Within JFX-EDT", t);
+ }
+ } finally {
+ if(DEBUG) {
+ System.err.println(getName()+": JFX-EDT run() END "+ getName()+", "+error);
+ }
+ synchronized(edtLock) {
+ isRunning = false;
+ edtLock.notifyAll();
+ }
+ if(DEBUG) {
+ System.err.println(getName()+": JFX-EDT run() EXIT "+ getName()+", exception: "+error);
+ }
+ if(null!=error) {
+ throw error;
+ }
+ } // finally
+ } // run()
+ } // EventDispatchThread
+
+}
diff --git a/src/newt/classes/jogamp/newt/swt/SWTEDTUtil.java b/src/newt/classes/jogamp/newt/swt/SWTEDTUtil.java
index 9039b6083..9d2b41bbc 100644
--- a/src/newt/classes/jogamp/newt/swt/SWTEDTUtil.java
+++ b/src/newt/classes/jogamp/newt/swt/SWTEDTUtil.java
@@ -32,6 +32,8 @@ import com.jogamp.nativewindow.NativeWindowException;
import jogamp.newt.Debug;
import com.jogamp.common.ExceptionUtils;
+import com.jogamp.common.util.InterruptSource;
+import com.jogamp.common.util.InterruptedRuntimeException;
import com.jogamp.common.util.RunnableTask;
import com.jogamp.newt.util.EDTUtil;
@@ -162,8 +164,7 @@ public class SWTEDTUtil implements EDTUtil {
}
private final boolean invokeImpl(boolean wait, final Runnable task, boolean stop) {
- Throwable throwable = null;
- RunnableTask rTask = null;
+ final RunnableTask rTask;
final Object rTaskLock = new Object();
synchronized(rTaskLock) { // lock the optional task execution
synchronized(edtLock) { // lock the EDT status
@@ -184,6 +185,7 @@ public class SWTEDTUtil implements EDTUtil {
task.run();
}
wait = false; // running in same thread (EDT) -> no wait
+ rTask = null;
if( stop ) {
nedt.shouldStop = true;
}
@@ -225,18 +227,21 @@ public class SWTEDTUtil implements EDTUtil {
true /* always catch and report Exceptions, don't disturb EDT */,
wait ? null : System.err);
swtDisplay.asyncExec(rTask);
+ } else {
+ wait = false;
+ rTask = null;
}
}
}
if( wait ) {
try {
- rTaskLock.wait(); // free lock, allow execution of rTask
+ while( rTask.isInQueue() ) {
+ rTaskLock.wait(); // free lock, allow execution of rTask
+ }
} catch (final InterruptedException ie) {
- throwable = ie;
- }
- if(null==throwable) {
- throwable = rTask.getThrowable();
+ throw new InterruptedRuntimeException(ie);
}
+ final Throwable throwable = rTask.getThrowable();
if(null!=throwable) {
if(throwable instanceof NativeWindowException) {
throw (NativeWindowException)throwable;
@@ -274,12 +279,12 @@ public class SWTEDTUtil implements EDTUtil {
final Thread swtT = !swtDisplay.isDisposed() ? swtDisplay.getThread() : null;
final boolean onSWTEDT = swtT == curT;
if( nedt.isRunning && nedt != curT && !onSWTEDT ) {
- while( nedt.isRunning ) {
- try {
+ try {
+ while( nedt.isRunning ) {
edtLock.wait();
- } catch (final InterruptedException e) {
- e.printStackTrace();
}
+ } catch (final InterruptedException e) {
+ throw new InterruptedRuntimeException(e);
}
return true;
} else {
@@ -288,13 +293,13 @@ public class SWTEDTUtil implements EDTUtil {
}
}
- class NEDT extends Thread {
+ class NEDT extends InterruptSource.Thread {
volatile boolean shouldStop = false;
volatile boolean isRunning = false;
Object sync = new Object();
public NEDT(final ThreadGroup tg, final String name) {
- super(tg, name);
+ super(tg, null, name);
}
final public boolean isRunning() {
@@ -337,7 +342,7 @@ public class SWTEDTUtil implements EDTUtil {
try {
sync.wait(pollPeriod);
} catch (final InterruptedException e) {
- e.printStackTrace();
+ throw new InterruptedRuntimeException(e);
}
}
}
diff --git a/src/newt/native/MacWindow.m b/src/newt/native/MacWindow.m
index b59e19e4e..ee012add3 100644
--- a/src/newt/native/MacWindow.m
+++ b/src/newt/native/MacWindow.m
@@ -832,8 +832,12 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_createWindow
}
JNIEXPORT jint JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_getDisplayID0(JNIEnv *env, jobject jthis, jlong window) {
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NewtMacWindow* myWindow = (NewtMacWindow*) ((intptr_t) window);
+ if( NULL == myWindow ) {
+ DBG_PRINT( "getDisplayID0 - NULL NEWT win - abort\n");
+ return 0;
+ }
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSScreen *screen = [myWindow screen];
int32_t displayID = (int32_t)NewtScreen_getCGDirectDisplayIDByNSScreen(screen);
[pool release];
@@ -849,16 +853,16 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_getDisplayID0
*/
JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_initWindow0
(JNIEnv *env, jobject jthis, jlong parent, jlong window, jint x, jint y, jint w, jint h, jfloat reqPixelScale,
- jboolean opaque, jboolean visible, jlong jview)
+ jboolean opaque, jboolean atop, jboolean abottom, jboolean visible, jlong jview)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NewtMacWindow* myWindow = (NewtMacWindow*) ((intptr_t) window);
NewtView* myView = (NewtView*) (intptr_t) jview ;
BOOL fullscreen = myWindow->isFullscreenWindow;
- DBG_PRINT( "initWindow0 - %p (this), %p (parent), %p (window), %d/%d %dx%d, reqPixScale %f, opaque %d, fs %d, visible %d, view %p (START)\n",
+ DBG_PRINT( "initWindow0 - %p (this), %p (parent), %p (window), %d/%d %dx%d, reqPixScale %f, opaque %d, atop %d, abottom %d, fs %d, visible %d, view %p (START)\n",
(void*)(intptr_t)jthis, (void*)(intptr_t)parent, myWindow, (int)x, (int)y, (int)w, (int)h, (float)reqPixelScale,
- (int) opaque, (int)fullscreen, (int)visible, myView);
+ (int) opaque, (int)atop, (int)abottom, (int)fullscreen, (int)visible, myView);
NS_DURING
// HiDPI scaling: Setup - Available >= 10.7
@@ -921,6 +925,7 @@ NS_ENDHANDLER
[myWindow setOpaque: NO];
[myWindow setBackgroundColor: [NSColor clearColor]];
}
+ [myWindow setAlwaysOn: atop bottom:abottom];
// specify we want mouse-moved events
[myWindow setAcceptsMouseMovedEvents:YES];
@@ -1035,8 +1040,12 @@ NS_ENDHANDLER
JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setPixelScale0
(JNIEnv *env, jobject jthis, jlong window, jlong view, jfloat reqPixelScale)
{
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NewtMacWindow* myWindow = (NewtMacWindow*) ((intptr_t) window);
+ if( NULL == myWindow ) {
+ DBG_PRINT( "setPixelScale0 - NULL NEWT win - abort\n");
+ return;
+ }
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NewtView* myView = (NewtView*) (intptr_t) view ;
#ifdef VERBOSE_ON
int dbgIdx = 1;
@@ -1195,8 +1204,12 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_unlockSur
JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_requestFocus0
(JNIEnv *env, jobject window, jlong w, jboolean force)
{
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSWindow* mWin = (NSWindow*) ((intptr_t) w);
+ if( NULL == mWin ) {
+ DBG_PRINT( "requestFocus - NULL NEWT win - abort\n");
+ return;
+ }
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
#ifdef VERBOSE_ON
BOOL hasFocus = [mWin isKeyWindow];
#endif
@@ -1220,12 +1233,16 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_requestFocus0
JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_resignFocus0
(JNIEnv *env, jobject window, jlong w)
{
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSWindow* mWin = (NSWindow*) ((intptr_t) w);
+ if( NULL == mWin ) {
+ DBG_PRINT( "resignFocus0 - NULL NEWT win - abort\n");
+ return;
+ }
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSWindow* pWin = [mWin parentWindow];
BOOL hasFocus = [mWin isKeyWindow];
- DBG_PRINT( "requestFocusParent0 - window: %p, parent %p, hasFocus %d (START)\n", mWin, pWin, hasFocus );
+ DBG_PRINT( "resignFocus0 - window: %p, parent %p, hasFocus %d (START)\n", mWin, pWin, hasFocus );
if( hasFocus ) {
if(NULL != pWin) {
// [mWin makeFirstResponder: pWin];
@@ -1234,7 +1251,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_resignFocus0
[pWin resignKeyWindow];
}
}
- DBG_PRINT( "requestFocusParent0 - window: %p (END)\n", mWin);
+ DBG_PRINT( "resignFocus0 - window: %p (END)\n", mWin);
[pool release];
}
@@ -1247,8 +1264,12 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_resignFocus0
JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_orderFront0
(JNIEnv *env, jobject unused, jlong window)
{
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSWindow* mWin = (NSWindow*) ((intptr_t) window);
+ if( NULL == mWin ) {
+ DBG_PRINT( "orderFront0 - NULL NEWT win - abort\n");
+ return;
+ }
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSWindow* pWin = [mWin parentWindow];
DBG_PRINT( "orderFront0 - window: (parent %p) %p visible %d (START)\n", pWin, mWin, [mWin isVisible]);
@@ -1272,8 +1293,12 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_orderFront0
JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_orderOut0
(JNIEnv *env, jobject unused, jlong window)
{
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSWindow* mWin = (NSWindow*) ((intptr_t) window);
+ if( NULL == mWin ) {
+ DBG_PRINT( "orderOut0 - NULL NEWT win - abort\n");
+ return;
+ }
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSWindow* pWin = [mWin parentWindow];
DBG_PRINT( "orderOut0 - window: (parent %p) %p visible %d (START)\n", pWin, mWin, [mWin isVisible]);
@@ -1297,8 +1322,12 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_orderOut0
JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setTitle0
(JNIEnv *env, jobject unused, jlong window, jstring title)
{
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSWindow* win = (NSWindow*) ((intptr_t) window);
+ if( NULL == win ) {
+ DBG_PRINT( "setTitle0 - NULL NEWT win - abort\n");
+ return;
+ }
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
DBG_PRINT( "setTitle0 - window: %p (START)\n", win);
@@ -1374,88 +1403,64 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_changeContent
/*
* Class: jogamp_newt_driver_macosx_WindowDriver
- * Method: setWindowClientTopLeftPointAndSize0
- * Signature: (JIIIIZ)V
+ * Method: updateSizePosInsets0
+ * Signature: (JZ)V
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setWindowClientTopLeftPointAndSize0
- (JNIEnv *env, jobject unused, jlong window, jint x, jint y, jint w, jint h, jboolean display)
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_updateSizePosInsets0
+ (JNIEnv *env, jobject jthis, jlong window, jboolean defer)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NewtMacWindow* mWin = (NewtMacWindow*) ((intptr_t) window);
- DBG_PRINT( "setWindowClientTopLeftPointAndSize - window: %p (START)\n", mWin);
+ DBG_PRINT( "updateSizePosInsets - window: %p, defer %d (START)\n", mWin, (int)defer);
- setWindowClientTopLeftPointAndSize(mWin, x, y, w, h, display);
+ [mWin updateSizePosInsets: env jwin:jthis defer:defer];
- DBG_PRINT( "setWindowClientTopLeftPointAndSize - window: %p (END)\n", mWin);
+ DBG_PRINT( "updateSizePosInsets - window: %p, defer %d (END)\n", mWin, (int)defer);
[pool release];
}
/*
* Class: jogamp_newt_driver_macosx_WindowDriver
- * Method: setWindowClientTopLeftPoint0
- * Signature: (JIIZ)V
+ * Method: setWindowClientTopLeftPointAndSize0
+ * Signature: (JIIIIZ)V
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setWindowClientTopLeftPoint0
- (JNIEnv *env, jobject unused, jlong window, jint x, jint y, jboolean display)
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setWindowClientTopLeftPointAndSize0
+ (JNIEnv *env, jobject unused, jlong window, jint x, jint y, jint w, jint h, jboolean display)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NewtMacWindow* mWin = (NewtMacWindow*) ((intptr_t) window);
- DBG_PRINT( "setWindowClientTopLeftPoint - window: %p (START)\n", mWin);
+ DBG_PRINT( "setWindowClientTopLeftPointAndSize - window: %p (START)\n", mWin);
- setWindowClientTopLeftPoint(mWin, x, y, display);
+ setWindowClientTopLeftPointAndSize(mWin, x, y, w, h, display);
- DBG_PRINT( "setWindowClientTopLeftPoint - window: %p (END)\n", mWin);
+ DBG_PRINT( "setWindowClientTopLeftPointAndSize - window: %p (END)\n", mWin);
[pool release];
}
/*
* Class: jogamp_newt_driver_macosx_WindowDriver
- * Method: setAlwaysOnTop0
- * Signature: (JZ)V
+ * Method: setWindowClientTopLeftPoint0
+ * Signature: (JIIZ)V
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setAlwaysOnTop0
- (JNIEnv *env, jobject unused, jlong window, jboolean atop)
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setWindowClientTopLeftPoint0
+ (JNIEnv *env, jobject unused, jlong window, jint x, jint y, jboolean display)
{
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- NSWindow* win = (NSWindow*) ((intptr_t) window);
-
- DBG_PRINT( "setAlwaysOnTop0 - window: %p, atop %d (START)\n", win, (int)atop);
-
- if(atop) {
- [win setLevel:NSFloatingWindowLevel];
- } else {
- [win setLevel:NSNormalWindowLevel];
+ NewtMacWindow* mWin = (NewtMacWindow*) ((intptr_t) window);
+ if( NULL == mWin ) {
+ DBG_PRINT( "setWindowClientTopLeftPoint - NULL NEWT win - abort\n");
+ return;
}
-
- DBG_PRINT( "setAlwaysOnTop0 - window: %p, atop %d (END)\n", win, (int)atop);
-
- [pool release];
-}
-
-/*
- * Class: jogamp_newt_driver_macosx_WindowDriver
- * Method: setAlwaysOnBottom0
- * Signature: (JZ)V
- */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setAlwaysOnBottom0
- (JNIEnv *env, jobject unused, jlong window, jboolean abottom)
-{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- NSWindow* win = (NSWindow*) ((intptr_t) window);
- DBG_PRINT( "setAlwaysOnBottom0 - window: %p, abottom %d (START)\n", win, (int)abottom);
+ DBG_PRINT( "setWindowClientTopLeftPoint - window: %p (START)\n", mWin);
- if(abottom) {
- [win setLevel:NSScreenSaverWindowLevel]; // ??
- } else {
- [win setLevel:NSNormalWindowLevel];
- }
+ setWindowClientTopLeftPoint(mWin, x, y, display);
- DBG_PRINT( "setAlwaysOnBottom0 - window: %p, abottom %d (END)\n", win, (int)abottom);
+ DBG_PRINT( "setWindowClientTopLeftPoint - window: %p (END)\n", mWin);
[pool release];
}
@@ -1469,6 +1474,10 @@ JNIEXPORT jobject JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_getLocatio
(JNIEnv *env, jclass unused, jlong win, jint src_x, jint src_y)
{
NewtMacWindow *mWin = (NewtMacWindow*) (intptr_t) win;
+ if( NULL == mWin ) {
+ DBG_PRINT( "getLocationOnScreen0 - NULL NEWT win - abort\n");
+ return NULL;
+ }
if( ![mWin isKindOfClass:[NewtMacWindow class]] ) {
NewtCommon_throwNewRuntimeException(env, "Not a NewtMacWindow %p", mWin);
return NULL;
@@ -1480,12 +1489,16 @@ JNIEXPORT jobject JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_getLocatio
JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setPointerIcon0
(JNIEnv *env, jobject unused, jlong window, jlong handle)
{
+ NewtMacWindow *mWin = (NewtMacWindow*) (intptr_t) window;
+ if( NULL == mWin ) {
+ DBG_PRINT( "setPointerIcon0 - NULL NEWT win - abort\n");
+ return;
+ }
NSCursor *c = (NSCursor*) (intptr_t) handle ;
if ( NULL != c && NO == [c isKindOfClass:[NSCursor class]] ) {
NewtCommon_throwNewRuntimeException(env, "Not a NSCursor %p", c);
return;
}
- NewtMacWindow *mWin = (NewtMacWindow*) (intptr_t) window;
if( ! [mWin isKindOfClass:[NewtMacWindow class]] ) {
NewtCommon_throwNewRuntimeException(env, "Not a NewtMacWindow %p", mWin);
return;
@@ -1509,6 +1522,10 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setPointerVis
(JNIEnv *env, jclass clazz, jlong window, jboolean hasFocus, jboolean mouseVisible)
{
NewtMacWindow *mWin = (NewtMacWindow*) ((intptr_t) window);
+ if( NULL == mWin ) {
+ DBG_PRINT( "setPointerVisible0 - NULL NEWT win - abort\n");
+ return;
+ }
if( ! [mWin isKindOfClass:[NewtMacWindow class]] ) {
NewtCommon_throwNewRuntimeException(env, "Not a NewtMacWindow %p", mWin);
return;
@@ -1533,6 +1550,10 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_confinePointe
(JNIEnv *env, jclass clazz, jlong window, jboolean confine)
{
NewtMacWindow *mWin = (NewtMacWindow*) ((intptr_t) window);
+ if( NULL == mWin ) {
+ DBG_PRINT( "confinePointer0 - NULL NEWT win - abort\n");
+ return;
+ }
if( ! [mWin isKindOfClass:[NewtMacWindow class]] ) {
NewtCommon_throwNewRuntimeException(env, "Not a NewtMacWindow %p", mWin);
return;
@@ -1556,6 +1577,10 @@ 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);
+ if( NULL == mWin ) {
+ DBG_PRINT( "warpPointer0 - NULL NEWT win - abort\n");
+ return;
+ }
if( ! [mWin isKindOfClass:[NewtMacWindow class]] ) {
NewtCommon_throwNewRuntimeException(env, "Not a NewtMacWindow %p", mWin);
return;
diff --git a/src/newt/native/NewtMacWindow.h b/src/newt/native/NewtMacWindow.h
index 7dc5c6e19..14474bc10 100644
--- a/src/newt/native/NewtMacWindow.h
+++ b/src/newt/native/NewtMacWindow.h
@@ -142,6 +142,7 @@ CGDirectDisplayID NewtScreen_getCGDirectDisplayIDByNSScreen(NSScreen *screen);
#endif
{
BOOL realized;
+ jboolean withinLiveResize;
@public
BOOL hasPresentationSwitch;
NSUInteger defaultPresentationOptions;
@@ -164,7 +165,10 @@ CGDirectDisplayID NewtScreen_getCGDirectDisplayIDByNSScreen(NSScreen *screen);
- (void) setRealized: (BOOL)v;
- (BOOL) isRealized;
+- (void) setAlwaysOn: (BOOL)top bottom:(BOOL)bottom;
+
- (void) updateInsets: (JNIEnv*) env jwin: (jobject) javaWin;
+- (void) updateSizePosInsets: (JNIEnv*) env jwin: (jobject) javaWin defer: (jboolean)defer;
- (void) attachToParent: (NSWindow*) parent;
- (void) detachFromParent: (NSWindow*) parent;
@@ -189,7 +193,12 @@ CGDirectDisplayID NewtScreen_getCGDirectDisplayIDByNSScreen(NSScreen *screen);
- (void) windowDidBecomeKey: (NSNotification *) notification;
- (void) windowDidResignKey: (NSNotification *) notification;
+- (void) windowWillStartLiveResize: (NSNotification *) notification;
+- (void) windowDidEndLiveResize: (NSNotification *) notification;
+- (NSSize) windowWillResize: (NSWindow *)sender toSize:(NSSize)frameSize;
- (void) windowDidResize: (NSNotification*) notification;
+- (void) sendResizeEvent;
+
- (void) windowDidMove: (NSNotification*) notification;
- (BOOL) windowClosingImpl: (BOOL) force;
- (BOOL) windowShouldClose: (id) sender;
diff --git a/src/newt/native/NewtMacWindow.m b/src/newt/native/NewtMacWindow.m
index 7b3df391d..6024a90d4 100644
--- a/src/newt/native/NewtMacWindow.m
+++ b/src/newt/native/NewtMacWindow.m
@@ -54,7 +54,7 @@ static jfloat GetDelta(NSEvent *event, jint javaMods[]) {
deltaX = CGEventGetIntegerValueField(cgEvent, kCGScrollWheelEventPointDeltaAxis2);
deltaY = CGEventGetIntegerValueField(cgEvent, kCGScrollWheelEventPointDeltaAxis1);
// fprintf(stderr, "WHEEL/PAD: %lf/%lf - 0x%X\n", (double)deltaX, (double)deltaY, javaMods[0]);
- if( fabsf(deltaX) > fabsf(deltaY) ) {
+ if( fabs(deltaX) > fabs(deltaY) ) {
javaMods[0] |= EVENT_SHIFT_MASK;
delta = deltaX;
} else {
@@ -179,9 +179,10 @@ static jmethodID requestFocusID = NULL;
static jmethodID insetsChangedID = NULL;
static jmethodID sizeChangedID = NULL;
+static jmethodID sizeScreenPosInsetsChangedID = NULL;
static jmethodID updatePixelScaleID = NULL;
static jmethodID visibleChangedID = NULL;
-static jmethodID positionChangedID = NULL;
+static jmethodID screenPositionChangedID = NULL;
static jmethodID focusChangedID = NULL;
static jmethodID windowDestroyNotifyID = NULL;
static jmethodID windowRepaintID = NULL;
@@ -649,31 +650,32 @@ static jmethodID windowRepaintID = NULL;
// convert to 1-based button number (or use zero if no button is involved)
// TODO: detect mouse button when mouse wheel scrolled
- jshort javaButtonNum = 0;
+ jshort javaButtonNum;
jfloat scrollDeltaY = 0.0f;
switch ([event type]) {
- case NSScrollWheel: {
- scrollDeltaY = GetDelta(event, javaMods);
- javaButtonNum = 1;
- break;
- }
- case NSLeftMouseDown:
- case NSLeftMouseUp:
- case NSLeftMouseDragged:
- javaButtonNum = 1;
- break;
- case NSRightMouseDown:
- case NSRightMouseUp:
- case NSRightMouseDragged:
- javaButtonNum = 3;
- break;
- case NSOtherMouseDown:
- case NSOtherMouseUp:
- case NSOtherMouseDragged:
- javaButtonNum = 2;
- break;
+ case NSScrollWheel:
+ scrollDeltaY = GetDelta(event, javaMods);
+ javaButtonNum = 1;
+ break;
+ case NSLeftMouseDown:
+ case NSLeftMouseUp:
+ case NSLeftMouseDragged:
+ javaButtonNum = 1;
+ break;
+ case NSRightMouseDown:
+ case NSRightMouseUp:
+ case NSRightMouseDragged:
+ javaButtonNum = 3;
+ break;
+ case NSOtherMouseDown:
+ case NSOtherMouseUp:
+ case NSOtherMouseDragged:
+ javaButtonNum = 2;
+ break;
+ default:
+ javaButtonNum = 0;
+ break;
}
-
if (evType == EVENT_MOUSE_WHEEL_MOVED && scrollDeltaY == 0) {
// ignore 0 increment wheel scroll events
return;
@@ -830,13 +832,15 @@ NS_ENDHANDLER
updatePixelScaleID = (*env)->GetMethodID(env, clazz, "updatePixelScale", "(ZFF)V");
visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(ZZ)V");
insetsChangedID = (*env)->GetMethodID(env, clazz, "insetsChanged", "(ZIIII)V");
- positionChangedID = (*env)->GetMethodID(env, clazz, "screenPositionChanged", "(ZII)V");
+ sizeScreenPosInsetsChangedID = (*env)->GetMethodID(env, clazz, "sizeScreenPosInsetsChanged", "(ZIIIIIIIIZZ)V");
+ screenPositionChangedID = (*env)->GetMethodID(env, clazz, "screenPositionChanged", "(ZII)V");
focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(ZZ)V");
windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "(Z)Z");
windowRepaintID = (*env)->GetMethodID(env, clazz, "windowRepaint", "(ZIIII)V");
requestFocusID = (*env)->GetMethodID(env, clazz, "requestFocus", "(Z)V");
- if (enqueueMouseEventID && enqueueKeyEventID && sizeChangedID && updatePixelScaleID && visibleChangedID && insetsChangedID &&
- positionChangedID && focusChangedID && windowDestroyNotifyID && requestFocusID && windowRepaintID)
+ if (enqueueMouseEventID && enqueueKeyEventID && sizeChangedID && updatePixelScaleID && visibleChangedID &&
+ insetsChangedID && sizeScreenPosInsetsChangedID &&
+ screenPositionChangedID && focusChangedID && windowDestroyNotifyID && requestFocusID && windowRepaintID)
{
CKCH_CreateDictionaries();
return YES;
@@ -889,6 +893,7 @@ NS_ENDHANDLER
cachedInsets[3] = 0; // b
realized = YES;
+ withinLiveResize = JNI_FALSE;
DBG_PRINT("NewtWindow::create: %p, realized %d, hasPresentationSwitch %d[defaultOptions 0x%X, fullscreenOptions 0x%X], (refcnt %d)\n",
res, realized, (int)hasPresentationSwitch, (int)defaultPresentationOptions, (int)fullscreenPresentationOptions, (int)[res retainCount]);
return res;
@@ -928,6 +933,20 @@ NS_ENDHANDLER
return realized;
}
+- (void) setAlwaysOn: (BOOL)top bottom:(BOOL)bottom
+{
+ if( top ) {
+ DBG_PRINT( "*************** setAlwaysOn -> top\n");
+ [self setLevel: kCGMaximumWindowLevel];
+ } else if ( bottom ) {
+ DBG_PRINT( "*************** setAlwaysOn -> bottom\n");
+ [self setLevel: kCGDesktopIconWindowLevel]; // w/ input
+ } else {
+ DBG_PRINT( "*************** setAlwaysOn -> normal\n");
+ [self setLevel:NSNormalWindowLevel];
+ }
+}
+
- (void) updateInsets: (JNIEnv*) env jwin: (jobject) javaWin
{
NSRect frameRect = [self frame];
@@ -948,6 +967,33 @@ NS_ENDHANDLER
}
}
+- (void) updateSizePosInsets: (JNIEnv*) env jwin: (jobject) javaWin defer: (jboolean)defer
+{
+ // update insets on every window resize for lack of better hook place
+ [self updateInsets: NULL jwin:NULL];
+
+ NSRect frameRect = [self frame];
+ NSRect contentRect = [self contentRectForFrameRect: frameRect];
+
+ DBG_PRINT( "updateSize: [ w %d, h %d ], liveResize %d\n", (jint) contentRect.size.width, (jint) contentRect.size.height, (jint)withinLiveResize);
+
+ NSPoint p0 = { 0, 0 };
+ p0 = [self getLocationOnScreen: p0];
+
+ DBG_PRINT( "updatePos: [ x %d, y %d ]\n", (jint) p0.x, (jint) p0.y);
+
+ if( NULL != env && NULL != javaWin ) {
+ (*env)->CallVoidMethod(env, javaWin, sizeScreenPosInsetsChangedID, defer,
+ (jint) p0.x, (jint) p0.y,
+ (jint) contentRect.size.width, (jint) contentRect.size.height,
+ cachedInsets[0], cachedInsets[1], cachedInsets[2], cachedInsets[3],
+ JNI_FALSE, // force
+ withinLiveResize
+ );
+ }
+}
+
+
- (void) attachToParent: (NSWindow*) parent
{
DBG_PRINT( "attachToParent.1\n");
@@ -1183,8 +1229,30 @@ NS_ENDHANDLER
[self focusChanged: NO];
}
+- (void) windowWillStartLiveResize: (NSNotification *) notification
+{
+ DBG_PRINT( "*************** windowWillStartLiveResize\n");
+ withinLiveResize = JNI_TRUE;
+}
+- (void) windowDidEndLiveResize: (NSNotification *) notification
+{
+ DBG_PRINT( "*************** windowDidEndLiveResize\n");
+ withinLiveResize = JNI_FALSE;
+ [self sendResizeEvent];
+}
+- (NSSize) windowWillResize: (NSWindow *)sender toSize:(NSSize)frameSize
+{
+ DBG_PRINT( "*************** windowWillResize %lfx%lf\n", frameSize.width, frameSize.height);
+ return frameSize;
+}
- (void)windowDidResize: (NSNotification*) notification
{
+ DBG_PRINT( "*************** windowDidResize\n");
+ [self sendResizeEvent];
+}
+
+- (void) sendResizeEvent
+{
jobject javaWindowObject = NULL;
int shallBeDetached = 0;
JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached);
@@ -1198,15 +1266,7 @@ NS_ENDHANDLER
javaWindowObject = [newtView getJavaWindowObject];
}
if( NULL != javaWindowObject ) {
- // update insets on every window resize for lack of better hook place
- [self updateInsets: env jwin:javaWindowObject];
-
- NSRect frameRect = [self frame];
- NSRect contentRect = [self contentRectForFrameRect: frameRect];
-
- (*env)->CallVoidMethod(env, javaWindowObject, sizeChangedID, JNI_TRUE, // defer
- (jint) contentRect.size.width,
- (jint) contentRect.size.height, JNI_FALSE);
+ [self updateSizePosInsets: env jwin: javaWindowObject defer:JNI_TRUE];
}
// detaching thread not required - daemon
// NewtCommon_ReleaseJNIEnv(shallBeDetached);
@@ -1232,7 +1292,8 @@ NS_ENDHANDLER
NSPoint p0 = { 0, 0 };
p0 = [self getLocationOnScreen: p0];
- (*env)->CallVoidMethod(env, javaWindowObject, positionChangedID, JNI_FALSE, (jint) p0.x, (jint) p0.y);
+ DBG_PRINT( "windowDidMove: [ x %d, y %d ]\n", (jint) p0.x, (jint) p0.y);
+ (*env)->CallVoidMethod(env, javaWindowObject, screenPositionChangedID, JNI_TRUE, (jint) p0.x, (jint) p0.y);
// detaching thread not required - daemon
// NewtCommon_ReleaseJNIEnv(shallBeDetached);
diff --git a/src/newt/native/Window.h b/src/newt/native/Window.h
index ada886d24..f6aba4c83 100644
--- a/src/newt/native/Window.h
+++ b/src/newt/native/Window.h
@@ -53,7 +53,9 @@
#define FLAG_IS_MAXIMIZED_VERT ( 1 << 9 )
#define FLAG_IS_MAXIMIZED_HORZ ( 1 << 10 )
#define FLAG_IS_FULLSCREEN ( 1 << 11 )
-#define FLAG_IS_FULLSCREEN_SPAN ( 1 << 12 )
+#define FLAG_IS_POINTERVISIBLE ( 1 << 12 )
+#define FLAG_IS_POINTERCONFINED ( 1 << 13 )
+#define FLAG_IS_FULLSCREEN_SPAN ( 1 << 14 )
#define TST_FLAG_CHANGE_VISIBILITY(f) ( 0 != ( (f) & FLAG_CHANGE_VISIBILITY ) )
#define TST_FLAG_CHANGE_VISIBILITY_FAST(f) ( 0 != ( (f) & FLAG_CHANGE_VISIBILITY_FAST ) )
diff --git a/src/newt/native/WindowsEDID.c b/src/newt/native/WindowsEDID.c
index d84773dc6..5fc410a91 100644
--- a/src/newt/native/WindowsEDID.c
+++ b/src/newt/native/WindowsEDID.c
@@ -144,8 +144,14 @@ static _TCHAR* Get2ndSlashBlock(const _TCHAR* sIn, _TCHAR* sOut, size_t sOutLen)
size_t len = t - s;
if( len > 0 ) {
if( sOutLen >= len ) {
- _tcsncpy_s(sOut, sOutLen, s, len);
- return sOut;
+ // Bug 1196: Unresolved strncpy_s (MSVCRT) on WinXP.
+ // Mapped: _tcsncpy_s -> strncpy_s (!UNICODE).
+ // On WinXP MSVCRT has no strncpy_s.
+ // _tcsncpy_s(sOut, sOutLen, s, len);
+ if( len <= sOutLen-1 ) {
+ _tcsncpy(sOut, s, len);
+ return sOut;
+ }
}
}
}
diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c
index ad4111ec7..59e054516 100644
--- a/src/newt/native/WindowsWindow.c
+++ b/src/newt/native/WindowsWindow.c
@@ -177,9 +177,11 @@
static jmethodID insetsChangedID = NULL;
static jmethodID sizeChangedID = NULL;
+static jmethodID maximizedChangedID = NULL;
static jmethodID positionChangedID = NULL;
static jmethodID focusChangedID = NULL;
static jmethodID visibleChangedID = NULL;
+static jmethodID sizePosInsetsFocusVisibleChangedID = NULL;
static jmethodID windowDestroyNotifyID = NULL;
static jmethodID windowRepaintID = NULL;
static jmethodID sendMouseEventID = NULL;
@@ -202,15 +204,23 @@ static UnregisterTouchWindowPROCADDR WinTouch_UnregisterTouchWindow = NULL;
static int NewtEDID_avail = 0;
-static RECT* UpdateInsets(JNIEnv *env, jobject window, HWND hwnd);
-
typedef struct {
JNIEnv* jenv;
jobject jinstance;
+ /* client x-pos */
+ int xpos;
+ /* client y-pos */
+ int ypos;
/* client size width */
int width;
/* client size height */
int height;
+ /* visible state */
+ BOOL visible;
+ /* focused state */
+ BOOL focused;
+ /* Insets left, right, top, bottom */
+ RECT insets;
/** Tristate: -1 HIDE, 0 NOP, 1 SHOW */
int setPointerVisible;
/** Tristate: -1 RESET, 0 NOP, 1 SET-NEW */
@@ -218,9 +228,17 @@ typedef struct {
HCURSOR setPointerHandle;
HCURSOR defPointerHandle;
/** Bool: 0 NOP, 1 FULLSCREEN */
- int isFullscreen;
+ BOOL isFullscreen;
/** Bool: 0 TOP, 1 CHILD */
- int isChildWindow;
+ BOOL isChildWindow;
+ /** Bool: 0 NOP, 1 minimized/iconic */
+ BOOL isMinimized;
+ /** Bool: 0 NOP, 1 maximized */
+ BOOL isMaximized;
+ BOOL isOnBottom;
+ BOOL isOnTop;
+ /** Bug 1205: Clear Window Background -> security! */
+ BOOL isInCreation;
int pointerCaptured;
int pointerInside;
int touchDownCount;
@@ -228,6 +246,8 @@ typedef struct {
int supportsMTouch;
} WindowUserData;
+static void UpdateInsets(JNIEnv *env, WindowUserData *wud, HWND hwnd);
+
typedef struct {
USHORT javaKey;
USHORT windowsKey;
@@ -601,21 +621,41 @@ static int WmKeyUp(JNIEnv *env, jobject window, USHORT wkey, WORD repCnt, BYTE s
static void NewtWindows_requestFocus (JNIEnv *env, jobject window, HWND hwnd, jboolean force) {
HWND pHwnd, current;
+ WindowUserData * wud;
BOOL isEnabled = IsWindowEnabled(hwnd);
pHwnd = GetParent(hwnd);
current = GetFocus();
- 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 !defined(__MINGW64__) && ( defined(UNDER_CE) || _MSC_VER <= 1200 )
+ wud = (WindowUserData *) GetWindowLong(hwnd, GWL_USERDATA);
+#else
+ wud = (WindowUserData *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
+#endif
+
+ DBG_PRINT("*** WindowsWindow: requestFocus.S force %d, parent %p, window %p, isEnabled %d, isCurrent %d, isOn[Top %d, Bottom %d]\n",
+ (int)force, (void*)pHwnd, (void*)hwnd, isEnabled, current==hwnd,
+ wud->isOnTop, wud->isOnBottom);
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
+ BOOL frontWindow;
+ if( wud->isOnBottom ) {
+ SetWindowPos(hwnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
+ frontWindow = FALSE;
+ } else if( wud->isOnTop ) {
+ SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, flags);
+ frontWindow = TRUE;
+ } else {
+ SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, flags);
+ frontWindow = TRUE;
+ }
+ if( frontWindow ) {
+ SetForegroundWindow(hwnd); // Slightly Higher Priority
+ }
SetFocus(hwnd);// Sets Keyboard Focus To Window (activates parent window if exist, or this window)
- if(NULL!=pHwnd) {
+ if( frontWindow && NULL!=pHwnd ) {
SetActiveWindow(hwnd);
}
current = GetFocus();
@@ -660,91 +700,34 @@ static jboolean NewtWindows_setFullScreen(jboolean fullscreen)
return ( DISP_CHANGE_SUCCESSFUL == ChangeDisplaySettings(&dm, flags) ) ? JNI_TRUE : JNI_FALSE;
}
-#if 0
-
-static RECT* UpdateInsets(JNIEnv *env, jobject window, HWND hwnd)
-{
- // being naughty here
- static RECT m_insets = { 0, 0, 0, 0 };
- RECT outside;
- RECT inside;
- POINT *rp_inside = (POINT *) (void *) &inside;
- int dx, dy, dw, dh;
-
- if (IsIconic(hwnd)) {
- m_insets.left = m_insets.top = m_insets.right = m_insets.bottom = -1;
- return FALSE;
- }
-
- m_insets.left = m_insets.top = m_insets.right = m_insets.bottom = 0;
-
- GetClientRect(hwnd, &inside);
- GetWindowRect(hwnd, &outside);
-
- DBG_PRINT("*** WindowsWindow: UpdateInsets (a1) window %p, Inside CC: %d/%d - %d/%d %dx%d\n",
- (void*)hwnd,
- (int)inside.left, (int)inside.top, (int)inside.right, (int)inside.bottom,
- (int)(inside.right - inside.left), (int)(inside.bottom - inside.top));
- DBG_PRINT("*** WindowsWindow: UpdateInsets (a1) window %p, Outside SC: %d/%d - %d/%d %dx%d\n",
- (void*)hwnd,
- (int)outside.left, (int)outside.top, (int)outside.right, (int)outside.bottom,
- (int)(outside.right - outside.left), (int)(outside.bottom - outside.top));
-
- // xform client -> screen coord
- ClientToScreen(hwnd, rp_inside);
- ClientToScreen(hwnd, rp_inside+1);
-
- DBG_PRINT("*** WindowsWindow: UpdateInsets (a2) window %p, Inside SC: %d/%d - %d/%d %dx%d\n",
- (void*)hwnd,
- (int)inside.left, (int)inside.top, (int)inside.right, (int)inside.bottom,
- (int)(inside.right - inside.left), (int)(inside.bottom - inside.top));
-
- m_insets.top = inside.top - outside.top;
- m_insets.bottom = outside.bottom - inside.bottom;
- m_insets.left = inside.left - outside.left;
- m_insets.right = outside.right - inside.right;
-
- DBG_PRINT("*** WindowsWindow: UpdateInsets (1.0) window %p, %d/%d - %d/%d %dx%d\n",
- (void*)hwnd,
- (int)m_insets.left, (int)m_insets.top, (int)m_insets.right, (int)m_insets.bottom,
- (int)(m_insets.right-m_insets.left), (int)(m_insets.top-m_insets.bottom));
-
- (*env)->CallVoidMethod(env, window, insetsChangedID, JNI_FALSE,
- m_insets.left, m_insets.right,
- m_insets.top, m_insets.bottom);
- return &m_insets;
-}
-
-#else
-
-static RECT* UpdateInsets(JNIEnv *env, jobject window, HWND hwnd)
-{
- // being naughty here
- static RECT m_insets = { 0, 0, 0, 0 };
+static void UpdateInsets(JNIEnv *env, WindowUserData *wud, HWND hwnd) {
+ jobject window = wud->jinstance;
RECT outside;
RECT inside;
+ int strategy = 0;
if (IsIconic(hwnd)) {
- m_insets.left = m_insets.top = m_insets.right = m_insets.bottom = -1;
- return FALSE;
+ wud->insets.left = wud->insets.top = wud->insets.right = wud->insets.bottom = -1;
+ return;
}
- m_insets.left = m_insets.top = m_insets.right = m_insets.bottom = 0;
+ wud->insets.left = wud->insets.top = wud->insets.right = wud->insets.bottom = 0;
GetClientRect(hwnd, &inside);
GetWindowRect(hwnd, &outside);
if (outside.right - outside.left > 0 && outside.bottom - outside.top > 0) {
MapWindowPoints(hwnd, 0, (LPPOINT)&inside, 2);
- m_insets.top = inside.top - outside.top;
- m_insets.bottom = outside.bottom - inside.bottom;
- m_insets.left = inside.left - outside.left;
- m_insets.right = outside.right - inside.right;
+ wud->insets.top = inside.top - outside.top;
+ wud->insets.bottom = outside.bottom - inside.bottom;
+ wud->insets.left = inside.left - outside.left;
+ wud->insets.right = outside.right - inside.right;
+ strategy = 1;
} else {
- m_insets.top = -1;
+ wud->insets.top = -1;
}
- if (m_insets.left < 0 || m_insets.top < 0 ||
- m_insets.right < 0 || m_insets.bottom < 0)
+ if (wud->insets.left < 0 || wud->insets.top < 0 ||
+ wud->insets.right < 0 || wud->insets.bottom < 0)
{
LONG style = GetWindowLong(hwnd, GWL_STYLE);
@@ -752,49 +735,65 @@ static RECT* UpdateInsets(JNIEnv *env, jobject window, HWND hwnd)
if (!bIsUndecorated) {
/* Get outer frame sizes. */
if (style & WS_THICKFRAME) {
- m_insets.left = m_insets.right =
+ wud->insets.left = wud->insets.right =
GetSystemMetrics(SM_CXSIZEFRAME);
- m_insets.top = m_insets.bottom =
+ wud->insets.top = wud->insets.bottom =
GetSystemMetrics(SM_CYSIZEFRAME);
} else {
- m_insets.left = m_insets.right =
+ wud->insets.left = wud->insets.right =
GetSystemMetrics(SM_CXDLGFRAME);
- m_insets.top = m_insets.bottom =
+ wud->insets.top = wud->insets.bottom =
GetSystemMetrics(SM_CYDLGFRAME);
}
/* Add in title. */
- m_insets.top += GetSystemMetrics(SM_CYCAPTION);
+ wud->insets.top += GetSystemMetrics(SM_CYCAPTION);
+ strategy += 10;
} else {
/* undo the -1 set above */
- m_insets.left = m_insets.top = m_insets.right = m_insets.bottom = 0;
+ wud->insets.left = wud->insets.top = wud->insets.right = wud->insets.bottom = 0;
+ strategy += 20;
}
}
- DBG_PRINT("*** WindowsWindow: UpdateInsets window %p, [l %d, r %d - t %d, b %d - %dx%d]\n",
- (void*)hwnd, (int)m_insets.left, (int)m_insets.right, (int)m_insets.top, (int)m_insets.bottom,
- (int) ( m_insets.left + m_insets.right ), (int) (m_insets.top + m_insets.bottom));
-
- (*env)->CallVoidMethod(env, window, insetsChangedID, JNI_FALSE,
- (int)m_insets.left, (int)m_insets.right, (int)m_insets.top, (int)m_insets.bottom);
- return &m_insets;
+ DBG_PRINT("*** WindowsWindow: UpdateInsets window %p, s %d, [l %d, r %d - t %d, b %d - %dx%d], at-init %d\n",
+ (void*)hwnd, strategy, (int)wud->insets.left, (int)wud->insets.right, (int)wud->insets.top, (int)wud->insets.bottom,
+ (int) ( wud->insets.left + wud->insets.right ), (int) (wud->insets.top + wud->insets.bottom), wud->isInCreation);
+ if( !wud->isInCreation ) {
+ (*env)->CallVoidMethod(env, window, insetsChangedID, JNI_FALSE,
+ (int)wud->insets.left, (int)wud->insets.right, (int)wud->insets.top, (int)wud->insets.bottom);
+ }
}
-#endif
-
static void WmSize(JNIEnv *env, WindowUserData * wud, HWND wnd, UINT type)
{
RECT rc;
BOOL isVisible = IsWindowVisible(wnd);
jobject window = wud->jinstance;
+ BOOL maxChanged = FALSE;
+
+ DBG_PRINT("*** WindowsWindow: WmSize.0 window %p, %dx%d, isMinimized %d, isMaximized %d, visible %d\n",
+ (void*)wnd, wud->width, wud->height, wud->isMinimized, wud->isMaximized, isVisible);
if (type == SIZE_MINIMIZED) {
- // TODO: deal with minimized window sizing
+ wud->isMinimized = TRUE;
return;
}
+ if (type == SIZE_MAXIMIZED) {
+ if( !wud->isMaximized ) {
+ wud->isMaximized = 1;
+ maxChanged = TRUE;
+ }
+ } else if (type == SIZE_RESTORED) {
+ wud->isMinimized = FALSE;
+ if( wud->isMaximized ) {
+ wud->isMaximized = FALSE;
+ maxChanged = TRUE;
+ }
+ }
// make sure insets are up to date
- (void)UpdateInsets(env, window, wnd);
+ UpdateInsets(env, wud, wnd);
GetClientRect(wnd, &rc);
@@ -802,9 +801,16 @@ static void WmSize(JNIEnv *env, WindowUserData * wud, HWND wnd, UINT type)
wud->width = (int) ( rc.right - rc.left );
wud->height = (int) ( rc.bottom - rc.top );
- DBG_PRINT("*** WindowsWindow: WmSize window %p, %dx%d, visible %d\n", (void*)wnd, wud->width, wud->height, isVisible);
+ DBG_PRINT("*** WindowsWindow: WmSize.X window %p, %dx%d, isMinimized %d, isMaximized %d (changed %d), visible %d, at-init %d\n",
+ (void*)wnd, wud->width, wud->height, wud->isMinimized, wud->isMaximized, maxChanged, isVisible, wud->isInCreation);
- (*env)->CallVoidMethod(env, window, sizeChangedID, JNI_FALSE, wud->width, wud->height, JNI_FALSE);
+ if( !wud->isInCreation ) {
+ if( maxChanged ) {
+ jboolean v = wud->isMaximized ? JNI_TRUE : JNI_FALSE;
+ (*env)->CallVoidMethod(env, window, maximizedChangedID, v, v);
+ }
+ (*env)->CallVoidMethod(env, window, sizeChangedID, JNI_FALSE, wud->width, wud->height, JNI_FALSE);
+ }
}
#ifdef TEST_MOUSE_HOOKS
@@ -930,6 +936,7 @@ static void sendTouchScreenEvent(JNIEnv *env, jobject window,
jNames, jX, jY, jPressure, (jfloat)maxPressure);
}
+// #define DO_ERASEBKGND 1
static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lParam) {
LRESULT res = 0;
@@ -993,11 +1000,15 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
// Bug 916 - NEWT Fullscreen Mode on Windows ALT-TAB doesn't allow Application Switching
// Remedy for 'some' display drivers, i.e. Intel HD:
// Explicitly push fullscreen window to BOTTOM when inactive (ALT-TAB)
- UINT flags = SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
- if( inactive ) {
- SetWindowPos(wnd, HWND_BOTTOM, 0, 0, 0, 0, flags);
+ if( inactive || wud->isOnBottom ) {
+ SetWindowPos(wnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
} else {
- SetWindowPos(wnd, HWND_TOP, 0, 0, 0, 0, flags);
+ UINT flags = SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
+ if( wud->isOnTop ) {
+ SetWindowPos(wnd, HWND_TOPMOST, 0, 0, 0, 0, flags);
+ } else {
+ SetWindowPos(wnd, HWND_TOP, 0, 0, 0, 0, flags);
+ }
SetForegroundWindow(wnd); // Slightly Higher Priority
}
}
@@ -1005,11 +1016,39 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
}
break;
+ case WM_WINDOWPOSCHANGING: {
+ WINDOWPOS *p = (WINDOWPOS*)lParam;
+ BOOL isThis = wnd == p->hwnd;
+ BOOL isBottom = HWND_BOTTOM == p->hwndInsertAfter;
+ BOOL isTopMost = HWND_TOPMOST == p->hwndInsertAfter;
+ BOOL forceBottom = isThis && wud->isOnBottom && !isBottom;
+ BOOL forceTop = isThis && wud->isOnTop && !isTopMost;
+ #ifdef VERBOSE_ON
+ BOOL isNoTopMost = HWND_NOTOPMOST == p->hwndInsertAfter;
+ BOOL isTop = HWND_TOP == p->hwndInsertAfter;
+ BOOL isNoZ = 0 != ( SWP_NOZORDER & p->flags );
+ DBG_PRINT("*** WindowsWindow: WM_WINDOWPOSCHANGING window %p / %p (= %d), %p[bottom %d, notop %d, top %d, topmost %d, noZ %d, force[Top %d, Bottom %d], %d/%d %dx%d 0x%X\n",
+ wnd, p->hwnd, isThis,
+ p->hwndInsertAfter, isBottom, isNoTopMost, isTop, isTopMost, isNoZ,
+ forceTop, forceBottom,
+ p->x, p->y, p->cx, p->cy, p->flags);
+ #endif
+ if( forceTop ) {
+ p->hwndInsertAfter = HWND_TOPMOST;
+ p->flags &= ~SWP_NOZORDER;
+ } else if( forceBottom ) {
+ p->hwndInsertAfter = HWND_BOTTOM;
+ p->flags &= ~SWP_NOZORDER;
+ }
+ useDefWindowProc = 1;
+ }
+ break;
+
case WM_SETTINGCHANGE:
if (wParam == SPI_SETNONCLIENTMETRICS) {
// make sure insets are updated, we don't need to resize the window
// because the size of the client area doesn't change
- (void)UpdateInsets(env, window, wnd);
+ UpdateInsets(env, wud, wnd);
} else {
useDefWindowProc = 1;
}
@@ -1020,32 +1059,79 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
break;
case WM_SHOWWINDOW:
- (*env)->CallVoidMethod(env, window, visibleChangedID, JNI_FALSE, wParam==TRUE?JNI_TRUE:JNI_FALSE);
+ DBG_PRINT("*** WindowsWindow: WM_SHOWWINDOW window %p: %d, at-init %d\n", wnd, wParam==TRUE, wud->isInCreation);
+ wud->visible = wParam==TRUE;
+ if( !wud->isInCreation ) {
+ (*env)->CallVoidMethod(env, window, visibleChangedID, JNI_FALSE, wParam==TRUE?JNI_TRUE:JNI_FALSE);
+ }
break;
case WM_MOVE:
- DBG_PRINT("*** WindowsWindow: WM_MOVE window %p, %d/%d\n", wnd, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
- (*env)->CallVoidMethod(env, window, positionChangedID, JNI_FALSE, (jint)GET_X_LPARAM(lParam), (jint)GET_Y_LPARAM(lParam));
+ wud->xpos = (int)GET_X_LPARAM(lParam);
+ wud->ypos = (int)GET_Y_LPARAM(lParam);
+ DBG_PRINT("*** WindowsWindow: WM_MOVE window %p, %d/%d, at-init %d\n", wnd, wud->xpos, wud->ypos, wud->isInCreation);
+ if( !wud->isInCreation ) {
+ (*env)->CallVoidMethod(env, window, positionChangedID, JNI_FALSE, (jint)wud->xpos, (jint)wud->ypos);
+ }
useDefWindowProc = 1;
break;
case WM_PAINT: {
- RECT r;
- if (GetUpdateRect(wnd, &r, FALSE /* do not erase background */)) {
- // clear the whole client area and issue repaint for it, w/o looping through erase background
- ValidateRect(wnd, NULL); // clear all!
- (*env)->CallVoidMethod(env, window, windowRepaintID, JNI_FALSE, 0, 0, -1, -1);
+ if( wud->isInCreation ) {
+ #ifdef DO_ERASEBKGND
+ if (GetUpdateRect(wnd, NULL, TRUE /* erase background */)) {
+ DBG_PRINT("*** WindowsWindow: WM_PAINT.0 (dirty)\n");
+ // WM_ERASEBKGND sent!
+ #else
+ if (GetUpdateRect(wnd, NULL, FALSE /* do not erase background */)) {
+ DBG_PRINT("*** WindowsWindow: WM_PAINT.0 (dirty)\n");
+ ValidateRect(wnd, NULL); // clear all!
+ #endif
+ } else {
+ DBG_PRINT("*** WindowsWindow: WM_PAINT.0 (clean)\n");
+ }
} else {
- // shall not happen ?
- ValidateRect(wnd, NULL); // clear all!
+ if (GetUpdateRect(wnd, NULL, FALSE /* do not erase background */)) {
+ DBG_PRINT("*** WindowsWindow: WM_PAINT.1 (dirty)\n");
+ // Let NEWT render the whole client area by issueing repaint for it, w/o looping through erase background
+ ValidateRect(wnd, NULL); // clear all!
+ (*env)->CallVoidMethod(env, window, windowRepaintID, JNI_FALSE, 0, 0, -1, -1);
+ } else {
+ DBG_PRINT("*** WindowsWindow: WM_PAINT.1 (clean)\n");
+ // shall not happen ?
+ ValidateRect(wnd, NULL); // clear all!
+ }
+ // return 0 == done
}
- // return 0 == done
break;
}
case WM_ERASEBKGND:
- // ignore erase background
- (*env)->CallVoidMethod(env, window, windowRepaintID, JNI_FALSE, 0, 0, -1, -1);
- res = 1; // return 1 == done, OpenGL, etc .. erases the background, hence we claim to have just done this
+ if( wud->isInCreation ) {
+ #ifdef DO_ERASEBKGND
+ // On Windows the initial window is clean?!
+ // This fill destroys translucency on Windows 10
+ // (which only seem to work on undecorated windows)
+ PAINTSTRUCT ps;
+ HDC hdc;
+ hdc = BeginPaint(wnd, &ps);
+ DBG_PRINT("*** WindowsWindow: WM_ERASEBKGND.0 (erasure) l/b %d/%d r/t %d/%d\n",
+ ps.rcPaint.left, ps.rcPaint.bottom, ps.rcPaint.right, ps.rcPaint.top);
+ // FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW+1));
+ // FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_APPWORKSPACE+1));
+ // A black color also sets alpha to zero for translucency!
+ FillRect(hdc, &ps.rcPaint, (HBRUSH)GetStockObject(BLACK_PEN));
+ EndPaint(wnd, &ps);
+ #else
+ ValidateRect(wnd, NULL); // clear all!
+ #endif
+ res = 1; // return 1 == done
+ } else {
+ // ignore erase background, but let NEWT render the whole client area
+ DBG_PRINT("*** WindowsWindow: WM_ERASEBKGND.1 (repaint)\n");
+ ValidateRect(wnd, NULL); // clear all!
+ (*env)->CallVoidMethod(env, window, windowRepaintID, JNI_FALSE, 0, 0, -1, -1);
+ res = 1; // return 1 == done, OpenGL, etc .. erases the background, hence we claim to have just done this
+ }
break;
case WM_SETCURSOR :
@@ -1094,8 +1180,11 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
break;
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);
+ DBG_PRINT("*** WindowsWindow: WM_SETFOCUS window %p, lost %p, at-init %d\n", wnd, (HWND)wParam, wud->isInCreation);
+ wud->focused = TRUE;
+ if( !wud->isInCreation ) {
+ (*env)->CallVoidMethod(env, window, focusChangedID, JNI_FALSE, JNI_TRUE);
+ }
useDefWindowProc = 1;
break;
@@ -1108,7 +1197,10 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
wud->pointerCaptured = 0;
ReleaseCapture();
}
- (*env)->CallVoidMethod(env, window, focusChangedID, JNI_FALSE, JNI_FALSE);
+ wud->focused = FALSE;
+ if( !wud->isInCreation ) {
+ (*env)->CallVoidMethod(env, window, focusChangedID, JNI_FALSE, JNI_FALSE);
+ }
useDefWindowProc = 1;
} else {
// quick focus .. we had it already, are enabled ..
@@ -2032,9 +2124,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowDriver_initIDs0
insetsChangedID = (*env)->GetMethodID(env, clazz, "insetsChanged", "(ZIIII)V");
sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(ZIIZ)V");
+ maximizedChangedID = (*env)->GetMethodID(env, clazz, "maximizedChanged", "(ZZ)V");
positionChangedID = (*env)->GetMethodID(env, clazz, "positionChanged", "(ZII)V");
focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(ZZ)V");
visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(ZZ)V");
+ sizePosInsetsFocusVisibleChangedID = (*env)->GetMethodID(env, clazz, "sizePosInsetsFocusVisibleChanged", "(ZIIIIIIIIIIZ)V");
windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "(Z)Z");
windowRepaintID = (*env)->GetMethodID(env, clazz, "windowRepaint", "(ZIIII)V");
sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(SIIISF)V");
@@ -2044,9 +2138,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowDriver_initIDs0
if (insetsChangedID == NULL ||
sizeChangedID == NULL ||
+ maximizedChangedID == NULL ||
positionChangedID == NULL ||
focusChangedID == NULL ||
visibleChangedID == NULL ||
+ sizePosInsetsFocusVisibleChangedID == NULL ||
windowDestroyNotifyID == NULL ||
windowRepaintID == NULL ||
sendMouseEventID == NULL ||
@@ -2088,32 +2184,61 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowDriver_getNewtWndP
return (jlong) (intptr_t) wndProc;
}
-static void NewtWindow_setVisiblePosSize(HWND hwnd, BOOL atop, BOOL visible,
+static void NewtWindow_setVisiblePosSize(WindowUserData *wud, HWND hwnd, int jflags, BOOL visible,
int x, int y, int width, int height)
{
- UINT flags;
- BOOL bRes;
-
- DBG_PRINT("*** WindowsWindow: NewtWindow_setVisiblePosSize %d/%d %dx%d, atop %d, visible %d\n",
- x, y, width, height, atop, visible);
+ BOOL atop = TST_FLAG_IS_ALWAYSONTOP(jflags);
+ BOOL abottom = TST_FLAG_IS_ALWAYSONBOTTOM(jflags);
+ UINT wflags;
+
+ DBG_PRINT("*** WindowsWindow: NewtWindow_setVisiblePosSize client %d/%d %dx%d, atop %d, abottom %d, max[change[%d %d], is[%d %d]], visible %d\n",
+ x, y, width, height, atop, abottom,
+ TST_FLAG_CHANGE_MAXIMIZED_VERT(jflags), TST_FLAG_CHANGE_MAXIMIZED_HORZ(jflags),
+ TST_FLAG_IS_MAXIMIZED_VERT(jflags), TST_FLAG_IS_MAXIMIZED_HORZ(jflags),
+ visible);
+
+ x -= wud->insets.left; // top-level
+ y -= wud->insets.top; // top-level
+ width += wud->insets.left + wud->insets.right; // top-level
+ height += wud->insets.top + wud->insets.bottom; // top-level
+ DBG_PRINT("*** WindowsWindow: NewtWindow_setVisiblePosSize top-level %d/%d %dx%d\n", x, y, width, height);
if(visible) {
- flags = SWP_SHOWWINDOW;
+ wflags = SWP_SHOWWINDOW;
+ if( abottom ) {
+ wflags |= SWP_NOACTIVATE;
+ }
} else {
- flags = SWP_NOACTIVATE | SWP_NOZORDER;
+ wflags = SWP_NOACTIVATE | SWP_NOZORDER;
}
if(0>=width || 0>=height ) {
- flags |= SWP_NOSIZE;
+ wflags |= SWP_NOSIZE;
}
+ wud->isOnTop = atop;
+ wud->isOnBottom = abottom;
if(atop) {
- SetWindowPos(hwnd, HWND_TOP, x, y, width, height, flags);
- SetWindowPos(hwnd, HWND_TOPMOST, x, y, width, height, flags);
+ SetWindowPos(hwnd, HWND_TOP, x, y, width, height, wflags);
+ SetWindowPos(hwnd, HWND_TOPMOST, x, y, width, height, wflags);
+ } else if(abottom) {
+ SetWindowPos(hwnd, HWND_NOTOPMOST, x, y, width, height, wflags);
+ SetWindowPos(hwnd, HWND_BOTTOM, x, y, width, height, wflags);
} else {
- SetWindowPos(hwnd, HWND_NOTOPMOST, x, y, width, height, flags);
- SetWindowPos(hwnd, HWND_TOP, x, y, width, height, flags);
+ SetWindowPos(hwnd, HWND_NOTOPMOST, x, y, width, height, wflags);
+ SetWindowPos(hwnd, HWND_TOP, x, y, width, height, wflags);
+ }
+
+ if( TST_FLAG_CHANGE_MAXIMIZED_ANY(jflags) ) {
+ if( TST_FLAG_IS_MAXIMIZED_VERT(jflags) && TST_FLAG_IS_MAXIMIZED_HORZ(jflags) ) {
+ wud->isMaximized = 1;
+ ShowWindow(hwnd, SW_MAXIMIZE);
+ } else if( !TST_FLAG_IS_MAXIMIZED_VERT(jflags) && !TST_FLAG_IS_MAXIMIZED_HORZ(jflags) ) {
+ if( wud->isMaximized ) {
+ ShowWindow(hwnd, SW_RESTORE);
+ wud->isMaximized = 0;
+ }
+ }
}
- // SetWindowPos(hwnd, atop ? HWND_TOPMOST : HWND_TOP, x, y, width, height, flags);
InvalidateRect(hwnd, NULL, TRUE);
UpdateWindow(hwnd);
@@ -2128,16 +2253,15 @@ static void NewtWindow_setVisiblePosSize(HWND hwnd, BOOL atop, BOOL visible,
JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowDriver_CreateWindow0
(JNIEnv *env, jobject obj,
jlong hInstance, jstring jWndClassName, jstring jWndName, jint winMajor, jint winMinor,
- jlong parent, jint jx, jint jy, jint defaultWidth, jint defaultHeight, jboolean autoPosition, jint flags)
+ jlong parent, jint jxpos, jint jypos, jint defaultWidth, jint defaultHeight, jint flags)
{
HWND parentWindow = (HWND) (intptr_t) parent;
const TCHAR* wndClassName = NULL;
const TCHAR* wndName = NULL;
- DWORD windowStyle = WS_DEFAULT_STYLES | WS_VISIBLE;
- int x=(int)jx, y=(int)jy;
+ DWORD windowStyle = WS_DEFAULT_STYLES;
+ int xpos=(int)jxpos, ypos=(int)jypos;
int width=(int)defaultWidth, height=(int)defaultHeight;
- HWND window = NULL;
- int _x = x, _y = y; // pos for CreateWindow, might be tweaked
+ HWND hwnd = NULL;
#ifdef UNICODE
wndClassName = NewtCommon_GetNullTerminatedStringChars(env, jWndClassName);
@@ -2153,43 +2277,54 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowDriver_CreateWindo
return 0;
}
windowStyle |= WS_CHILD ;
- } else if ( TST_FLAG_IS_UNDECORATED(flags) ) {
- windowStyle |= WS_POPUP | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX;
} else {
- windowStyle |= WS_OVERLAPPEDWINDOW;
- if(JNI_TRUE == autoPosition) {
+ if ( TST_FLAG_IS_UNDECORATED(flags) ) {
+ windowStyle |= WS_POPUP | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX;
+ } else if ( TST_FLAG_IS_RESIZABLE(flags) ) {
+ // WS_OVERLAPPEDWINDOW = (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX);
+ windowStyle |= WS_OVERLAPPEDWINDOW;
+ } else {
+ windowStyle |= WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
+ }
+ if( TST_FLAG_IS_AUTOPOSITION(flags) ) {
// user didn't requested specific position, use WM default
- _x = CW_USEDEFAULT;
- _y = 0;
+ xpos = CW_USEDEFAULT;
+ ypos = 0;
}
}
- window = CreateWindow(wndClassName, wndName, windowStyle,
- _x, _y, width, height,
- parentWindow, NULL,
- (HINSTANCE) (intptr_t) hInstance,
- NULL);
+ hwnd = CreateWindow(wndClassName, wndName, windowStyle,
+ xpos, ypos, width, height,
+ parentWindow, NULL, (HINSTANCE) (intptr_t) hInstance, NULL);
- DBG_PRINT("*** WindowsWindow: CreateWindow thread 0x%X, win %d.%d parent %p, window %p, %d/%d %dx%d, undeco %d, alwaysOnTop %d, autoPosition %d\n",
- (int)GetCurrentThreadId(), winMajor, winMinor, parentWindow, window, x, y, width, height,
- TST_FLAG_IS_UNDECORATED(flags), TST_FLAG_IS_ALWAYSONTOP(flags), autoPosition);
+ DBG_PRINT("*** WindowsWindow: CreateWindow thread 0x%X, win %d.%d parent %p, window %p, %d/%d -> %d/%d %dx%d, undeco %d, alwaysOnTop %d, autoPosition %d\n",
+ (int)GetCurrentThreadId(), winMajor, winMinor, parentWindow, hwnd, jxpos, jypos, xpos, ypos, width, height,
+ TST_FLAG_IS_UNDECORATED(flags), TST_FLAG_IS_ALWAYSONTOP(flags), TST_FLAG_IS_AUTOPOSITION(flags));
- if (NULL == window) {
+ if (NULL == hwnd) {
int lastError = (int) GetLastError();
DBG_PRINT("*** WindowsWindow: CreateWindow failure: 0x%X %d\n", lastError, lastError);
- return 0;
} else {
WindowUserData * wud = (WindowUserData *) malloc(sizeof(WindowUserData));
wud->jinstance = (*env)->NewGlobalRef(env, obj);
wud->jenv = env;
+ wud->xpos = xpos;
+ wud->ypos = ypos;
wud->width = width;
wud->height = height;
+ wud->visible = TRUE;
+ wud->focused = TRUE;
wud->setPointerVisible = 0;
wud->setPointerAction = 0;
wud->defPointerHandle = LoadCursor( NULL, IDC_ARROW);
wud->setPointerHandle = wud->defPointerHandle;
- wud->isFullscreen = 0;
+ wud->isFullscreen = FALSE;
wud->isChildWindow = NULL!=parentWindow;
+ wud->isMinimized = FALSE;
+ wud->isMaximized = FALSE;
+ wud->isOnBottom = FALSE;
+ wud->isOnTop = FALSE;
+ wud->isInCreation = TRUE;
wud->pointerCaptured = 0;
wud->pointerInside = 0;
wud->touchDownCount = 0;
@@ -2208,40 +2343,26 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowDriver_CreateWindo
DBG_PRINT("*** WindowsWindow: CreateWindow winTouchFuncAvail %d, supportsMTouch %d\n", WinTouch_func_avail, wud->supportsMTouch);
#if !defined(__MINGW64__) && ( defined(UNDER_CE) || _MSC_VER <= 1200 )
- SetWindowLong(window, GWL_USERDATA, (intptr_t) wud);
+ SetWindowLong(hwnd, GWL_USERDATA, (intptr_t) wud);
#else
- SetWindowLongPtr(window, GWLP_USERDATA, (intptr_t) wud);
+ SetWindowLongPtr(hwnd, GWLP_USERDATA, (intptr_t) wud);
#endif
- // gather and adjust position and size
- {
- RECT rc;
- RECT * insets;
-
- ShowWindow(window, SW_SHOW);
-
- // send insets before visibility, allowing java code a proper sync point!
- insets = UpdateInsets(env, wud->jinstance, window);
- (*env)->CallVoidMethod(env, wud->jinstance, visibleChangedID, JNI_FALSE, JNI_TRUE);
-
- if(JNI_TRUE == autoPosition) {
- GetWindowRect(window, &rc);
- x = rc.left + insets->left; // client coords
- y = rc.top + insets->top; // client coords
- }
- DBG_PRINT("*** WindowsWindow: CreateWindow client: %d/%d %dx%d (autoPosition %d)\n", x, y, width, height, autoPosition);
+ // send insets before visibility, allowing java code a proper sync point!
+ UpdateInsets(env, wud, hwnd);
- x -= insets->left; // top-level
- y -= insets->top; // top-level
- width += insets->left + insets->right; // top-level
- height += insets->top + insets->bottom; // top-level
- DBG_PRINT("*** WindowsWindow: CreateWindow top-level %d/%d %dx%d\n", x, y, width, height);
-
- NewtWindow_setVisiblePosSize(window, TST_FLAG_IS_ALWAYSONTOP(flags), TRUE, x, y, width, height);
- }
- if( wud->supportsMTouch ) {
- WinTouch_RegisterTouchWindow(window, 0);
+ if( TST_FLAG_IS_AUTOPOSITION(flags) ) {
+ RECT rc;
+ GetWindowRect(hwnd, &rc);
+ xpos = rc.left + wud->insets.left; // client coords
+ ypos = rc.top + wud->insets.top; // client coords
+ wud->xpos = xpos;
+ wud->ypos = ypos;
}
+ DBG_PRINT("*** WindowsWindow: CreateWindow client: %d/%d %dx%d -> %d/%d %dx%d (autoPosition %d)\n",
+ xpos, ypos, width, height,
+ wud->xpos, wud->ypos, wud->width, wud->height,
+ TST_FLAG_IS_AUTOPOSITION(flags));
}
#ifdef UNICODE
@@ -2258,7 +2379,49 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowDriver_CreateWindo
DBG_PRINT("**** LLMP Hook %p, MP Hook %p\n", hookLLMP, hookMP);
#endif
- return (jlong) (intptr_t) window;
+ DBG_PRINT("*** WindowsWindow: CreateWindow done\n");
+ return (jlong) (intptr_t) hwnd;
+}
+
+/*
+ * Class: jogamp_newt_driver_windows_WindowDriver
+ * Method: InitWindow
+ */
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowDriver_InitWindow0
+ (JNIEnv *env, jobject obj, jlong window, jint flags)
+{
+ HWND hwnd = (HWND) (intptr_t) window;
+ WindowUserData * wud;
+#if !defined(__MINGW64__) && ( defined(UNDER_CE) || _MSC_VER <= 1200 )
+ wud = (WindowUserData *) GetWindowLong(hwnd, GWL_USERDATA);
+#else
+ wud = (WindowUserData *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
+#endif
+
+ DBG_PRINT("*** WindowsWindow: InitWindow start %d/%d %dx%d, focused %d, visible %d\n",
+ wud->xpos, wud->ypos, wud->width, wud->height, wud->focused, wud->visible);
+
+ NewtWindow_setVisiblePosSize(wud, hwnd, flags, TRUE, wud->xpos, wud->ypos, wud->width, wud->height);
+ wud->isInCreation = FALSE;
+
+ DBG_PRINT("*** WindowsWindow: InitWindow pos/size set: %d/%d %dx%d, focused %d, visible %d\n",
+ wud->xpos, wud->ypos, wud->width, wud->height, wud->focused, wud->visible);
+
+ if( wud->isMaximized ) {
+ (*env)->CallVoidMethod(env, wud->jinstance, maximizedChangedID, JNI_TRUE, JNI_TRUE);
+ }
+ (*env)->CallVoidMethod(env, wud->jinstance, sizePosInsetsFocusVisibleChangedID, JNI_FALSE,
+ (jint)wud->xpos, (jint)wud->ypos,
+ (jint)wud->width, (jint)wud->height,
+ (jint)wud->insets.left, (jint)wud->insets.right, (jint)wud->insets.top, (jint)wud->insets.bottom,
+ (jint)(wud->focused ? 1 : 0),
+ (jint)(wud->visible ? 1 : 0),
+ JNI_FALSE);
+ DBG_PRINT("*** WindowsWindow: InitWindow JNI callbacks done\n");
+
+ if( wud->supportsMTouch ) {
+ WinTouch_RegisterTouchWindow(hwnd, 0);
+ }
}
/*
@@ -2288,7 +2451,10 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowDriver_reconfigureW
HWND hwndP = (HWND) (intptr_t) parent;
HWND hwnd = (HWND) (intptr_t) window;
DWORD windowStyle = WS_DEFAULT_STYLES;
- BOOL styleChange = TST_FLAG_CHANGE_DECORATION(flags) || TST_FLAG_CHANGE_FULLSCREEN(flags) || TST_FLAG_CHANGE_PARENTING(flags) ;
+ BOOL styleChange = TST_FLAG_CHANGE_DECORATION(flags) || TST_FLAG_CHANGE_FULLSCREEN(flags) ||
+ TST_FLAG_CHANGE_PARENTING(flags) || TST_FLAG_CHANGE_RESIZABLE(flags);
+ BOOL atop = TST_FLAG_IS_ALWAYSONTOP(flags);
+ BOOL abottom = TST_FLAG_IS_ALWAYSONBOTTOM(flags);
WindowUserData * wud;
#if !defined(__MINGW64__) && ( defined(UNDER_CE) || _MSC_VER <= 1200 )
wud = (WindowUserData *) GetWindowLong(hwnd, GWL_USERDATA);
@@ -2296,20 +2462,25 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowDriver_reconfigureW
wud = (WindowUserData *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
#endif
-
- DBG_PRINT( "*** WindowsWindow: reconfigureWindow0 parent %p, window %p, %d/%d %dx%d, parentChange %d, isChild %d, decorationChange %d, undecorated %d, fullscreenChange %d, fullscreen %d, alwaysOnTopChange %d, alwaysOnTop %d, visibleChange %d, visible %d -> styleChange %d, isChild %d, isFullscreen %d\n",
+ DBG_PRINT( "*** WindowsWindow: reconfigureWindow0 parent %p, window %p, %d/%d %dx%d, parentChange %d, isChild %d, undecoration[change %d, val %d], fullscreen[change %d, val %d], alwaysOnTop[change %d, val %d], alwaysOnBottom[change %d, val %d], visible[change %d, val %d], resizable[change %d, val %d] -> styleChange %d, isChild %d, isMinimized %d, isMaximized %d, isFullscreen %d\n",
parent, window, x, y, width, height,
TST_FLAG_CHANGE_PARENTING(flags), TST_FLAG_IS_CHILD(flags),
TST_FLAG_CHANGE_DECORATION(flags), TST_FLAG_IS_UNDECORATED(flags),
TST_FLAG_CHANGE_FULLSCREEN(flags), TST_FLAG_IS_FULLSCREEN(flags),
TST_FLAG_CHANGE_ALWAYSONTOP(flags), TST_FLAG_IS_ALWAYSONTOP(flags),
- TST_FLAG_CHANGE_VISIBILITY(flags), TST_FLAG_IS_VISIBLE(flags), styleChange, wud->isChildWindow, wud->isFullscreen);
+ TST_FLAG_CHANGE_ALWAYSONBOTTOM(flags), TST_FLAG_IS_ALWAYSONBOTTOM(flags),
+ TST_FLAG_CHANGE_VISIBILITY(flags), TST_FLAG_IS_VISIBLE(flags),
+ TST_FLAG_CHANGE_RESIZABLE(flags), TST_FLAG_CHANGE_RESIZABLE(flags), styleChange,
+ wud->isChildWindow, wud->isMinimized, wud->isMaximized, wud->isFullscreen);
if (!IsWindow(hwnd)) {
DBG_PRINT("*** WindowsWindow: reconfigureWindow0 failure: Passed window %p is invalid\n", (void*)hwnd);
return;
}
+ wud->isOnTop = atop;
+ wud->isOnBottom = abottom;
+
if (NULL!=hwndP && !IsWindow(hwndP)) {
DBG_PRINT("*** WindowsWindow: reconfigureWindow0 failure: Passed parent window %p is invalid\n", (void*)hwndP);
return;
@@ -2334,10 +2505,15 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowDriver_reconfigureW
SetParent(hwnd, NULL);
}
- if( TST_FLAG_CHANGE_FULLSCREEN(flags) && TST_FLAG_IS_FULLSCREEN(flags) ) { // FS on
- // TOP: in -> out
- wud->isFullscreen = 1;
- NewtWindows_setFullScreen(JNI_TRUE);
+ if( TST_FLAG_IS_FULLSCREEN(flags) ) {
+ if( TST_FLAG_CHANGE_FULLSCREEN(flags) ) { // FS on
+ wud->isFullscreen = TRUE;
+ if( !abottom ) {
+ NewtWindows_setFullScreen(JNI_TRUE);
+ }
+ } else if( TST_FLAG_CHANGE_ALWAYSONBOTTOM(flags) ) { // FS BOTTOM toggle
+ NewtWindows_setFullScreen( abottom ? JNI_FALSE : JNI_TRUE);
+ }
}
if ( styleChange ) {
@@ -2345,16 +2521,18 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowDriver_reconfigureW
windowStyle |= WS_CHILD ;
} else if ( TST_FLAG_IS_UNDECORATED(flags) ) {
windowStyle |= WS_POPUP | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX;
- } else {
+ } else if ( TST_FLAG_IS_RESIZABLE(flags) ) {
+ // WS_OVERLAPPEDWINDOW = (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX);
windowStyle |= WS_OVERLAPPEDWINDOW;
+ } else {
+ windowStyle |= WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
}
SetWindowLong(hwnd, GWL_STYLE, windowStyle);
SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER );
}
if( TST_FLAG_CHANGE_FULLSCREEN(flags) && !TST_FLAG_IS_FULLSCREEN(flags) ) { // FS off
- // CHILD: out -> in
- wud->isFullscreen = 0;
+ wud->isFullscreen = FALSE;
NewtWindows_setFullScreen(JNI_FALSE);
}
@@ -2363,17 +2541,25 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowDriver_reconfigureW
SetParent(hwnd, hwndP );
}
- NewtWindow_setVisiblePosSize(hwnd, TST_FLAG_IS_ALWAYSONTOP(flags), TST_FLAG_IS_VISIBLE(flags), x, y, width, height);
+ NewtWindow_setVisiblePosSize(wud, hwnd, flags, TST_FLAG_IS_VISIBLE(flags), x, y, width, height);
if( TST_FLAG_CHANGE_VISIBILITY(flags) ) {
if( TST_FLAG_IS_VISIBLE(flags) ) {
- ShowWindow(hwnd, SW_SHOW);
+ int cmd = wud->isMinimized ? SW_RESTORE : ( abottom ? SW_SHOWNA : SW_SHOW );
+ wud->isMinimized = FALSE;
+ ShowWindow(hwnd, cmd);
+ if( abottom ) {
+ SetWindowPos(hwnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
+ }
+ } else if( !TST_FLAG_CHANGE_VISIBILITY_FAST(flags) && !TST_FLAG_IS_CHILD(flags) ) {
+ wud->isMinimized = TRUE;
+ ShowWindow(hwnd, SW_MINIMIZE);
} else {
ShowWindow(hwnd, SW_HIDE);
}
}
- DBG_PRINT("*** WindowsWindow: reconfigureWindow0.X isChild %d, isFullscreen %d\n", wud->isChildWindow, wud->isFullscreen);
+ DBG_PRINT("*** WindowsWindow: reconfigureWindow0.X isChild %d, isMinimized %d, isFullscreen %d\n", wud->isChildWindow, wud->isMinimized, wud->isFullscreen);
}
/*
diff --git a/src/newt/native/X11Common.h b/src/newt/native/X11Common.h
index 309e62683..f9254ab76 100644
--- a/src/newt/native/X11Common.h
+++ b/src/newt/native/X11Common.h
@@ -71,7 +71,7 @@
extern jclass X11NewtWindowClazz;
extern jmethodID insetsChangedID;
extern jmethodID visibleChangedID;
-extern jmethodID minMaxSizeChangedID;
+extern jmethodID insetsVisibleChangedID;
typedef struct {
Window window;
@@ -81,13 +81,71 @@ typedef struct {
Atom windowDeleteAtom;
uint32_t supportedAtoms;
uint32_t lastDesktop;
+ Bool maxHorz;
+ Bool maxVert;
+ /** flag whether window is mapped */
+ Bool isMapped;
} JavaWindow;
JavaWindow * getJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, jlong javaObjectAtom, Bool showWarning);
Status NewtWindows_getRootAndParent (Display *dpy, Window w, Window * root_return, Window * parent_return);
-Status NewtWindows_updateInsets(JNIEnv *env, Display *dpy, JavaWindow * w, int *left, int *right, int *top, int *bottom);
-void NewtWindows_updateMinMaxSize(JNIEnv *env, Display *dpy, JavaWindow * w);
+Bool NewtWindows_updateInsets(Display *dpy, JavaWindow * w, int *left, int *right, int *top, int *bottom);
+Bool NewtWindows_updateMaximized(Display *dpy, JavaWindow * w, uint32_t netWMState);
+
+#define _MASK_NET_WM_STATE ( 1 << 0 )
+#define _MASK_NET_WM_STATE_MODAL ( 1 << 1 )
+#define _MASK_NET_WM_STATE_STICKY ( 1 << 2 )
+#define _MASK_NET_WM_STATE_MAXIMIZED_VERT ( 1 << 3 )
+#define _MASK_NET_WM_STATE_MAXIMIZED_HORZ ( 1 << 4 )
+#define _MASK_NET_WM_STATE_SHADED ( 1 << 5 )
+#define _MASK_NET_WM_STATE_HIDDEN ( 1 << 8 )
+#define _MASK_NET_WM_STATE_FULLSCREEN ( 1 << 9 )
+#define _MASK_NET_WM_STATE_ABOVE ( 1 << 10 )
+#define _MASK_NET_WM_STATE_BELOW ( 1 << 11 )
+#define _MASK_NET_WM_STATE_DEMANDS_ATTENTION ( 1 << 12 )
+#define _MASK_NET_WM_STATE_FOCUSED ( 1 << 13 )
+#define _MASK_NET_WM_BYPASS_COMPOSITOR ( 1 << 14 )
+#define _MASK_NET_WM_DESKTOP ( 1 << 15 )
+#define _MASK_NET_CURRENT_DESKTOP ( 1 << 16 )
+#define _MASK_NET_WM_WINDOW_TYPE ( 1 << 17 )
+#define _MASK_NET_WM_WINDOW_TYPE_NORMAL ( 1 << 18 )
+#define _MASK_NET_WM_WINDOW_TYPE_POPUP_MENU ( 1 << 19 )
+#define _MASK_NET_FRAME_EXTENTS ( 1 << 20 )
+#define _MASK_NET_SUPPORTED ( 1 << 21 )
+#define _MASK_NET_ACTIVE_WINDOW ( 1 << 22 )
+#define _MASK_WM_CHANGE_STATE ( 1 << 23 )
+#define _MASK_MOTIF_WM_HINTS ( 1 << 24 )
+
+#define _NET_WM_STATE_IDX 0
+#define _NET_WM_STATE_MODAL_IDX 1
+#define _NET_WM_STATE_STICKY_IDX 2
+#define _NET_WM_STATE_MAXIMIZED_VERT_IDX 3
+#define _NET_WM_STATE_MAXIMIZED_HORZ_IDX 4
+#define _NET_WM_STATE_SHADED_IDX 5
+#define _NET_WM_STATE_SKIP_TASKBAR_IDX 6
+#define _NET_WM_STATE_SKIP_PAGER_IDX 7
+#define _NET_WM_STATE_HIDDEN_IDX 8
+#define _NET_WM_STATE_FULLSCREEN_IDX 9
+#define _NET_WM_STATE_ABOVE_IDX 10
+#define _NET_WM_STATE_BELOW_IDX 11
+#define _NET_WM_STATE_DEMANDS_ATTENTION_IDX 12
+#define _NET_WM_STATE_FOCUSED_IDX 13
+#define _NET_WM_BYPASS_COMPOSITOR_IDX 14
+#define _NET_WM_DESKTOP_IDX 15
+#define _NET_CURRENT_DESKTOP_IDX 16
+#define _NET_WM_WINDOW_TYPE_IDX 17
+#define _NET_WM_WINDOW_TYPE_NORMAL_IDX 18
+#define _NET_WM_WINDOW_TYPE_POPUP_MENU_IDX 19
+#define _NET_FRAME_EXTENTS_IDX 20
+#define _NET_SUPPORTED_IDX 21
+#define _NET_ACTIVE_WINDOW_IDX 22
+#define _WM_CHANGE_STATE_IDX 23
+#define _MOTIF_WM_HINTS_IDX 24
+
+void NewtWindows_setUrgency(Display *dpy, Window window, Bool enable);
+void NewtWindows_sendNET_WM_STATE(Display *dpy, Window root, JavaWindow *w, int prop1Idx, int prop2Idx, Bool enable);
+uint32_t NewtWindows_getNET_WM_STATE(Display *dpy, JavaWindow *w);
#endif /* _X11COMMON_H_ */
diff --git a/src/newt/native/X11Display.c b/src/newt/native/X11Display.c
index 0ba454a00..32e0f8786 100644
--- a/src/newt/native/X11Display.c
+++ b/src/newt/native/X11Display.c
@@ -35,7 +35,7 @@
jclass X11NewtWindowClazz = NULL;
jmethodID insetsChangedID = NULL;
jmethodID visibleChangedID = NULL;
-jmethodID minMaxSizeChangedID = NULL;
+jmethodID insetsVisibleChangedID = NULL;
static const char * const ClazzNameX11NewtWindow = "jogamp/newt/driver/x11/WindowDriver";
@@ -46,13 +46,16 @@ static jmethodID getCurrentThreadNameID = NULL;
static jmethodID dumpStackID = NULL;
static jmethodID sizeChangedID = NULL;
static jmethodID positionChangedID = NULL;
-static jmethodID focusChangedID = NULL;
+static jmethodID focusVisibleChangedID = NULL;
static jmethodID reparentNotifyID = NULL;
static jmethodID windowDestroyNotifyID = NULL;
static jmethodID windowRepaintID = NULL;
static jmethodID sendMouseEventID = NULL;
static jmethodID sendKeyEventID = NULL;
-static jmethodID requestFocusID = NULL;
+static jmethodID sendMouseEventRequestFocusID = NULL;
+static jmethodID visibleChangedWindowRepaintID = NULL;
+static jmethodID visibleChangedSendMouseEventID = NULL;
+static jmethodID sizePosMaxInsetsVisibleChangedID = NULL;
/**
* Keycode
@@ -222,7 +225,7 @@ static jint X11InputState2NewtModifiers(unsigned int xstate, jshort javaVKey, jb
/*
* Class: jogamp_newt_driver_x11_DisplayDriver
- * Method: initIDs
+ * Method: initIDs0
* Signature: (Z)Z
*/
JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_initIDs0
@@ -252,15 +255,18 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_initIDs0
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");
+ focusVisibleChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "focusVisibleChanged", "(ZII)V");
visibleChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "visibleChanged", "(ZZ)V");
- minMaxSizeChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "minMaxSizeChanged", "(IIII)V");
+ insetsVisibleChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "insetsVisibleChanged", "(ZIIIII)V");
+ sizePosMaxInsetsVisibleChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sizePosMaxInsetsVisibleChanged", "(ZIIIIIIIIIIIZ)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");
+ visibleChangedWindowRepaintID = (*env)->GetMethodID(env, X11NewtWindowClazz, "visibleChangedWindowRepaint", "(ZIIIII)V");
sendMouseEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendMouseEvent", "(SIIISF)V");
+ sendMouseEventRequestFocusID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendMouseEventRequestFocus", "(SIIISF)V");
+ visibleChangedSendMouseEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "visibleChangedSendMouseEvent", "(ZISIIISF)V");
sendKeyEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendKeyEvent", "(SISSCLjava/lang/String;)V");
- requestFocusID = (*env)->GetMethodID(env, X11NewtWindowClazz, "requestFocus", "(Z)V");
if (displayCompletedID == NULL ||
sendRRScreenChangeNotifyID == NULL ||
@@ -269,15 +275,18 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_initIDs0
insetsChangedID == NULL ||
sizeChangedID == NULL ||
positionChangedID == NULL ||
- focusChangedID == NULL ||
+ focusVisibleChangedID == NULL ||
visibleChangedID == NULL ||
- minMaxSizeChangedID == NULL ||
+ insetsVisibleChangedID == NULL ||
+ sizePosMaxInsetsVisibleChangedID == NULL ||
reparentNotifyID == NULL ||
windowDestroyNotifyID == NULL ||
windowRepaintID == NULL ||
+ visibleChangedWindowRepaintID == NULL ||
sendMouseEventID == NULL ||
- sendKeyEventID == NULL ||
- requestFocusID == NULL) {
+ sendMouseEventRequestFocusID == NULL ||
+ visibleChangedSendMouseEventID == NULL ||
+ sendKeyEventID == NULL) {
return JNI_FALSE;
}
@@ -287,7 +296,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_initIDs0
/*
* Class: jogamp_newt_driver_x11_DisplayDriver
- * Method: CompleteDisplay
+ * Method: CompleteDisplay0
* Signature: (J)V
*/
JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_CompleteDisplay0
@@ -353,10 +362,33 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DisplayRelease0
DBG_PRINT("X11: X11Display_DisplayRelease dpy %p\n", dpy);
}
+static int NewtWindows_updateVisibility(JNIEnv *env, Display *dpy, JavaWindow *jw, uint32_t netWMState, const char *dbgs) {
+ int visibleChange;
+ if( jw->isMapped && 0 != ( _MASK_NET_WM_STATE_HIDDEN & jw->supportedAtoms ) ) {
+ if( 0 != ( _MASK_NET_WM_STATE_HIDDEN & netWMState ) ) {
+ visibleChange = 0;
+ } else {
+ visibleChange = 1;
+ }
+ } else {
+ visibleChange = -1;
+ }
+ #ifdef VERBOSE_ON
+ XWindowAttributes xwa;
+ memset(&xwa, 0, sizeof(XWindowAttributes));
+ XGetWindowAttributes(dpy, jw->window, &xwa);
+
+ // map_state: IsUnmapped(0), IsUnviewable(1), IsViewable(2)
+ DBG_PRINT( "X11: event . %s call %p - isMapped %d, visibleChanged %d, map_state %d\n",
+ dbgs, (void*)jw->window, jw->isMapped, visibleChange, xwa.map_state);
+ #endif
+ return visibleChange;
+}
+
/*
* Class: jogamp_newt_driver_x11_DisplayDriver
- * Method: DispatchMessages
- * Signature: (JJJ)V
+ * Method: DispatchMessages0
+ * Signature: (JJJII)V
*/
JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessages0
(JNIEnv *env, jobject obj, jlong display, jlong javaObjectAtom, jlong windowDeleteAtom /*, jlong kbdHandle*/,
@@ -522,8 +554,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage
switch(evt.type) {
case ButtonPress:
- (*env)->CallVoidMethod(env, jw->jwindow, requestFocusID, JNI_FALSE);
- (*env)->CallVoidMethod(env, jw->jwindow, sendMouseEventID, (jshort) EVENT_MOUSE_PRESSED,
+ (*env)->CallVoidMethod(env, jw->jwindow, sendMouseEventRequestFocusID, (jshort) EVENT_MOUSE_PRESSED,
modifiers,
(jint) evt.xbutton.x, (jint) evt.xbutton.y, (jshort) evt.xbutton.button, 0.0f /*rotation*/);
break;
@@ -539,15 +570,23 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage
break;
case EnterNotify:
DBG_PRINT( "X11: event . EnterNotify call %p %d/%d\n", (void*)evt.xcrossing.window, evt.xcrossing.x, evt.xcrossing.y);
- (*env)->CallVoidMethod(env, jw->jwindow, sendMouseEventID, (jshort) EVENT_MOUSE_ENTERED,
- modifiers,
- (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jshort) 0, 0.0f /*rotation*/);
+ {
+ uint32_t netWMState = NewtWindows_getNET_WM_STATE(dpy, jw);
+ int visibleChange = NewtWindows_updateVisibility(env, dpy, jw, netWMState, "EnterNotify");
+ (*env)->CallVoidMethod(env, jw->jwindow, visibleChangedSendMouseEventID, JNI_FALSE, (jint)visibleChange,
+ (jshort) EVENT_MOUSE_ENTERED, modifiers,
+ (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jshort) 0, 0.0f /*rotation*/);
+ }
break;
case LeaveNotify:
DBG_PRINT( "X11: event . LeaveNotify call %p %d/%d\n", (void*)evt.xcrossing.window, evt.xcrossing.x, evt.xcrossing.y);
- (*env)->CallVoidMethod(env, jw->jwindow, sendMouseEventID, (jshort) EVENT_MOUSE_EXITED,
- modifiers,
- (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jshort) 0, 0.0f /*rotation*/);
+ {
+ uint32_t netWMState = NewtWindows_getNET_WM_STATE(dpy, jw);
+ int visibleChange = NewtWindows_updateVisibility(env, dpy, jw, netWMState, "LeaveNotify");
+ (*env)->CallVoidMethod(env, jw->jwindow, visibleChangedSendMouseEventID, JNI_FALSE, (jint)visibleChange,
+ (jshort) EVENT_MOUSE_EXITED, modifiers,
+ (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jshort) 0, 0.0f /*rotation*/);
+ }
break;
case MappingNotify:
DBG_PRINT( "X11: event . MappingNotify call %p type %d\n", (void*)evt.xmapping.window, evt.xmapping.type);
@@ -579,19 +618,25 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage
evt.xconfigure.override_redirect, evt.xconfigure.window != evt.xconfigure.event);
if ( evt.xconfigure.window == evt.xconfigure.event ) {
// ignore child window change notification
- {
- // update insets
- int left, right, top, bottom;
- NewtWindows_updateInsets(env, dpy, jw, &left, &right, &top, &bottom);
- }
- NewtWindows_updateMinMaxSize(env, dpy, jw);
- (*env)->CallVoidMethod(env, jw->jwindow, sizeChangedID, JNI_FALSE,
- (jint) evt.xconfigure.width, (jint) evt.xconfigure.height, JNI_FALSE);
- (*env)->CallVoidMethod(env, jw->jwindow, positionChangedID, JNI_FALSE,
- (jint) evt.xconfigure.x, (jint) evt.xconfigure.y);
+ // insets: negative values are ignored
+ int left=-1, right=-1, top=-1, bottom=-1;
+ uint32_t netWMState = NewtWindows_getNET_WM_STATE(dpy, jw);
+ int visibleChange = NewtWindows_updateVisibility(env, dpy, jw, netWMState, "ConfigureNotify");
+ NewtWindows_updateInsets(dpy, jw, &left, &right, &top, &bottom);
+ Bool maxChanged = NewtWindows_updateMaximized(dpy, jw, netWMState);
+ (*env)->CallVoidMethod(env, jw->jwindow, sizePosMaxInsetsVisibleChangedID, JNI_FALSE,
+ (jint) evt.xconfigure.x, (jint) evt.xconfigure.y,
+ (jint) evt.xconfigure.width, (jint) evt.xconfigure.height,
+ (jint)(maxChanged ? ( jw->maxHorz ? 1 : 0 ) : -1),
+ (jint)(maxChanged ? ( jw->maxVert ? 1 : 0 ) : -1),
+ (jint)left, (jint)right, (jint)top, (jint)bottom,
+ (jint)visibleChange,
+ JNI_FALSE);
}
break;
case ClientMessage:
+ DBG_PRINT( "X11: event . ClientMessage call %p type 0x%X, sendEvent %d\n",
+ (void*)evt.xclient.window, (unsigned int)evt.xclient.message_type, evt.xclient.send_event);
if (evt.xclient.send_event==True && evt.xclient.data.l[0]==wm_delete_atom) { // windowDeleteAtom
jboolean closed;
DBG_PRINT( "X11: event . ClientMessage call %p type 0x%X ..\n",
@@ -605,46 +650,76 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage
break;
case FocusIn:
- DBG_PRINT( "X11: event . FocusIn call %p\n", (void*)evt.xvisibility.window);
- (*env)->CallVoidMethod(env, jw->jwindow, focusChangedID, JNI_FALSE, JNI_TRUE);
+ DBG_PRINT( "X11: event . FocusIn call %p\n", (void*)evt.xfocus.window);
+ {
+ uint32_t netWMState = NewtWindows_getNET_WM_STATE(dpy, jw);
+ int visibleChange = NewtWindows_updateVisibility(env, dpy, jw, netWMState, "FocusIn");
+ (*env)->CallVoidMethod(env, jw->jwindow, focusVisibleChangedID, JNI_FALSE, (jint)1, (jint)visibleChange);
+ }
break;
case FocusOut:
- DBG_PRINT( "X11: event . FocusOut call %p\n", (void*)evt.xvisibility.window);
- (*env)->CallVoidMethod(env, jw->jwindow, focusChangedID, JNI_FALSE, JNI_FALSE);
+ DBG_PRINT( "X11: event . FocusOut call %p\n", (void*)evt.xfocus.window);
+ {
+ uint32_t netWMState = NewtWindows_getNET_WM_STATE(dpy, jw);
+ int visibleChange = NewtWindows_updateVisibility(env, dpy, jw, netWMState, "FocusOut");
+ (*env)->CallVoidMethod(env, jw->jwindow, focusVisibleChangedID, JNI_FALSE, (jint)0, (jint)visibleChange);
+ }
+ break;
+
+ case VisibilityNotify:
+ DBG_PRINT( "X11: event . VisibilityNotify call %p\n", (void*)evt.xvisibility.window);
+ {
+ #if 0
+ uint32_t netWMState = NewtWindows_getNET_WM_STATE(dpy, jw);
+ int visibleChange = NewtWindows_updateVisibility(env, dpy, jw, netWMState, "VisibilityNotify");
+ if( 0 <= visibleChange ) {
+ (*env)->CallVoidMethod(env, jw->jwindow, visibleChangedID, JNI_FALSE, 0 < visibleChange ? JNI_TRUE : JNI_FALSE);
+ }
+ #endif
+ }
break;
+
case Expose:
DBG_PRINT( "X11: event . Expose call %p %d/%d %dx%d count %d\n", (void*)evt.xexpose.window,
evt.xexpose.x, evt.xexpose.y, evt.xexpose.width, evt.xexpose.height, evt.xexpose.count);
-
if (evt.xexpose.count == 0 && evt.xexpose.width > 0 && evt.xexpose.height > 0) {
(*env)->CallVoidMethod(env, jw->jwindow, windowRepaintID, JNI_FALSE,
evt.xexpose.x, evt.xexpose.y, evt.xexpose.width, evt.xexpose.height);
+ #if 0
+ uint32_t netWMState = NewtWindows_getNET_WM_STATE(dpy, jw);
+ int visibleChange = NewtWindows_updateVisibility(env, dpy, jw, netWMState, "Expose");
+ (*env)->CallVoidMethod(env, jw->jwindow, visibleChangedWindowRepaintID, JNI_FALSE, (jint)visibleChange,
+ evt.xexpose.x, evt.xexpose.y, evt.xexpose.width, evt.xexpose.height);
+ #endif
}
break;
case MapNotify:
- DBG_PRINT( "X11: event . MapNotify call Event %p, Window %p, override_redirect %d, child-event: %d\n",
- (void*)evt.xmap.event, (void*)evt.xmap.window, (int)evt.xmap.override_redirect,
+ DBG_PRINT( "X11: event . MapNotify call Event %p, Window %p, isMapped %d -> 1, override_redirect %d, child-event: %d\n",
+ (void*)evt.xmap.event, (void*)evt.xmap.window, jw->isMapped, (int)evt.xmap.override_redirect,
evt.xmap.event!=evt.xmap.window);
if( evt.xmap.event == evt.xmap.window ) {
// ignore child window notification
- {
- // update insets
- int left, right, top, bottom;
- NewtWindows_updateInsets(env, dpy, jw, &left, &right, &top, &bottom);
+ jw->isMapped = True;
+ // insets: negative values are ignored
+ int left=-1, right=-1, top=-1, bottom=-1;
+ if( NewtWindows_updateInsets(dpy, jw, &left, &right, &top, &bottom) ) {
+ (*env)->CallVoidMethod(env, jw->jwindow, insetsVisibleChangedID, JNI_FALSE, left, right, top, bottom, 1);
+ } else {
+ (*env)->CallVoidMethod(env, jw->jwindow, visibleChangedID, JNI_FALSE, JNI_TRUE);
}
- (*env)->CallVoidMethod(env, jw->jwindow, visibleChangedID, JNI_FALSE, JNI_TRUE);
}
break;
case UnmapNotify:
- DBG_PRINT( "X11: event . UnmapNotify call Event %p, Window %p, from_configure %d, child-event: %d\n",
- (void*)evt.xunmap.event, (void*)evt.xunmap.window, (int)evt.xunmap.from_configure,
+ DBG_PRINT( "X11: event . UnmapNotify call Event %p, Window %p, isMapped %d -> 0, from_configure %d, child-event: %d\n",
+ (void*)evt.xunmap.event, (void*)evt.xunmap.window, jw->isMapped, (int)evt.xunmap.from_configure,
evt.xunmap.event!=evt.xunmap.window);
if( evt.xunmap.event == evt.xunmap.window ) {
// ignore child window notification
+ jw->isMapped = False;
(*env)->CallVoidMethod(env, jw->jwindow, visibleChangedID, JNI_FALSE, JNI_FALSE);
}
break;
@@ -693,7 +768,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage
/*
* Class: Java_jogamp_newt_driver_x11_DisplayDriver
* Method: createPointerIcon0
- * Signature: (JJILjava/lang/Object;I)V
+ * Signature: (JJIZIIII)J
*/
JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_createPointerIcon0
(JNIEnv *env, jclass clazz, jlong display, jobject pixels, jint pixels_byte_offset, jboolean pixels_is_direct, jint width, jint height, jint hotX, jint hotY)
@@ -731,7 +806,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_createPointerI
/*
* Class: Java_jogamp_newt_driver_x11_DisplayDriver
* Method: destroyPointerIcon0
- * Signature: (JJILjava/lang/Object;I)V
+ * Signature: (JJ)V
*/
JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_destroyPointerIcon0
(JNIEnv *env, jclass clazz, jlong display, jlong handle)
diff --git a/src/newt/native/X11RandR13.c b/src/newt/native/X11RandR13.c
index 0dd53feb8..3f9dff289 100644
--- a/src/newt/native/X11RandR13.c
+++ b/src/newt/native/X11RandR13.c
@@ -39,6 +39,14 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_RandR13_getScreenResources0
Display *dpy = (Display *) (intptr_t) display;
Window root = RootWindow(dpy, (int)screen_idx);
+ /* Bug 1183
+ * XRRGetScreenResourcesCurrent (or XRRGetScreenResources)
+ * _occasionally_ reports empty data
+ * unless XRRGetScreenSizeRange has been called once.
+ */
+ int minWidth, minHeight, maxWidth, maxHeight;
+ XRRGetScreenSizeRange ( dpy, root, &minWidth, &minHeight, &maxWidth, &maxHeight);
+
XRRScreenResources *res = XRRGetScreenResourcesCurrent( dpy, root); // 1.3
// XRRScreenResources *res = XRRGetScreenResources( dpy, root); // 1.2
diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c
index 778b71cc5..de2bddc86 100644
--- a/src/newt/native/X11Window.c
+++ b/src/newt/native/X11Window.c
@@ -85,53 +85,7 @@ static uintptr_t getPtrOut32Long(unsigned long * src) {
#define _NET_WM_STATE_REMOVE 0
#define _NET_WM_STATE_ADD 1
-#define _MASK_NET_WM_STATE ( 1 << 0 )
-#define _MASK_NET_WM_STATE_MODAL ( 1 << 1 )
-#define _MASK_NET_WM_STATE_STICKY ( 1 << 2 )
-#define _MASK_NET_WM_STATE_MAXIMIZED_VERT ( 1 << 3 )
-#define _MASK_NET_WM_STATE_MAXIMIZED_HORZ ( 1 << 4 )
-#define _MASK_NET_WM_STATE_SHADED ( 1 << 5 )
-#define _MASK_NET_WM_STATE_HIDDEN ( 1 << 8 )
-#define _MASK_NET_WM_STATE_FULLSCREEN ( 1 << 9 )
-#define _MASK_NET_WM_STATE_ABOVE ( 1 << 10 )
-#define _MASK_NET_WM_STATE_BELOW ( 1 << 11 )
-#define _MASK_NET_WM_STATE_DEMANDS_ATTENTION ( 1 << 12 )
-#define _MASK_NET_WM_STATE_FOCUSED ( 1 << 13 )
-#define _MASK_NET_WM_BYPASS_COMPOSITOR ( 1 << 14 )
-#define _MASK_NET_WM_DESKTOP ( 1 << 15 )
-#define _MASK_NET_CURRENT_DESKTOP ( 1 << 16 )
-#define _MASK_NET_WM_WINDOW_TYPE ( 1 << 17 )
-#define _MASK_NET_WM_WINDOW_TYPE_NORMAL ( 1 << 18 )
-#define _MASK_NET_WM_WINDOW_TYPE_POPUP_MENU ( 1 << 19 )
-#define _MASK_NET_FRAME_EXTENTS ( 1 << 20 )
-#define _MASK_NET_SUPPORTED ( 1 << 21 )
-#define _MASK_WM_CHANGE_STATE ( 1 << 22 )
-#define _MASK_MOTIF_WM_HINTS ( 1 << 23 )
-
-#define _NET_WM_STATE_IDX 0
-#define _NET_WM_STATE_MODAL_IDX 1
-#define _NET_WM_STATE_STICKY_IDX 2
-#define _NET_WM_STATE_MAXIMIZED_VERT_IDX 3
-#define _NET_WM_STATE_MAXIMIZED_HORZ_IDX 4
-#define _NET_WM_STATE_SHADED_IDX 5
-#define _NET_WM_STATE_SKIP_TASKBAR_IDX 6
-#define _NET_WM_STATE_SKIP_PAGER_IDX 7
-#define _NET_WM_STATE_HIDDEN_IDX 8
-#define _NET_WM_STATE_FULLSCREEN_IDX 9
-#define _NET_WM_STATE_ABOVE_IDX 10
-#define _NET_WM_STATE_BELOW_IDX 11
-#define _NET_WM_STATE_DEMANDS_ATTENTION_IDX 12
-#define _NET_WM_STATE_FOCUSED_IDX 13
-#define _NET_WM_BYPASS_COMPOSITOR_IDX 14
-#define _NET_WM_DESKTOP_IDX 15
-#define _NET_CURRENT_DESKTOP_IDX 16
-#define _NET_WM_WINDOW_TYPE_IDX 17
-#define _NET_WM_WINDOW_TYPE_NORMAL_IDX 18
-#define _NET_WM_WINDOW_TYPE_POPUP_MENU_IDX 19
-#define _NET_FRAME_EXTENTS_IDX 20
-#define _NET_SUPPORTED_IDX 21
-#define _WM_CHANGE_STATE_IDX 22
-#define _MOTIF_WM_HINTS_IDX 23
+/** Sync w/ X11Common.h MASK and IDX */
static const char * _ALL_ATOM_NAMES[] = {
/* 0 */ "_NET_WM_STATE",
/* 1 */ "_NET_WM_STATE_MODAL",
@@ -155,8 +109,9 @@ static const char * _ALL_ATOM_NAMES[] = {
/* 19 */ "_NET_WM_WINDOW_TYPE_POPUP_MENU",
/* 20 */ "_NET_FRAME_EXTENTS",
/* 21 */ "_NET_SUPPORTED",
- /* 22 */ "WM_CHANGE_STATE",
- /* 23 */ "_MOTIF_WM_HINTS"
+ /* 22 */ "_NET_ACTIVE_WINDOW",
+ /* 23 */ "WM_CHANGE_STATE",
+ /* 24 */ "_MOTIF_WM_HINTS"
};
static const uint32_t _ALL_ATOM_COUNT = (uint32_t)(sizeof(_ALL_ATOM_NAMES)/sizeof(const char *));
@@ -178,21 +133,20 @@ static uint32_t NewtWindows_getSupportedFeatureEWMH(Display *dpy, const Atom * a
return 0;
}
static uint32_t NewtWindows_getSupportedFeaturesEWMH(Display *dpy, Window root, Atom * allAtoms, Bool verbose) {
- Atom * actions = NULL;
+ Atom * properties = NULL;
Atom type = 0;
- unsigned long action_len = 0, remain = 0;
+ unsigned long props_count = 0, remain = 0;
int form = 0, i = 0;
uint32_t res = 0;
Status s;
- XSync(dpy, False);
if ( Success == (s = XGetWindowProperty(dpy, root, allAtoms[_NET_SUPPORTED_IDX], 0, 1024, False, AnyPropertyType,
- &type, &form, &action_len, &remain, (unsigned char**)&actions)) ) {
- if( NULL != actions ) {
- for(i=0; i<action_len; i++) {
- res |= NewtWindows_getSupportedFeatureEWMH(dpy, allAtoms, actions[i], i, verbose);
+ &type, &form, &props_count, &remain, (unsigned char**)&properties)) ) {
+ if( NULL != properties ) {
+ for(i=0; i<props_count; i++) {
+ res |= NewtWindows_getSupportedFeatureEWMH(dpy, allAtoms, properties[i], i, verbose);
}
- XFree(actions);
+ XFree(properties);
}
if(verbose) {
fprintf(stderr, "**************** X11: Feature EWMH CHECK: 0x%X\n", res);
@@ -202,6 +156,39 @@ static uint32_t NewtWindows_getSupportedFeaturesEWMH(Display *dpy, Window root,
}
return res;
}
+uint32_t NewtWindows_getNET_WM_STATE(Display *dpy, JavaWindow *w) {
+ Bool verbose =
+#ifdef VERBOSE_ON
+ True
+#else
+ False
+#endif
+ ;
+ Window window = w->window;
+ Atom * allAtoms = w->allAtoms;
+ Atom * properties = NULL;
+ Atom type = 0;
+ unsigned long props_count = 0, remain = 0;
+ int form = 0, i = 0;
+ uint32_t res = 0;
+ Status s;
+
+ if ( Success == (s = XGetWindowProperty(dpy, window, allAtoms[_NET_WM_STATE_IDX], 0, 1024, False, AnyPropertyType,
+ &type, &form, &props_count, &remain, (unsigned char**)&properties)) ) {
+ if( NULL != properties ) {
+ for(i=0; i<props_count; i++) {
+ res |= NewtWindows_getSupportedFeatureEWMH(dpy, allAtoms, properties[i], i, verbose);
+ }
+ XFree(properties);
+ }
+ if(verbose) {
+ fprintf(stderr, "**************** X11: WM_STATE of %p: %d props -> 0x%X\n", (void*)window, (int)props_count, res);
+ }
+ } else if(verbose) {
+ fprintf(stderr, "**************** X11: WM_STATE of %p: XGetWindowProperty failed: %d\n", (void*)window, s);
+ }
+ return res;
+}
static JavaWindow* createJavaWindowProperty(JNIEnv *env, Display *dpy, Window root, Window window,
jlong javaObjectAtom, jlong windowDeleteAtom, jobject obj, Bool verbose) {
@@ -222,6 +209,9 @@ static JavaWindow* createJavaWindowProperty(JNIEnv *env, Display *dpy, Window ro
res->windowDeleteAtom = (Atom)windowDeleteAtom;
res->supportedAtoms = NewtWindows_getSupportedFeaturesEWMH(dpy, root, allAtoms, verbose);
res->lastDesktop = 0; //undef
+ res->maxHorz = False;
+ res->maxVert = False;
+ res->isMapped = False;
}
unsigned long jogl_java_object_data[2]; // X11 is based on 'unsigned long'
int nitems_32 = putPtrIn32Long( jogl_java_object_data, (uintptr_t) res);
@@ -325,7 +315,6 @@ static void NewtWindows_setCWAbove(Display *dpy, Window w) {
memset(&xwc, 0, sizeof(XWindowChanges));
xwc.stack_mode = Above;
XConfigureWindow(dpy, w, CWStackMode, &xwc);
- XSync(dpy, False);
}
static Status NewtWindows_getWindowPositionRelative2Parent (Display *dpy, Window w, int *x_return, int *y_return) {
Window root_return;
@@ -413,8 +402,7 @@ static void NewtWindows_setDecorations (Display *dpy, JavaWindow *w, Bool decora
#ifdef DECOR_USE_EWMH
XChangeProperty( dpy, w->window, w->allAtoms[_NET_WM_WINDOW_TYPE_IDX], XA_ATOM, 32, PropModeReplace, (unsigned char *)&types, ntypes);
#endif
-
- XSync(dpy, False);
+ XFlush(dpy);
}
static Bool NewtWindows_hasDecorations (Display *dpy, JavaWindow * w) {
@@ -446,7 +434,6 @@ static void NewtWindows_requestFocus (Display *dpy, JavaWindow * jw, Bool force)
Window focus_return;
int revert_to_return;
- XSync(dpy, False);
XGetInputFocus(dpy, &focus_return, &revert_to_return);
DBG_PRINT( "X11: requestFocus dpy %p,win %p, force %d, hasFocus %d\n", dpy, (void*)jw->window, force, focus_return==jw->window);
@@ -461,16 +448,14 @@ static void NewtWindows_requestFocus (Display *dpy, JavaWindow * jw, Bool force)
XSetInputFocus(dpy, jw->window, RevertToParent, CurrentTime);
}
}
+ XFlush(dpy);
DBG_PRINT( "X11: requestFocus dpy %p,win %p, force %d - FIN\n", dpy, (void*)jw->window, force);
- XSync(dpy, False);
}
-Status NewtWindows_updateInsets(JNIEnv *env, Display *dpy, JavaWindow * w, int *left, int *right, int *top, int *bottom) {
+Bool NewtWindows_updateInsets(Display *dpy, JavaWindow * w, int *left, int *right, int *top, int *bottom) {
if(0 != NewtWindows_getFrameExtends(dpy, w, left, right, top, bottom)) {
- DBG_PRINT( "NewtWindows_updateInsets: insets by _NET_FRAME_EXTENTS [ l %d, r %d, t %d, b %d ]\n",
- *left, *right, *top, *bottom);
- (*env)->CallVoidMethod(env, w->jwindow, insetsChangedID, JNI_FALSE, *left, *right, *top, *bottom);
- return 1; // OK
+ DBG_PRINT( "NewtWindows_updateInsets: insets by _NET_FRAME_EXTENTS [ l %d, r %d, t %d, b %d ]\n", *left, *right, *top, *bottom);
+ return True; // OK
}
Bool hasDecor = NewtWindows_hasDecorations (dpy, w);
@@ -480,43 +465,23 @@ Status NewtWindows_updateInsets(JNIEnv *env, Display *dpy, JavaWindow * w, int *
Window parent = NewtWindows_getParent(dpy, w->window);
if(0 != NewtWindows_getWindowPositionRelative2Parent (dpy, parent, left, top)) {
*right = *left; *bottom = *top;
- DBG_PRINT( "NewtWindows_updateInsets: insets by parent position [ l %d, r %d, t %d, b %d ]\n",
- *left, *right, *top, *bottom);
- (*env)->CallVoidMethod(env, w->jwindow, insetsChangedID, JNI_FALSE, *left, *right, *top, *bottom);
- return 1; // OK
+ DBG_PRINT( "NewtWindows_updateInsets: insets by parent position [ l %d, r %d, t %d, b %d ]\n", *left, *right, *top, *bottom);
+ return True; // OK
}
}
DBG_PRINT( "NewtWindows_updateInsets: cannot determine insets - hasDecor %d\n", hasDecor);
- return 0; // Error
+ return False; // Error
}
-void NewtWindows_updateMinMaxSize(JNIEnv *env, Display *dpy, JavaWindow * w) {
- XSizeHints * xsh = XAllocSizeHints();
- long xsh_bits = 0;
- int min_width=-1, min_height=-1;
- int max_width=-1, max_height=-1;
- if( NULL != xsh ) {
- xsh->flags = 0;
- xsh->min_width=0;
- xsh->min_height=0;
- xsh->max_width=0;
- xsh->max_height=0;
- if( 0 != XGetWMNormalHints(dpy, w->window, xsh, &xsh_bits) ) {
- // OK
- if( 0 != ( xsh_bits & PMinSize ) ) {
- min_width = xsh->min_width;
- min_height = xsh->min_height;
- }
- if( 0 != ( xsh_bits & PMaxSize ) ) {
- max_width = xsh->max_width;
- max_height = xsh->max_height;
- }
- DBG_PRINT( "NewtWindows_updateMinMaxSize: XGetWMNormalHints 0x%X / 0x%X for window %p on display %p\n", xsh_bits, xsh->flags, (void*)w->window, dpy);
- (*env)->CallVoidMethod(env, w->jwindow, minMaxSizeChangedID, min_width, min_height, max_width, max_height);
- } else {
- DBG_PRINT( "NewtWindows_updateMinMaxSize: XGetWMNormalHints failed (0x%X / 0x%X) for window %p on display %p\n", xsh_bits, xsh->flags, (void*)w->window, dpy);
- }
- XFree(xsh);
+Bool NewtWindows_updateMaximized(Display *dpy, JavaWindow * w, uint32_t netWMState) {
+ Bool maxHorz = 0 != ( _MASK_NET_WM_STATE_MAXIMIZED_HORZ & netWMState ) ;
+ Bool maxVert = 0 != ( _MASK_NET_WM_STATE_MAXIMIZED_VERT & netWMState ) ;
+ if( w->maxHorz != maxHorz || w->maxVert != maxVert ) {
+ w->maxHorz = maxHorz;
+ w->maxVert = maxVert;
+ return True;
+ } else {
+ return False;
}
}
@@ -546,11 +511,20 @@ static void NewtWindows_setWindowTypeEWMH (Display *dpy, JavaWindow * w, int typ
} // else { }
if( 0 != types[0] ) {
XChangeProperty( dpy, w->window, w->allAtoms[_NET_WM_WINDOW_TYPE_IDX], XA_ATOM, 32, PropModeReplace, (unsigned char *)&types, 1);
- XSync(dpy, False);
+ XFlush(dpy);
+ }
+}
+
+void NewtWindows_setUrgency(Display *dpy, Window window, Bool enable) {
+ XWMHints wmh;
+ memset ( &wmh, 0, sizeof(wmh) );
+ if( enable ) {
+ wmh.flags = XUrgencyHint;
}
+ XSetWMHints(dpy, window, &wmh);
}
-static void NewtWindows_sendNET_WM_STATE(Display *dpy, Window root, JavaWindow *w, int prop1Idx, int prop2Idx, Bool enable) {
+void NewtWindows_sendNET_WM_STATE(Display *dpy, Window root, JavaWindow *w, int prop1Idx, int prop2Idx, Bool enable) {
XEvent xev;
int i=0;
@@ -671,12 +645,18 @@ static void NewtWindows_setStackingEWMHFlags (Display *dpy, Window root, JavaWin
XChangeProperty( dpy, w->window, w->allAtoms[_NET_WM_BYPASS_COMPOSITOR_IDX], XA_CARDINAL, 32, PropModeReplace, (unsigned char*)&value, 1);
}
} else if( changeMaxVert || changeMaxHorz ) {
+ if( changeMaxHorz ) {
+ w->maxHorz = enable;
+ }
+ if( changeMaxVert ) {
+ w->maxVert = enable;
+ }
NewtWindows_sendNET_WM_STATE(dpy, root, w,
- changeMaxVert ? _NET_WM_STATE_MAXIMIZED_VERT_IDX : 0,
changeMaxHorz ? _NET_WM_STATE_MAXIMIZED_HORZ_IDX : 0,
+ changeMaxVert ? _NET_WM_STATE_MAXIMIZED_VERT_IDX : 0,
enable);
}
- XSync(dpy, False);
+ XFlush(dpy);
DBG_PRINT( "X11: setStackingEWMHFlags ON %d, change[Sticky %d, Fullscreen %d, Above %d, Below %d, MaxV %d, MaxH %d]\n",
enable, changeSticky, changeFullscreen, changeAbove, changeBelow, changeMaxVert, changeMaxHorz);
}
@@ -691,35 +671,47 @@ static Bool WaitForUnmapNotify( Display *dpy, XEvent *event, XPointer arg ) {
static void NewtWindows_setVisible(Display *dpy, Window root, JavaWindow* jw, Bool visible, Bool useWM, Bool waitForNotify) {
XEvent event;
- if( !visible && useWM && 0 != ( _MASK_NET_WM_STATE_HIDDEN & jw->supportedAtoms ) ) {
- DBG_PRINT( "X11: setVisible -> %d, method: IconicState, wait %d, window %p\n", (int)visible, (int)waitForNotify, (void*)jw->window);
- // It has been experienced that UnmapNotify is not sent for child windows when using IconicState!
+ DBG_PRINT( "X11: setVisible -> %d, useWM: %d, wait %d, window %p\n", (int)visible, (int)useWM, (int)waitForNotify, (void*)jw->window);
+ if( useWM && jw->isMapped && 0 != ( _MASK_NET_WM_STATE_HIDDEN & jw->supportedAtoms ) ) {
+ // It has been experienced that MapNotify/UnmapNotify is not sent for windows when using NormalState/IconicState!
+ // See X11Display.c::Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessages0 case ConfigureNotify
+ // NewtWindows_sendNET_WM_STATE(dpy, root, jw, _NET_WM_STATE_DEMANDS_ATTENTION_IDX, 0, True);
+ // NewtWindows_setUrgency(dpy, jw->window, True);
XEvent xev;
memset ( &xev, 0, sizeof(xev) );
- xev.type = ClientMessage;
- xev.xclient.window = jw->window;
- xev.xclient.message_type = jw->allAtoms[_WM_CHANGE_STATE_IDX];
- xev.xclient.format = 32;
- xev.xclient.data.l[0] = IconicState;
- XSendEvent ( dpy, root, False, SubstructureNotifyMask | SubstructureRedirectMask, &xev );
- // NewtWindows_sendNET_WM_STATE(dpy, root, jw, _NET_WM_STATE_HIDDEN_IDX, 0, !visible);
- if(waitForNotify) {
- XIfEvent( dpy, &event, WaitForUnmapNotify, (XPointer) jw->window );
+ if( visible ) {
+ // NormalState does not work on some WMs (Gnome, KDE)
+ xev.type = ClientMessage;
+ xev.xclient.window = jw->window;
+ xev.xclient.message_type = jw->allAtoms[_NET_ACTIVE_WINDOW_IDX];
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = 1; //source indication for normal applications
+ xev.xclient.data.l[1] = CurrentTime;
+ XSendEvent ( dpy, root, False, SubstructureNotifyMask | SubstructureRedirectMask, &xev );
+ } else {
+ xev.type = ClientMessage;
+ xev.xclient.window = jw->window;
+ xev.xclient.message_type = jw->allAtoms[_WM_CHANGE_STATE_IDX];
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = IconicState;
+ XSendEvent ( dpy, root, False, SubstructureNotifyMask | SubstructureRedirectMask, &xev );
}
} else {
- DBG_PRINT( "X11: setVisible -> %d, method: Map/Unmap, wait %d, window %p\n", (int)visible, (int)waitForNotify, (void*)jw->window);
if( visible ) {
XMapRaised(dpy, jw->window);
if(waitForNotify) {
XIfEvent( dpy, &event, WaitForMapNotify, (XPointer) jw->window );
}
+ jw->isMapped=True;
} else {
XUnmapWindow(dpy, jw->window);
if(waitForNotify) {
XIfEvent( dpy, &event, WaitForUnmapNotify, (XPointer) jw->window );
}
+ jw->isMapped=False;
}
}
+ XFlush(dpy);
}
@@ -753,7 +745,7 @@ static void NewtWindows_setPosSize(Display *dpy, JavaWindow* w, jint x, jint y,
xwc.height=height;
}
XConfigureWindow(dpy, w->window, flags, &xwc);
- XSync(dpy, False);
+ XFlush(dpy);
}
}
@@ -840,24 +832,23 @@ JNIEXPORT jlongArray JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CreateWind
pVisualQuery=NULL;
}
- attrMask = ( CWBackingStore | CWBackingPlanes | CWBackingPixel | CWBackPixmap |
- CWBorderPixel | CWColormap | CWOverrideRedirect | CWEventMask ) ;
+ attrMask = ( CWBackingStore | CWBackingPlanes | CWBackingPixel |
+ CWBackPixmap | CWBackPixel | CWBorderPixel | CWColormap |
+ CWOverrideRedirect | CWEventMask ) ;
memset(&xswa, 0, sizeof(xswa));
- xswa.override_redirect = False; // use the window manager, always (default)
- xswa.border_pixel = 0;
- xswa.background_pixmap = None;
xswa.backing_store=NotUseful; /* NotUseful, WhenMapped, Always */
xswa.backing_planes=0; /* planes to be preserved if possible */
xswa.backing_pixel=0; /* value to use in restoring planes */
+ xswa.background_pixmap = None;
+ xswa.background_pixel = BlackPixel(dpy, scrn_idx);
+ xswa.border_pixel = 0;
+ xswa.colormap = XCreateColormap(dpy, windowParent, visual, AllocNone);
+ xswa.override_redirect = False; // use the window manager, always (default)
xswa.event_mask = X11_MOUSE_EVENT_MASK;
xswa.event_mask |= KeyPressMask | KeyReleaseMask ;
- xswa.event_mask |= FocusChangeMask | SubstructureNotifyMask | StructureNotifyMask | ExposureMask ;
-
- xswa.colormap = XCreateColormap(dpy,
- windowParent,
- visual,
- AllocNone);
+ xswa.event_mask |= FocusChangeMask | SubstructureNotifyMask | StructureNotifyMask | ExposureMask;
+ // xswa.event_mask |= VisibilityChangeMask;
{
int _x = x, _y = y; // pos for CreateWindow, might be tweaked
@@ -882,6 +873,7 @@ JNIEXPORT jlongArray JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CreateWind
NewtCommon_throwNewRuntimeException(env, "could not create Window, bail out!");
return 0;
}
+ // XClearWindow(dpy, window);
XSetWMProtocols(dpy, window, &wm_delete_atom, 1); // windowDeleteAtom
javaWindow = createJavaWindowProperty(env, dpy, root, window, javaObjectAtom, windowDeleteAtom, obj, verbose);
@@ -893,7 +885,8 @@ JNIEXPORT jlongArray JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CreateWind
// we can pre-map the window here to be able to gather the insets and position.
{
XEvent event;
- int left=0, right=0, top=0, bottom=0;
+ // insets: negative values are ignored
+ int left=-1, right=-1, top=-1, bottom=-1;
const unsigned char * pixelPtr = NULL;
// NOTE: MUST BE DIRECT BUFFER, since _NET_WM_ICON Atom uses buffer directly!
@@ -908,16 +901,20 @@ JNIEXPORT jlongArray JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CreateWind
XMapWindow(dpy, window);
XIfEvent( dpy, &event, WaitForMapNotify, (XPointer) window ); // wait to get proper insets values
-
- XSync(dpy, False);
+ javaWindow->isMapped=True;
if( JNI_FALSE == pixels_is_direct && NULL != pixelPtr ) {
(*env)->ReleasePrimitiveArrayCritical(env, pixels, (void*)pixelPtr, JNI_ABORT);
}
// send insets before visibility, allowing java code a proper sync point!
- NewtWindows_updateInsets(env, dpy, javaWindow, &left, &right, &top, &bottom);
- (*env)->CallVoidMethod(env, javaWindow->jwindow, visibleChangedID, JNI_FALSE, JNI_TRUE);
+ XSync(dpy, False);
+ if( NewtWindows_updateInsets(dpy, javaWindow, &left, &right, &top, &bottom) ) {
+ (*env)->CallVoidMethod(env, javaWindow->jwindow, insetsVisibleChangedID, JNI_FALSE, left, right, top, bottom, 1);
+ } else {
+ (*env)->CallVoidMethod(env, javaWindow->jwindow, visibleChangedID, JNI_FALSE, JNI_TRUE);
+ left=0; right=0; top=0; bottom=0;
+ }
if( TST_FLAG_IS_AUTOPOSITION(flags) ) {
// get position from WM
@@ -955,6 +952,7 @@ JNIEXPORT jlongArray JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CreateWind
NewtWindows_setMinMaxSize(dpy, javaWindow, width, height, width, height);
}
}
+ XFlush(dpy);
handles[0] = (jlong)(intptr_t)window;
handles[1] = (jlong)(intptr_t)javaWindow;
jhandles = (*env)->NewLongArray(env, 2);
@@ -968,6 +966,34 @@ JNIEXPORT jlongArray JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CreateWind
/*
* Class: jogamp_newt_driver_x11_WindowDriver
+ * Method: GetSupportedReconfigMask0
+ * Signature: (J)I
+ */
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_WindowDriver_GetSupportedReconfigMask0
+ (JNIEnv *env, jclass clazz, jlong javaWindow)
+{
+ JavaWindow * jw = (JavaWindow*)(intptr_t)javaWindow;
+ uint32_t supported = jw->supportedAtoms;
+ return
+ FLAG_IS_VISIBLE |
+ FLAG_IS_AUTOPOSITION |
+ FLAG_IS_CHILD |
+ FLAG_IS_FOCUSED |
+ FLAG_IS_UNDECORATED |
+ ( ( 0 != ( _MASK_NET_WM_STATE_ABOVE & supported ) ) ? FLAG_IS_ALWAYSONTOP : 0 ) |
+ ( ( 0 != ( _MASK_NET_WM_STATE_BELOW & supported ) ) ? FLAG_IS_ALWAYSONBOTTOM : 0 ) |
+ ( ( 0 != ( _MASK_NET_WM_DESKTOP & supported ) ) ? FLAG_IS_STICKY : 0 ) |
+ FLAG_IS_RESIZABLE |
+ ( ( 0 != ( _MASK_NET_WM_STATE_MAXIMIZED_VERT & supported ) ) ? FLAG_IS_MAXIMIZED_VERT : 0 ) |
+ ( ( 0 != ( _MASK_NET_WM_STATE_MAXIMIZED_HORZ & supported ) ) ? FLAG_IS_MAXIMIZED_HORZ : 0 ) |
+ FLAG_IS_FULLSCREEN |
+ FLAG_IS_POINTERVISIBLE |
+ FLAG_IS_POINTERCONFINED |
+ FLAG_IS_FULLSCREEN_SPAN;
+}
+
+/*
+ * Class: jogamp_newt_driver_x11_WindowDriver
* Method: CloseWindow
* Signature: (JJ)V
*/
@@ -1006,6 +1032,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CloseWindow0
XGetWindowAttributes(dpy, jw->window, &xwa); // prefetch colormap to be destroyed after window destruction
XSelectInput(dpy, jw->window, 0);
XUnmapWindow(dpy, jw->window);
+ jw->isMapped=False;
// Drain all events related to this window ..
Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessages0(env, obj, display,
@@ -1045,7 +1072,7 @@ static Bool WaitForReparentNotify( Display *dpy, XEvent *event, XPointer arg ) {
* Signature: (JIJJIIIII)V
*/
JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindow0
- (JNIEnv *env, jobject obj, jlong jdisplay, jint screen_index,
+ (JNIEnv *env, jclass clazz, jlong jdisplay, jint screen_index,
jlong jparent, jlong javaWindow,
jint x, jint y, jint width, jint height, jint flags)
{
@@ -1101,6 +1128,8 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo
TST_FLAG_CHANGE_STICKY(flags), TST_FLAG_IS_STICKY(flags),
fsEWMHFlags);
+ XSync(dpy, False);
+
// FS Note: To toggle FS, utilizing the _NET_WM_STATE_FULLSCREEN WM state should be enough.
// However, we have to consider other cases like reparenting and WM which don't support it.
#if 0 // Also doesn't work work properly w/ Unity WM
@@ -1142,8 +1171,9 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo
XReparentWindow( dpy, jw->window, parent, x, y ); // actual reparent call
#ifdef REPARENT_WAIT_FOR_REPARENT_NOTIFY
XIfEvent( dpy, &event, WaitForReparentNotify, (XPointer) jw->window );
+ #else
+ XSync(dpy, False);
#endif
- XSync(dpy, False);
XSetWMProtocols(dpy, jw->window, &wm_delete_atom, 1); // windowDeleteAtom
// Fix for Unity WM, i.e. _remove_ persistent previous states
NewtWindows_setStackingEWMHFlags(dpy, root, jw, fsEWMHFlags, False);
@@ -1185,10 +1215,12 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo
// CHILD: out -> in
DBG_PRINT( "X11: reconfigureWindow0 PARENTING out->in\n");
XReparentWindow( dpy, jw->window, parent, x, y ); // actual reparent call
+ XFlush(dpy);
#ifdef REPARENT_WAIT_FOR_REPARENT_NOTIFY
XIfEvent( dpy, &event, WaitForReparentNotify, (XPointer) jw->window );
+ #else
+ XSync(dpy, False);
#endif
- XSync(dpy, False);
}
if( tempInvisible ) {
@@ -1200,7 +1232,6 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo
if( TST_FLAG_IS_VISIBLE(flags) ) {
DBG_PRINT( "X11: reconfigureWindow0 VISIBLE ON\n");
NewtWindows_setVisible(dpy, root, jw, True /* visible */, useWM, False /* wait */);
- XSync(dpy, False);
if( !TST_FLAG_IS_MAXIMIZED_ANY(flags) ) {
// WM may disregard pos/size XConfigureWindow requests for invisible windows!
DBG_PRINT( "X11: reconfigureWindow0 setPosSize.2 %d/%d %dx%d\n", x, y, width, height);
@@ -1209,7 +1240,6 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo
} else {
DBG_PRINT( "X11: reconfigureWindow0 VISIBLE OFF\n");
NewtWindows_setVisible(dpy, root, jw, False /* visible */, useWM, False /* wait */);
- XSync(dpy, False);
}
}
@@ -1230,6 +1260,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo
NewtWindows_setMinMaxSize(dpy, jw, -1, -1, -1, -1); // FIXME: ..
}
}
+ XFlush(dpy);
DBG_PRINT( "X11: reconfigureWindow0 X (full)\n");
}
@@ -1239,9 +1270,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo
* Signature: (JJZ)V
*/
JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_requestFocus0
- (JNIEnv *env, jobject obj, jlong display, jlong javaWindow, jboolean force)
+ (JNIEnv *env, jclass clazz, jlong display, jlong javaWindow, jboolean force)
{
- NewtWindows_requestFocus ( (Display *) (intptr_t) display, (JavaWindow*)(intptr_t)javaWindow, JNI_TRUE==force?True:False ) ;
+ Display * dpy = (Display *) (intptr_t) display;
+ XSync(dpy, False);
+ NewtWindows_requestFocus ( dpy, (JavaWindow*)(intptr_t)javaWindow, JNI_TRUE==force?True:False ) ;
}
/*
diff --git a/src/oculusvr/classes/com/jogamp/oculusvr/OVRDynamicLibraryBundleInfo.java b/src/oculusvr/classes/com/jogamp/oculusvr/OVRDynamicLibraryBundleInfo.java
index 86041b35d..cd79409e5 100644
--- a/src/oculusvr/classes/com/jogamp/oculusvr/OVRDynamicLibraryBundleInfo.java
+++ b/src/oculusvr/classes/com/jogamp/oculusvr/OVRDynamicLibraryBundleInfo.java
@@ -85,6 +85,16 @@ import java.util.*;
}
@Override
+ public final boolean searchToolLibInSystemPath() {
+ return true;
+ }
+
+ @Override
+ public final boolean searchToolLibSystemPathFirst() {
+ return true;
+ }
+
+ @Override
public final List<List<String>> getToolLibNames() {
return new ArrayList<List<String>>(); // None
}
diff --git a/src/test/com/jogamp/opengl/test/android/NEWTGearsES2Activity.java b/src/test/com/jogamp/opengl/test/android/NEWTGearsES2Activity.java
index e4fabbbcc..eff2aae49 100644
--- a/src/test/com/jogamp/opengl/test/android/NEWTGearsES2Activity.java
+++ b/src/test/com/jogamp/opengl/test/android/NEWTGearsES2Activity.java
@@ -36,6 +36,7 @@ import com.jogamp.opengl.GLProfile;
import jogamp.newt.driver.android.NewtBaseActivity;
+import com.jogamp.common.util.InterruptSource;
import com.jogamp.newt.event.MonitorEvent;
import com.jogamp.newt.event.MouseAdapter;
import com.jogamp.newt.event.MouseEvent;
@@ -90,7 +91,7 @@ public class NEWTGearsES2Activity extends NewtBaseActivity {
public void mousePressed(final MouseEvent e) {
if( e.getPointerCount() == 3 ) {
Log.d(TAG, "MemoryHog");
- new Thread(new Runnable() {
+ new InterruptSource.Thread(null, new Runnable() {
public void run() {
final ArrayList<Buffer> buffers = new ArrayList<Buffer>();
while(true) {
diff --git a/src/test/com/jogamp/opengl/test/bugs/Bug735Inv0AppletAWT.java b/src/test/com/jogamp/opengl/test/bugs/Bug735Inv0AppletAWT.java
index 89d28c08d..7430dcd38 100644
--- a/src/test/com/jogamp/opengl/test/bugs/Bug735Inv0AppletAWT.java
+++ b/src/test/com/jogamp/opengl/test/bugs/Bug735Inv0AppletAWT.java
@@ -27,7 +27,7 @@ import com.jogamp.opengl.GLRunnable;
import com.jogamp.opengl.GLUniformData;
import com.jogamp.opengl.awt.GLCanvas;
import com.jogamp.opengl.glu.GLU;
-
+import com.jogamp.common.util.InterruptSource;
import com.jogamp.newt.awt.NewtCanvasAWT;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.test.junit.jogl.demos.es2.LandscapeES2;
@@ -98,7 +98,7 @@ public class Bug735Inv0AppletAWT extends Applet implements Runnable {
}
public void start() {
- thread = new Thread(this, "Animation Thread");
+ thread = new InterruptSource.Thread(null, this, "Animation Thread");
thread.start();
}
diff --git a/src/test/com/jogamp/opengl/test/bugs/Bug735Inv1AppletAWT.java b/src/test/com/jogamp/opengl/test/bugs/Bug735Inv1AppletAWT.java
index 5019391ad..b31a5f410 100644
--- a/src/test/com/jogamp/opengl/test/bugs/Bug735Inv1AppletAWT.java
+++ b/src/test/com/jogamp/opengl/test/bugs/Bug735Inv1AppletAWT.java
@@ -27,7 +27,7 @@ import com.jogamp.opengl.GLRunnable;
import com.jogamp.opengl.GLUniformData;
import com.jogamp.opengl.awt.GLCanvas;
import com.jogamp.opengl.glu.GLU;
-
+import com.jogamp.common.util.InterruptSource;
import com.jogamp.newt.awt.NewtCanvasAWT;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.test.junit.jogl.demos.es2.LandscapeES2;
@@ -100,7 +100,7 @@ public class Bug735Inv1AppletAWT extends Applet implements Runnable {
}
public void start() {
- thread = new Thread(this, "Animation Thread");
+ thread = new InterruptSource.Thread(null, this, "Animation Thread");
thread.start();
}
diff --git a/src/test/com/jogamp/opengl/test/bugs/Bug735Inv2AppletAWT.java b/src/test/com/jogamp/opengl/test/bugs/Bug735Inv2AppletAWT.java
index 1228f1453..d0e4448cc 100644
--- a/src/test/com/jogamp/opengl/test/bugs/Bug735Inv2AppletAWT.java
+++ b/src/test/com/jogamp/opengl/test/bugs/Bug735Inv2AppletAWT.java
@@ -20,7 +20,8 @@ import com.jogamp.opengl.GLCapabilities;
import com.jogamp.opengl.GLEventListener;
import com.jogamp.opengl.GLProfile;
import com.jogamp.opengl.awt.GLCanvas;
-
+import com.jogamp.common.util.InterruptSource;
+import com.jogamp.junit.util.JunitTracer;
import com.jogamp.newt.awt.NewtCanvasAWT;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.test.junit.jogl.demos.es2.LandscapeES2;
@@ -82,7 +83,7 @@ public class Bug735Inv2AppletAWT extends Applet implements Runnable {
public void start() {
initDraw();
- thread = new Thread(this, "Animation Thread");
+ thread = new InterruptSource.Thread(null, this, "Animation Thread");
thread.start();
}
@@ -219,7 +220,7 @@ public class Bug735Inv2AppletAWT extends Applet implements Runnable {
System.err.println("swapInterval "+SWAP_INTERVAL);
System.err.println("exclusiveContext "+USE_ECT);
if(waitForKey) {
- UITestCase.waitForKey("Start");
+ JunitTracer.waitForKey("Start");
}
final GraphicsEnvironment environment =
diff --git a/src/test/com/jogamp/opengl/test/bugs/Issue344Base.java b/src/test/com/jogamp/opengl/test/bugs/Issue344Base.java
index 184a2ef0f..7532ca6db 100644
--- a/src/test/com/jogamp/opengl/test/bugs/Issue344Base.java
+++ b/src/test/com/jogamp/opengl/test/bugs/Issue344Base.java
@@ -6,6 +6,7 @@ import java.awt.Frame;
import java.awt.event.*;
import java.awt.geom.*;
+import com.jogamp.common.util.InterruptSource;
import com.jogamp.opengl.GL;
import com.jogamp.opengl.GL2;
import com.jogamp.opengl.GLAutoDrawable;
@@ -49,7 +50,7 @@ public abstract class Issue344Base implements GLEventListener
frame.setSize(512, 512);
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(final WindowEvent e) {
- new Thread(new Runnable() {
+ new InterruptSource.Thread(null, new Runnable() {
public void run() {
System.exit(0);
}
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/FontSet01.java b/src/test/com/jogamp/opengl/test/junit/graph/FontSet01.java
index 0666ec4db..38eda9adf 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/FontSet01.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/FontSet01.java
@@ -14,22 +14,22 @@ public class FontSet01 {
fonts[i++] = FontFactory.get(FontFactory.UBUNTU).getDefault(); // FontSet.FAMILY_REGULAR, FontSet.STYLE_NONE
fonts[i++] = FontFactory.get(FontFactory.UBUNTU).get(FontSet.FAMILY_REGULAR, FontSet.STYLE_ITALIC);
fonts[i++] = FontFactory.get(FontFactory.UBUNTU).get(FontSet.FAMILY_REGULAR, FontSet.STYLE_BOLD);
- fonts[i++] = FontFactory.get(IOUtil.getResource(TestTextRendererNEWTBugXXXX.class,
- "fonts/freefont/FreeMono.ttf").getInputStream(), true);
- fonts[i++] = FontFactory.get(IOUtil.getResource(TestTextRendererNEWTBugXXXX.class,
- "fonts/freefont/FreeMonoBold.ttf").getInputStream(), true);
- fonts[i++] = FontFactory.get(IOUtil.getResource(TestTextRendererNEWTBugXXXX.class,
- "fonts/freefont/FreeSans.ttf").getInputStream(), true);
- fonts[i++] = FontFactory.get(IOUtil.getResource(TestTextRendererNEWTBugXXXX.class,
- "fonts/freefont/FreeSansBold.ttf").getInputStream(), true);
- fonts[i++] = FontFactory.get(IOUtil.getResource(TestTextRendererNEWTBugXXXX.class,
- "fonts/freefont/FreeSerif.ttf").getInputStream(), true);
- fonts[i++] = FontFactory.get(IOUtil.getResource(TestTextRendererNEWTBugXXXX.class,
- "fonts/freefont/FreeSerifBold.ttf").getInputStream(), true);
- fonts[i++] = FontFactory.get(IOUtil.getResource(TestTextRendererNEWTBugXXXX.class,
- "fonts/freefont/FreeSerifBoldItalic.ttf").getInputStream(), true);
- fonts[i++] = FontFactory.get(IOUtil.getResource(TestTextRendererNEWTBugXXXX.class,
- "fonts/freefont/FreeSerifItalic.ttf").getInputStream(), true);
+ fonts[i++] = FontFactory.get(IOUtil.getResource("fonts/freefont/FreeMono.ttf",
+ TestTextRendererNEWTBugXXXX.class.getClassLoader(), TestTextRendererNEWTBugXXXX.class).getInputStream(), true);
+ fonts[i++] = FontFactory.get(IOUtil.getResource("fonts/freefont/FreeMonoBold.ttf",
+ TestTextRendererNEWTBugXXXX.class.getClassLoader(), TestTextRendererNEWTBugXXXX.class).getInputStream(), true);
+ fonts[i++] = FontFactory.get(IOUtil.getResource("fonts/freefont/FreeSans.ttf",
+ TestTextRendererNEWTBugXXXX.class.getClassLoader(), TestTextRendererNEWTBugXXXX.class).getInputStream(), true);
+ fonts[i++] = FontFactory.get(IOUtil.getResource("fonts/freefont/FreeSansBold.ttf",
+ TestTextRendererNEWTBugXXXX.class.getClassLoader(), TestTextRendererNEWTBugXXXX.class).getInputStream(), true);
+ fonts[i++] = FontFactory.get(IOUtil.getResource("fonts/freefont/FreeSerif.ttf",
+ TestTextRendererNEWTBugXXXX.class.getClassLoader(), TestTextRendererNEWTBugXXXX.class).getInputStream(), true);
+ fonts[i++] = FontFactory.get(IOUtil.getResource("fonts/freefont/FreeSerifBold.ttf",
+ TestTextRendererNEWTBugXXXX.class.getClassLoader(), TestTextRendererNEWTBugXXXX.class).getInputStream(), true);
+ fonts[i++] = FontFactory.get(IOUtil.getResource("fonts/freefont/FreeSerifBoldItalic.ttf",
+ TestTextRendererNEWTBugXXXX.class.getClassLoader(), TestTextRendererNEWTBugXXXX.class).getInputStream(), true);
+ fonts[i++] = FontFactory.get(IOUtil.getResource("fonts/freefont/FreeSerifItalic.ttf",
+ TestTextRendererNEWTBugXXXX.class.getClassLoader(), TestTextRendererNEWTBugXXXX.class).getInputStream(), true);
return fonts;
}
}
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT00.java b/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT00.java
index 86b129fe1..36e263f78 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT00.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT00.java
@@ -54,6 +54,7 @@ import com.jogamp.graph.curve.opengl.RenderState;
import com.jogamp.graph.font.Font;
import com.jogamp.graph.font.FontFactory;
import com.jogamp.graph.geom.SVertex;
+import com.jogamp.junit.util.JunitTracer;
import com.jogamp.newt.Window;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.test.junit.util.MiscUtils;
@@ -73,7 +74,7 @@ public class TestTextRendererNEWT00 extends UITestCase {
static int GraphVBAASamples = 0;
static int GraphMSAASamples = 0;
static boolean ManualTest = false;
- static int SwapInterval = 0;
+ static int SwapInterval = 1;
static String fontFileName = null;
static URL fontURL = null;
@@ -213,7 +214,7 @@ public class TestTextRendererNEWT00 extends UITestCase {
window.display();
System.err.println("Chosen: "+window.getChosenGLCapabilities());
if( WaitStartEnd ) {
- UITestCase.waitForKey("Start");
+ JunitTracer.waitForKey("Start");
}
final RenderState rs = RenderState.createRenderState(SVertex.factory());
@@ -252,7 +253,7 @@ public class TestTextRendererNEWT00 extends UITestCase {
});
anim.stop();
if( WaitStartEnd ) {
- UITestCase.waitForKey("Stop");
+ JunitTracer.waitForKey("Stop");
}
destroyWindow(window);
}
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT10.java b/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT10.java
index 4e66f6920..37d457057 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT10.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT10.java
@@ -102,7 +102,7 @@ public class TestTextRendererNEWT10 extends UITestCase {
forceGL3 = true;
} else if(args[i].equals("-font")) {
i++;
- font = FontFactory.get(IOUtil.getResource(TestTextRendererNEWT10.class, args[i]).getInputStream(), true);
+ font = FontFactory.get(IOUtil.getResource(args[i], TestTextRendererNEWT10.class.getClassLoader(), TestTextRendererNEWT10.class).getInputStream(), true);
} else if(args[i].equals("-fontSize")) {
i++;
fontSize = MiscUtils.atof(args[i], fontSize);
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURendererListenerBase01.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURendererListenerBase01.java
index 73b76debb..2d3b0664e 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURendererListenerBase01.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURendererListenerBase01.java
@@ -47,6 +47,7 @@ import com.jogamp.graph.curve.Region;
import com.jogamp.graph.curve.opengl.GLRegion;
import com.jogamp.graph.curve.opengl.RegionRenderer;
import com.jogamp.graph.curve.opengl.RenderState;
+import com.jogamp.newt.Window;
import com.jogamp.newt.event.KeyEvent;
import com.jogamp.newt.event.KeyListener;
import com.jogamp.newt.opengl.GLWindow;
@@ -121,6 +122,17 @@ public abstract class GPURendererListenerBase01 implements GLEventListener {
@Override
public void init(final GLAutoDrawable drawable) {
+ final Object upObj = drawable.getUpstreamWidget();
+ if( upObj instanceof Window ) {
+ final Window window = (Window) upObj;
+ final float[] sDPI = window.getPixelsPerMM(new float[2]);
+ sDPI[0] *= 25.4f;
+ sDPI[1] *= 25.4f;
+ System.err.println("DPI "+sDPI[0]+" x "+sDPI[1]);
+
+ final float[] hasSurfacePixelScale1 = window.getCurrentSurfaceScale(new float[2]);
+ System.err.println("HiDPI PixelScale: "+hasSurfacePixelScale1[0]+"x"+hasSurfacePixelScale1[1]+" (has)");
+ }
autoDrawable = drawable;
GL2ES2 gl = drawable.getGL().getGL2ES2();
if(debug) {
@@ -302,9 +314,16 @@ public abstract class GPURendererListenerBase01 implements GLEventListener {
@Override
public boolean run(final GLAutoDrawable drawable) {
final GL gl = drawable.getGL();
- int i = gl.getSwapInterval();
- i = i==0 ? 1 : 0;
+ final int _i = gl.getSwapInterval();
+ final int i;
+ switch(_i) {
+ case 0: i = -1; break;
+ case -1: i = 1; break;
+ case 1: i = 0; break;
+ default: i = 1; break;
+ }
gl.setSwapInterval(i);
+
final GLAnimatorControl a = drawable.getAnimator();
if( null != a ) {
a.resetFPSCounter();
@@ -312,7 +331,7 @@ public abstract class GPURendererListenerBase01 implements GLEventListener {
if(drawable instanceof FPSCounter) {
((FPSCounter)drawable).resetFPSCounter();
}
- System.err.println("Swap Interval: "+i);
+ System.err.println("Swap Interval: "+_i+" -> "+i+" -> "+gl.getSwapInterval());
return true;
}
});
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextGLListener0A.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextGLListener0A.java
index f7e779cd3..bf0a907b0 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextGLListener0A.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextGLListener0A.java
@@ -34,7 +34,6 @@ import com.jogamp.opengl.GLAutoDrawable;
import com.jogamp.graph.curve.Region;
import com.jogamp.graph.curve.opengl.RenderState;
-import com.jogamp.graph.curve.opengl.RegionRenderer;
import com.jogamp.graph.geom.SVertex;
import com.jogamp.newt.opengl.GLWindow;
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextRendererListenerBase01.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextRendererListenerBase01.java
index c648708d4..945204052 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextRendererListenerBase01.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextRendererListenerBase01.java
@@ -165,9 +165,14 @@ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerB
super.init(drawable);
final Object upObj = drawable.getUpstreamWidget();
if( upObj instanceof Window ) {
- final float[] pixelsPerMM = new float[2];
- ((Window)upObj).getPixelsPerMM(pixelsPerMM);
- dpiH = pixelsPerMM[1]*25.4f;
+ final Window window = (Window) upObj;
+ final float[] sDPI = window.getPixelsPerMM(new float[2]);
+ sDPI[0] *= 25.4f;
+ sDPI[1] *= 25.4f;
+ dpiH = sDPI[1];
+ System.err.println("Using screen DPI of "+dpiH);
+ } else {
+ System.err.println("Using default DPI of "+dpiH);
}
fontNameBox = font.getMetricBounds(fontName, font.getPixelSize(fontSizeFName, dpiH));
switchHeadBox();
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUUISceneGLListener0A.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUUISceneGLListener0A.java
index 4bb72bbd2..33b7e2787 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUUISceneGLListener0A.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUUISceneGLListener0A.java
@@ -16,6 +16,7 @@ import com.jogamp.opengl.GLPipelineFactory;
import com.jogamp.opengl.GLRunnable;
import com.jogamp.common.net.Uri;
+import com.jogamp.common.util.InterruptSource;
import com.jogamp.graph.curve.Region;
import com.jogamp.graph.curve.opengl.RegionRenderer;
import com.jogamp.graph.curve.opengl.RenderState;
@@ -354,7 +355,7 @@ public class GPUUISceneGLListener0A implements GLEventListener {
button.addMouseListener(new UIShape.MouseGestureAdapter() {
@Override
public void mouseClicked(final MouseEvent e) {
- new Thread() {
+ new InterruptSource.Thread() {
public void run() {
if( null != cDrawable ) {
final GLAnimatorControl actrl = cDrawable.getAnimator();
@@ -521,6 +522,7 @@ public class GPUUISceneGLListener0A implements GLEventListener {
mPlayer.setTextureUnit(texUnitMediaPlayer);
final MediaPlayerButton mPlayerButton = new MediaPlayerButton(renderer.getRenderState().getVertexFactory(), renderModes,
button2XSize, button2YSize, mPlayer);
+ mPlayerButton.setVerbose(true);
mPlayerButton.addDefaultEventListener();
mPlayerButton.translate(xStartRight, yStartTop - diffY*1, 0f);
mPlayerButton.setToggleable(true);
@@ -665,14 +667,17 @@ public class GPUUISceneGLListener0A implements GLEventListener {
if( upObj instanceof Window ) {
final Window upWin = (Window)upObj;
final MonitorDevice mm = upWin.getMainMonitor();
- final float[] monitorPixelsPerMM = mm.getPixelsPerMM(new float[2]);
- final float monitorDpiH = monitorPixelsPerMM[1]*25.4f;
- final float[] surfacePixelsPerMM = upWin.getPixelsPerMM(new float[2]);
- dpiH = surfacePixelsPerMM[1]*25.4f;
+ final float[] monitorDPI = mm.getPixelsPerMM(new float[2]);
+ monitorDPI[0] *= 25.4f;
+ monitorDPI[1] *= 25.4f;
+ final float[] sDPI = upWin.getPixelsPerMM(new float[2]);
+ sDPI[0] *= 25.4f;
+ sDPI[1] *= 25.4f;
+ dpiH = sDPI[1];
System.err.println("Monitor detected: "+mm);
- System.err.println("Monitor dpi: "+monitorDpiH);
+ System.err.println("Monitor dpi: "+monitorDPI[0]+" x "+monitorDPI[1]);
System.err.println("Surface scale: native "+Arrays.toString(upWin.getMaximumSurfaceScale(new float[2]))+", current "+Arrays.toString(upWin.getCurrentSurfaceScale(new float[2])));
- System.err.println("Surface dpi: "+dpiH);
+ System.err.println("Surface dpi "+sDPI[0]+" x "+sDPI[1]);
} else {
System.err.println("Using default DPI of "+dpiH);
}
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUUISceneNewtCanvasAWTDemo.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUUISceneNewtCanvasAWTDemo.java
index 8b5b70239..721fe9cb0 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUUISceneNewtCanvasAWTDemo.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUUISceneNewtCanvasAWTDemo.java
@@ -180,10 +180,6 @@ public class GPUUISceneNewtCanvasAWTDemo {
frame.setVisible(true);
}
});
- final float[] hasSurfacePixelScale1 = window.getCurrentSurfaceScale(new float[2]);
- System.err.println("HiDPI PixelScale: "+reqSurfacePixelScale[0]+"x"+reqSurfacePixelScale[1]+" (req) -> "+
- valReqSurfacePixelScale[0]+"x"+valReqSurfacePixelScale[1]+" (val) -> "+
- hasSurfacePixelScale1[0]+"x"+hasSurfacePixelScale1[1]+" (has)");
animator.start();
}
}
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUUISceneNewtDemo.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUUISceneNewtDemo.java
index aa6dd00cc..3053ed40a 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUUISceneNewtDemo.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUUISceneNewtDemo.java
@@ -145,10 +145,6 @@ public class GPUUISceneNewtDemo {
});
window.setVisible(true);
- final float[] hasSurfacePixelScale1 = window.getCurrentSurfaceScale(new float[2]);
- System.err.println("HiDPI PixelScale: "+reqSurfacePixelScale[0]+"x"+reqSurfacePixelScale[1]+" (req) -> "+
- valReqSurfacePixelScale[0]+"x"+valReqSurfacePixelScale[1]+" (val) -> "+
- hasSurfacePixelScale1[0]+"x"+hasSurfacePixelScale1[1]+" (has)");
animator.start();
}
}
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/MediaPlayerButton.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/MediaPlayerButton.java
index bdde61ad9..44e2c6034 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/MediaPlayerButton.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/MediaPlayerButton.java
@@ -28,7 +28,7 @@
package com.jogamp.opengl.test.junit.graph.demos.ui;
import com.jogamp.opengl.GL2ES2;
-
+import com.jogamp.common.util.InterruptSource;
import com.jogamp.graph.curve.opengl.RegionRenderer;
import com.jogamp.graph.geom.Vertex;
import com.jogamp.graph.geom.Vertex.Factory;
@@ -41,7 +41,7 @@ import com.jogamp.opengl.util.texture.TextureSequence.TextureFrame;
* GPU based resolution independent {@link GLMediaPlayer} Button impl
*/
public class MediaPlayerButton extends TextureSeqButton {
- public boolean verbose = false;
+ private boolean verbose = false;
/**
* @param factory
@@ -62,6 +62,8 @@ public class MediaPlayerButton extends TextureSeqButton {
setEnabled(false); // data and shader n/a yet
}
+ public void setVerbose(final boolean v) { verbose = v; }
+
/**
* Add the default {@link GLMediaEventListener} to {@link #getGLMediaPlayer() this class's GLMediaPlayer}.
*/
@@ -91,7 +93,7 @@ public class MediaPlayerButton extends TextureSeqButton {
// FIXME: mPlayer.resetGLState();
}
if( 0 != ( GLMediaEventListener.EVENT_CHANGE_EOS & event_mask ) ) {
- new Thread() {
+ new InterruptSource.Thread() {
public void run() {
// loop for-ever ..
mPlayer.seek(0);
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIListenerBase01.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIListenerBase01.java
index 2e3d2fac3..ab5bfb926 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIListenerBase01.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIListenerBase01.java
@@ -32,6 +32,7 @@ import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
+import com.jogamp.opengl.FPSCounter;
import com.jogamp.opengl.GL;
import com.jogamp.opengl.GL2ES2;
import com.jogamp.opengl.GLAnimatorControl;
@@ -285,16 +286,27 @@ public abstract class UIListenerBase01 implements GLEventListener {
else if(arg0.getKeyCode() == KeyEvent.VK_V) {
if(null != autoDrawable) {
autoDrawable.invoke(false, new GLRunnable() {
+ @Override
public boolean run(final GLAutoDrawable drawable) {
final GL gl = drawable.getGL();
- int i = gl.getSwapInterval();
- i = i==0 ? 1 : 0;
+ final int _i = gl.getSwapInterval();
+ final int i;
+ switch(_i) {
+ case 0: i = 1; break;
+ case 1: i = -1; break;
+ case -1: i = 0; break;
+ default: i = 1; break;
+ }
gl.setSwapInterval(i);
+
final GLAnimatorControl a = drawable.getAnimator();
if( null != a ) {
a.resetFPSCounter();
}
- System.err.println("Swap Interval: "+i);
+ if(drawable instanceof FPSCounter) {
+ ((FPSCounter)drawable).resetFPSCounter();
+ }
+ System.err.println("Swap Interval: "+_i+" -> "+i+" -> "+gl.getSwapInterval());
return true;
}
});
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/GLProfile0XBase.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/GLProfile0XBase.java
index 7fd3488ba..75d588f8e 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/GLProfile0XBase.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/GLProfile0XBase.java
@@ -43,6 +43,7 @@ import org.junit.FixMethodOrder;
import org.junit.runners.MethodSorters;
import com.jogamp.common.os.Platform;
+import com.jogamp.common.util.PropertyAccess;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.JoglVersion;
import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
@@ -915,7 +916,7 @@ public abstract class GLProfile0XBase extends UITestCase {
Thread.sleep(100);
// Same definition as in GLProfile for 'disableOpenGLARBContext'
final boolean isOSX = Platform.OSType.MACOS == Platform.getOSType();
- final boolean disableOpenGLARBContext = null != System.getProperty("jogl.disable.openglarbcontext") && !isOSX;
+ final boolean disableOpenGLARBContext = PropertyAccess.isPropertyDefined("jogl.disable.openglarbcontext", true) && !isOSX;
if( disableOpenGLARBContext ) {
Assert.assertFalse("Property 'jogl.disable.openglarbcontext' set, but created w/ ARB",
glad.getContext().isCreatedWithARBMethod());
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/InitConcurrentBaseNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/InitConcurrentBaseNEWT.java
index 3379129dd..7a5b49168 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/InitConcurrentBaseNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/InitConcurrentBaseNEWT.java
@@ -28,6 +28,8 @@
package com.jogamp.opengl.test.junit.jogl.acore;
+import com.jogamp.common.util.InterruptSource;
+import com.jogamp.common.util.InterruptedRuntimeException;
import com.jogamp.nativewindow.Capabilities;
import com.jogamp.nativewindow.util.InsetsImmutable;
import com.jogamp.opengl.GLCapabilities;
@@ -194,11 +196,11 @@ public abstract class InitConcurrentBaseNEWT extends UITestCase {
final String currentThreadName = Thread.currentThread().getName();
final Object syncDone = new Object();
final JOGLTask[] tasks = new JOGLTask[num];
- final Thread[] threads = new Thread[num];
+ final InterruptSource.Thread[] threads = new InterruptSource.Thread[num];
int i;
for(i=0; i<num; i++) {
tasks[i] = new JOGLTask(syncDone, i, reuse);
- threads[i] = new Thread(tasks[i], currentThreadName+"-jt"+i);
+ threads[i] = new InterruptSource.Thread(null, tasks[i], currentThreadName+"-jt"+i);
}
final long t0 = System.currentTimeMillis();
@@ -211,7 +213,7 @@ public abstract class InitConcurrentBaseNEWT extends UITestCase {
try {
syncDone.wait(500);
} catch (final InterruptedException e) {
- throw new RuntimeException(e);
+ throw new InterruptedRuntimeException(e);
}
System.err.println(i+": "+doneDump(tasks));
i++;
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestBug1146GLContextDialogToolTipAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestBug1146GLContextDialogToolTipAWT.java
index 42646c07e..a736a481a 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestBug1146GLContextDialogToolTipAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestBug1146GLContextDialogToolTipAWT.java
@@ -52,6 +52,7 @@ import org.junit.Test;
import org.junit.runners.MethodSorters;
import com.jogamp.common.os.Platform;
+import com.jogamp.common.util.InterruptSource;
import com.jogamp.opengl.GLCapabilities;
import com.jogamp.opengl.GLCapabilitiesImmutable;
import com.jogamp.opengl.GLProfile;
@@ -127,7 +128,7 @@ public class TestBug1146GLContextDialogToolTipAWT extends UITestCase {
final String cancelButtonText = UIManager.getString("FileChooser.cancelButtonText",l);
// launch robot action ..
- new Thread()
+ new InterruptSource.Thread()
{
public void run()
{
@@ -161,7 +162,7 @@ public class TestBug1146GLContextDialogToolTipAWT extends UITestCase {
// hover to 'approve' -> tool tip
if( null != approveButtonPos ) {
AWTRobotUtil.mouseMove(robot, approveButtonPos, MOVE_ITER, MOVE_DELAY);
- Thread.sleep(TOOLTIP_WAIT);
+ java.lang.Thread.sleep(TOOLTIP_WAIT);
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOAutoDrawableDeadlockAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOAutoDrawableDeadlockAWT.java
index fd012e86f..a034f9c8a 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOAutoDrawableDeadlockAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOAutoDrawableDeadlockAWT.java
@@ -44,6 +44,7 @@ import org.junit.Test;
import org.junit.FixMethodOrder;
import org.junit.runners.MethodSorters;
+import com.jogamp.common.util.InterruptSource;
import com.jogamp.common.util.RunnableTask;
import com.jogamp.opengl.test.junit.util.UITestCase;
@@ -83,7 +84,7 @@ public class TestFBOAutoDrawableDeadlockAWT extends UITestCase {
System.err.println("BB.0: "+rTask.getSyncObject());
synchronized (rTask.getSyncObject()) {
System.err.println("BB.1: "+rTask.getSyncObject());
- new Thread(rTask, Thread.currentThread().getName()+"-Pbuffer_Creation").start();
+ new InterruptSource.Thread(null, rTask, Thread.currentThread().getName()+"-Pbuffer_Creation").start();
try {
System.err.println("BB.2");
rTask.getSyncObject().wait();
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 f2e8b86af..d8900b44e 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
@@ -32,6 +32,7 @@ import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
+import com.jogamp.common.util.InterruptSource;
import com.jogamp.newt.event.KeyAdapter;
import com.jogamp.newt.event.KeyEvent;
import com.jogamp.newt.event.WindowEvent;
@@ -114,7 +115,7 @@ public class TestFBOMix2DemosES2NEWT extends UITestCase {
if( 3 == c ) {
demo.setMSAA(4);
} else if( 6 == c ) {
- new Thread() {
+ new InterruptSource.Thread() {
@Override
public void run() {
glWindow.setSize(dw+64, dh+64);
@@ -124,14 +125,14 @@ public class TestFBOMix2DemosES2NEWT extends UITestCase {
} else if( 12 == c ) {
demo.setMSAA(0);
} else if( 15 == c ) {
- new Thread() {
+ new InterruptSource.Thread() {
@Override
public void run() {
glWindow.setSize(dw+128, dh+128);
} }.start();
} else if( 18 == c ) {
c=0;
- new Thread() {
+ new InterruptSource.Thread() {
@Override
public void run() {
glWindow.setSize(dw+256, dh+256);
@@ -167,7 +168,7 @@ public class TestFBOMix2DemosES2NEWT extends UITestCase {
}
System.err.println("*** "+e);
if(e.getKeyChar()=='f') {
- new Thread() {
+ new InterruptSource.Thread() {
public void run() {
System.err.println("[set fullscreen pre]: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getSurfaceWidth()+"x"+glWindow.getSurfaceHeight()+", f "+glWindow.isFullscreen()+", a "+glWindow.isAlwaysOnTop()+", "+glWindow.getInsets());
glWindow.setFullscreen(!glWindow.isFullscreen());
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOOffThreadSharedContextMix2DemosES2NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOOffThreadSharedContextMix2DemosES2NEWT.java
index 26d510a45..6c1e4b812 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOOffThreadSharedContextMix2DemosES2NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOOffThreadSharedContextMix2DemosES2NEWT.java
@@ -48,7 +48,7 @@ import com.jogamp.opengl.test.junit.jogl.demos.GLFinishOnDisplay;
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.common.util.InterruptSource;
import com.jogamp.nativewindow.NativeSurface;
import com.jogamp.nativewindow.SurfaceUpdatedListener;
import com.jogamp.opengl.GL;
@@ -192,7 +192,7 @@ public class TestFBOOffThreadSharedContextMix2DemosES2NEWT extends UITestCase {
}
if(9 == c) {
c=0;
- new Thread() {
+ new InterruptSource.Thread() {
@Override
public void run() {
glWindow.setSize(dw+256, dh+256);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOOnThreadSharedContext1DemoES2NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOOnThreadSharedContext1DemoES2NEWT.java
index 0586eef8e..1886d3d2a 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOOnThreadSharedContext1DemoES2NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOOnThreadSharedContext1DemoES2NEWT.java
@@ -46,7 +46,7 @@ import com.jogamp.opengl.util.texture.TextureIO;
import com.jogamp.opengl.test.junit.jogl.demos.GLFinishOnDisplay;
import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
import com.jogamp.opengl.test.junit.jogl.demos.es2.Mix2TexturesES2;
-
+import com.jogamp.common.util.InterruptSource;
import com.jogamp.nativewindow.NativeSurface;
import com.jogamp.nativewindow.SurfaceUpdatedListener;
import com.jogamp.opengl.GL;
@@ -178,7 +178,7 @@ public class TestFBOOnThreadSharedContext1DemoES2NEWT extends UITestCase {
}
if(9 == c) {
c=0;
- new Thread() {
+ new InterruptSource.Thread() {
@Override
public void run() {
glWindow.setSize(dw+256, dh+256);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableFactoryGLProfileDeviceNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableFactoryGLProfileDeviceNEWT.java
new file mode 100644
index 000000000..1e264d21a
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableFactoryGLProfileDeviceNEWT.java
@@ -0,0 +1,247 @@
+/**
+ * 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.nativewindow.AbstractGraphicsDevice;
+import com.jogamp.nativewindow.CapabilitiesImmutable;
+import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
+import com.jogamp.opengl.GLCapabilities;
+import com.jogamp.opengl.GLCapabilitiesImmutable;
+import com.jogamp.opengl.GLContext;
+import com.jogamp.opengl.GLDrawableFactory;
+import com.jogamp.opengl.GLEventListener;
+import com.jogamp.opengl.GLOffscreenAutoDrawable;
+import com.jogamp.opengl.GLProfile;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.FixMethodOrder;
+import org.junit.runners.MethodSorters;
+
+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.GLEventListenerCounter;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+
+/**
+ * Testing producing {@link GLContext} instances of different {@link GLProfile}s
+ * using different {@link AbstractGraphicsDevice}s.
+ */
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class TestGLAutoDrawableFactoryGLProfileDeviceNEWT extends UITestCase {
+ static final int widthStep = 800/4;
+ static final int heightStep = 600/4;
+ volatile int szStep = 2;
+
+ static GLProfile getProfile(final AbstractGraphicsDevice device, final String profile) {
+ if( !GLProfile.isAvailable(device, profile) ) {
+ System.err.println("Profile "+profile+" n/a");
+ return null;
+ } else {
+ return GLProfile.get(device, profile);
+ }
+ }
+
+ void doTest(final boolean isEGL, final GLDrawableFactory factory, final AbstractGraphicsDevice device,
+ final GLCapabilitiesImmutable reqGLCaps, final GLEventListener demo) throws InterruptedException {
+ System.err.println("Factory: "+factory.getClass().getName());
+ System.err.println("Requested GL Caps: "+reqGLCaps);
+
+ //
+ // Create native OpenGL resources .. XGL/WGL/CGL ..
+ // equivalent to GLAutoDrawable methods: setVisible(true)
+ //
+ final GLOffscreenAutoDrawable glad = factory.createOffscreenAutoDrawable(device, reqGLCaps, null, widthStep*szStep, heightStep*szStep);
+
+ Assert.assertNotNull(glad);
+ Assert.assertTrue(glad.isRealized());
+
+ // Check caps of NativeWindow config w/o GL
+ final CapabilitiesImmutable chosenCaps = glad.getChosenGLCapabilities();
+ Assert.assertNotNull(chosenCaps);
+
+ glad.display(); // force native context creation
+
+ // Check caps of GLDrawable after realization
+ final GLCapabilitiesImmutable chosenGLCaps = glad.getChosenGLCapabilities();
+ Assert.assertNotNull(chosenGLCaps);
+ System.err.println("Choosen GL Caps: "+chosenGLCaps);
+
+ glad.addGLEventListener(demo);
+ final GLEventListenerCounter glelc = new GLEventListenerCounter();
+ glad.addGLEventListener(glelc);
+
+ glad.display(); // initial resize/display
+
+ // 1 - szStep = 2
+ Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getSurfaceWidth()+"x"+glad.getSurfaceHeight(),
+ AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep));
+ glad.display();
+
+ // 2, 3 (resize + display)
+ szStep = 1;
+ glad.setSurfaceSize(widthStep*szStep, heightStep*szStep);
+ Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getSurfaceWidth()+"x"+glad.getSurfaceHeight(),
+ AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep));
+ glad.display();
+
+ Thread.sleep(50);
+
+ final AbstractGraphicsDevice adevice = glad.getNativeSurface().getGraphicsConfiguration().getScreen().getDevice();
+ glad.destroy();
+ System.err.println("Fin isEGL "+isEGL+", "+adevice);
+ System.err.println("Fin "+glelc);
+ Assert.assertTrue("init count: "+glelc, glelc.initCount > 0);
+ Assert.assertTrue("reshape count: "+glelc, glelc.reshapeCount > 0);
+ Assert.assertTrue("display count: "+glelc, glelc.displayCount > 0);
+ Assert.assertTrue("dispose count: "+glelc, glelc.disposeCount > 0);
+ Assert.assertEquals("EGL/Desktop not matching: isEGL "+isEGL+", "+adevice, isEGL, adevice instanceof EGLGraphicsDevice);
+ }
+
+ @Test
+ public void test00AvailableInfo() {
+ 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 test01ES2OnEGL() throws InterruptedException {
+ final GLDrawableFactory factory = GLDrawableFactory.getEGLFactory();
+ if( null == factory ) {
+ System.err.println("EGL Factory n/a");
+ return;
+ }
+ final AbstractGraphicsDevice prodDevice = factory.getDefaultDevice();
+ final GLProfile glp = getProfile(prodDevice, GLProfile.GLES2);
+ if(null != glp) {
+ Assert.assertTrue("Not a GLES2 profile but "+glp, glp.isGLES2());
+ Assert.assertTrue("Not a GL2ES2 profile but "+glp, glp.isGL2ES2());
+ }
+ if(null == glp) {
+ return;
+ }
+ final GLCapabilities reqGLCaps = new GLCapabilities(glp);
+ reqGLCaps.setOnscreen(false);
+ final GearsES2 demo = new GearsES2(1);
+ demo.setVerbose(false);
+ doTest(true /* isEGL */, factory, prodDevice, reqGLCaps, demo);
+ }
+
+ @Test
+ public void test02GLOnEGL() throws InterruptedException {
+ final GLDrawableFactory factory = GLDrawableFactory.getEGLFactory();
+ if( null == factory ) {
+ System.err.println("EGL Factory n/a");
+ return;
+ }
+ final AbstractGraphicsDevice prodDevice = factory.getDefaultDevice();
+ final GLProfile glp = getProfile(prodDevice, GLProfile.GL2GL3);
+ if(null != glp) {
+ Assert.assertTrue("Not a GL2GL3 profile but "+glp, glp.isGL2GL3());
+ }
+ if(null == glp || !glp.isGL2ES2()) {
+ if( null != glp ) {
+ System.err.println("Not a GL2ES2 profile but "+glp);
+ }
+ return;
+ }
+ final GLCapabilities reqGLCaps = new GLCapabilities(glp);
+ reqGLCaps.setOnscreen(false);
+ final GearsES2 demo = new GearsES2(1);
+ demo.setVerbose(false);
+ doTest(true /* isEGL */, factory, prodDevice, reqGLCaps, demo);
+ }
+
+ @Test
+ public void test11ES2OnDesktop() throws InterruptedException {
+ final GLDrawableFactory deskFactory = GLDrawableFactory.getDesktopFactory();
+ if( null == deskFactory ) {
+ System.err.println("Desktop Factory n/a");
+ return;
+ }
+ final AbstractGraphicsDevice prodDevice = deskFactory.getDefaultDevice();
+ final GLProfile glp = getProfile(prodDevice, GLProfile.GLES2);
+ if(null != glp) {
+ Assert.assertTrue("Not a GLES2 profile but "+glp, glp.isGLES2());
+ Assert.assertTrue("Not a GL2ES2 profile but "+glp, glp.isGL2ES2());
+ }
+ if(null == glp) {
+ return;
+ }
+ final GLDrawableFactory prodFactory = GLDrawableFactory.getFactory(glp);
+ if( null == prodFactory ) {
+ System.err.println("Production Factory n/a");
+ return;
+ }
+ final GLCapabilities reqGLCaps = new GLCapabilities(glp);
+ reqGLCaps.setOnscreen(false);
+ final GearsES2 demo = new GearsES2(1);
+ demo.setVerbose(false);
+ doTest(true /* isEGL */, prodFactory, prodDevice, reqGLCaps, demo);
+ }
+
+ @Test
+ public void test12GLOnDesktop() throws InterruptedException {
+ final GLDrawableFactory factory = GLDrawableFactory.getDesktopFactory();
+ if( null == factory ) {
+ System.err.println("Desktop Factory n/a");
+ return;
+ }
+ final AbstractGraphicsDevice prodDevice = factory.getDefaultDevice();
+ final GLProfile glp = getProfile(prodDevice, GLProfile.GL2GL3);
+ if(null != glp) {
+ Assert.assertTrue("Not a GL2GL3 profile but "+glp, glp.isGL2GL3());
+ }
+ if(null == glp || !glp.isGL2ES2()) {
+ if( null != glp ) {
+ System.err.println("Not a GL2ES2 profile but "+glp);
+ }
+ return;
+ }
+ final GLCapabilities reqGLCaps = new GLCapabilities(glp);
+ reqGLCaps.setOnscreen(false);
+ final GearsES2 demo = new GearsES2(1);
+ demo.setVerbose(false);
+ doTest(false /* isEGL */, factory, prodDevice, reqGLCaps, demo);
+ }
+
+ public static void main(final String args[]) throws IOException {
+ org.junit.runner.JUnitCore.main(TestGLAutoDrawableFactoryGLProfileDeviceNEWT.class.getName());
+ }
+
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextSurfaceLockNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextSurfaceLockNEWT.java
index 1e78691c4..8d26ebb82 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextSurfaceLockNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextSurfaceLockNEWT.java
@@ -31,6 +31,7 @@ package com.jogamp.opengl.test.junit.jogl.acore;
import java.io.IOException;
import java.util.concurrent.atomic.AtomicInteger;
+import com.jogamp.common.util.InterruptSource;
import com.jogamp.nativewindow.NativeSurface;
import com.jogamp.opengl.GLAutoDrawable;
import com.jogamp.opengl.GLCapabilities;
@@ -194,8 +195,8 @@ public class TestGLContextSurfaceLockNEWT extends UITestCase {
final Object sync = new Object();
final MyRunnable[] animTasks = new MyRunnable[animThreadCount];
final MyRunnable[] resizeTasks = new MyRunnable[animThreadCount];
- final Thread[] animThreads = new Thread[reszThreadCount];
- final Thread[] resizeThreads = new Thread[reszThreadCount];
+ final InterruptSource.Thread[] animThreads = new InterruptSource.Thread[reszThreadCount];
+ final InterruptSource.Thread[] resizeThreads = new InterruptSource.Thread[reszThreadCount];
System.err.println("animThreadCount "+animThreadCount+", frameCount "+frameCount);
System.err.println("reszThreadCount "+reszThreadCount+", resizeCount "+resizeCount);
@@ -204,12 +205,12 @@ public class TestGLContextSurfaceLockNEWT extends UITestCase {
for(int i=0; i<animThreadCount; i++) {
System.err.println("create anim task/thread "+i);
animTasks[i] = new RudeAnimator(glWindow, frameCount, sync, i);
- animThreads[i] = new Thread(animTasks[i], currentThreadName+"-anim"+i);
+ animThreads[i] = new InterruptSource.Thread(null, animTasks[i], currentThreadName+"-anim"+i);
}
for(int i=0; i<reszThreadCount; i++) {
System.err.println("create resz task/thread "+i);
resizeTasks[i] = new RudeResizer(glWindow, resizeCount, sync, i);
- resizeThreads[i] = new Thread(resizeTasks[i], currentThreadName+"-resz"+i);
+ resizeThreads[i] = new InterruptSource.Thread(null, resizeTasks[i], currentThreadName+"-resz"+i);
}
myEventCounter.reset();
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLDebug00NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLDebug00NEWT.java
index dcee114e5..8319a1c22 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLDebug00NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLDebug00NEWT.java
@@ -32,7 +32,6 @@ import java.io.IOException;
import com.jogamp.opengl.GL;
import com.jogamp.opengl.GL2ES2;
-import com.jogamp.opengl.GL2GL3;
import com.jogamp.opengl.GLCapabilities;
import com.jogamp.opengl.GLContext;
import com.jogamp.opengl.GLDebugListener;
@@ -58,6 +57,14 @@ public class TestGLDebug00NEWT extends UITestCase {
static String dbgTstMsg0 = "Hello World";
static int dbgTstId0 = 42;
+ static GLProfile getGLProfile(final String profile) {
+ if( !GLProfile.isAvailable(profile) ) {
+ System.err.println("Profile "+profile+" n/a");
+ return null;
+ }
+ return GLProfile.get(profile);
+ }
+
public static class WindowContext {
public final Window window;
public final GLContext context;
@@ -115,9 +122,7 @@ public class TestGLDebug00NEWT extends UITestCase {
}
- void test01GLDebug01EnableDisable(final boolean enable) throws InterruptedException {
- final GLProfile glp = GLProfile.getDefault();
-
+ void testX1GLDebugEnableDisable(final GLProfile glp, final boolean enable) throws InterruptedException {
final WindowContext winctx = createWindow(glp, enable);
final String glDebugExt = winctx.context.getGLDebugMessageExtension();
System.err.println("glDebug extension: "+glDebugExt);
@@ -131,19 +136,42 @@ public class TestGLDebug00NEWT extends UITestCase {
}
@Test
- public void test01GLDebugDisabled() throws InterruptedException {
- test01GLDebug01EnableDisable(false);
+ public void test01GL2GL3DebugDisabled() throws InterruptedException {
+ final GLProfile glp = getGLProfile(GLProfile.GL2GL3);
+ if( null == glp ) {
+ return;
+ }
+ testX1GLDebugEnableDisable(glp, false);
}
@Test
- public void test01GLDebugEnabled() throws InterruptedException {
- test01GLDebug01EnableDisable(true);
+ public void test02GL2GL3DebugEnabled() throws InterruptedException {
+ final GLProfile glp = getGLProfile(GLProfile.GL2GL3);
+ if( null == glp ) {
+ return;
+ }
+ testX1GLDebugEnableDisable(glp, true);
}
@Test
- public void test02GLDebugError() throws InterruptedException {
- final GLProfile glp = GLProfile.getDefault();
+ public void test11GLES2DebugDisabled() throws InterruptedException {
+ final GLProfile glp = getGLProfile(GLProfile.GLES2);
+ if( null == glp ) {
+ return;
+ }
+ testX1GLDebugEnableDisable(glp, false);
+ }
+
+ @Test
+ public void test12GLES2DebugEnabled() throws InterruptedException {
+ final GLProfile glp = getGLProfile(GLProfile.GLES2);
+ if( null == glp ) {
+ return;
+ }
+ testX1GLDebugEnableDisable(glp, true);
+ }
+ void testX2GLDebugError(final GLProfile glp) throws InterruptedException {
final WindowContext winctx = createWindow(glp, true);
final MyGLDebugListener myGLDebugListener = new MyGLDebugListener(
@@ -164,8 +192,24 @@ public class TestGLDebug00NEWT extends UITestCase {
}
@Test
- public void test03GLDebugInsert() throws InterruptedException {
- final GLProfile glp = GLProfile.getDefault();
+ public void test03GL2GL3DebugError() throws InterruptedException {
+ final GLProfile glp = getGLProfile(GLProfile.GL2GL3);
+ if( null == glp ) {
+ return;
+ }
+ testX2GLDebugError(glp);
+ }
+
+ @Test
+ public void test13GLES2DebugError() throws InterruptedException {
+ final GLProfile glp = getGLProfile(GLProfile.GLES2);
+ if( null == glp ) {
+ return;
+ }
+ testX2GLDebugError(glp);
+ }
+
+ void testX3GLDebugInsert(final GLProfile glp) throws InterruptedException {
final WindowContext winctx = createWindow(glp, true);
final MyGLDebugListener myGLDebugListener = new MyGLDebugListener(dbgTstMsg0, dbgTstId0);
winctx.context.addGLDebugListener(myGLDebugListener);
@@ -184,6 +228,23 @@ public class TestGLDebug00NEWT extends UITestCase {
destroyWindow(winctx);
}
+ @Test
+ public void test04GL2GL3DebugInsert() throws InterruptedException {
+ final GLProfile glp = getGLProfile(GLProfile.GL2GL3);
+ if( null == glp ) {
+ return;
+ }
+ testX3GLDebugInsert(glp);
+ }
+
+ @Test
+ public void test14GLES2DebugInsert() throws InterruptedException {
+ final GLProfile glp = getGLProfile(GLProfile.GLES2);
+ if( null == glp ) {
+ return;
+ }
+ testX3GLDebugInsert(glp);
+ }
public static void main(final String args[]) throws IOException {
final String tstname = TestGLDebug00NEWT.class.getName();
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLDebug01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLDebug01NEWT.java
index 66733209c..43d207a0d 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLDebug01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLDebug01NEWT.java
@@ -31,7 +31,6 @@ package com.jogamp.opengl.test.junit.jogl.acore;
import java.io.IOException;
import com.jogamp.opengl.GL2ES2;
-import com.jogamp.opengl.GL2GL3;
import com.jogamp.opengl.GLAutoDrawable;
import com.jogamp.opengl.GLCapabilities;
import com.jogamp.opengl.GLContext;
@@ -54,6 +53,14 @@ public class TestGLDebug01NEWT extends UITestCase {
static String dbgTstMsg0 = "Hello World";
static int dbgTstId0 = 42;
+ static GLProfile getGLProfile(final String profile) {
+ if( !GLProfile.isAvailable(profile) ) {
+ System.err.println("Profile "+profile+" n/a");
+ return null;
+ }
+ return GLProfile.get(profile);
+ }
+
GLWindow createWindow(final GLProfile glp, final boolean debugGL) {
final GLCapabilities caps = new GLCapabilities(glp);
//
@@ -76,9 +83,7 @@ public class TestGLDebug01NEWT extends UITestCase {
}
- void test01GLDebug01EnableDisable(final boolean enable, final String dbgTstMsg, final int dbgTstId) throws InterruptedException {
- final GLProfile glp = GLProfile.getDefault();
-
+ void testX1GLDebugEnableDisable(final GLProfile glp, final boolean enable, final String dbgTstMsg, final int dbgTstId) throws InterruptedException {
final GLWindow window = createWindow(glp, enable);
final GLContext ctx = window.getContext();
final MyGLDebugListener myGLDebugListener = new MyGLDebugListener(dbgTstMsg, dbgTstId);
@@ -109,19 +114,42 @@ public class TestGLDebug01NEWT extends UITestCase {
}
@Test
- public void test01GLDebug01Disabled() throws InterruptedException {
- test01GLDebug01EnableDisable(false, null, -1);
+ public void test01GL2GL3DebugDisabled() throws InterruptedException {
+ final GLProfile glp = getGLProfile(GLProfile.GL2GL3);
+ if( null == glp ) {
+ return;
+ }
+ testX1GLDebugEnableDisable(glp, false, null, -1);
}
@Test
- public void test01GLDebug01Enabled() throws InterruptedException {
- test01GLDebug01EnableDisable(true, dbgTstMsg0, dbgTstId0);
+ public void test02GL2GL3DebugEnabled() throws InterruptedException {
+ final GLProfile glp = getGLProfile(GLProfile.GL2GL3);
+ if( null == glp ) {
+ return;
+ }
+ testX1GLDebugEnableDisable(glp, true, dbgTstMsg0, dbgTstId0);
}
@Test
- public void test02GLDebug01Error() throws InterruptedException {
- final GLProfile glp = GLProfile.getDefault();
+ public void test11GLES2DebugDisabled() throws InterruptedException {
+ final GLProfile glp = getGLProfile(GLProfile.GLES2);
+ if( null == glp ) {
+ return;
+ }
+ testX1GLDebugEnableDisable(glp, false, null, -1);
+ }
+ @Test
+ public void test12GLES2DebugEnabled() throws InterruptedException {
+ final GLProfile glp = getGLProfile(GLProfile.GLES2);
+ if( null == glp ) {
+ return;
+ }
+ testX1GLDebugEnableDisable(glp, true, dbgTstMsg0, dbgTstId0);
+ }
+
+ void testX3GLDebugError(final GLProfile glp) throws InterruptedException {
final GLWindow window = createWindow(glp, true);
final MyGLDebugListener myGLDebugListener = new MyGLDebugListener(
@@ -144,6 +172,23 @@ public class TestGLDebug01NEWT extends UITestCase {
destroyWindow(window);
}
+ @Test
+ public void test03GL2GL3DebugError() throws InterruptedException {
+ final GLProfile glp = getGLProfile(GLProfile.GL2GL3);
+ if( null == glp ) {
+ return;
+ }
+ testX3GLDebugError(glp);
+ }
+
+ @Test
+ public void test13GLES2DebugError() throws InterruptedException {
+ final GLProfile glp = getGLProfile(GLProfile.GLES2);
+ if( null == glp ) {
+ return;
+ }
+ testX3GLDebugError(glp);
+ }
public static void main(final String args[]) throws IOException {
final String tstname = TestGLDebug01NEWT.class.getName();
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestOffscreenLayer02NewtCanvasAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestOffscreenLayer02NewtCanvasAWT.java
index 65925c6b5..d49c1e545 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestOffscreenLayer02NewtCanvasAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestOffscreenLayer02NewtCanvasAWT.java
@@ -49,16 +49,27 @@ import org.junit.Test;
import org.junit.FixMethodOrder;
import org.junit.runners.MethodSorters;
+import com.jogamp.junit.util.JunitTracer;
import com.jogamp.newt.Window;
import com.jogamp.newt.awt.NewtCanvasAWT;
import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.newt.opengl.util.NEWTDemoListener;
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.newt.parenting.NewtReparentingKeyAdapter;
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;
+/**
+ * <p>
+ * The demo code uses {@link NewtReparentingKeyAdapter} including {@link NEWTDemoListener} functionality.
+ * </p>
+ * <p>
+ * Manual invocation via main allows setting each tests's duration in milliseconds, e.g.{@code -duration 10000}, and many more, see {@link #main(String[])}
+ * </p>
+ */
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class TestOffscreenLayer02NewtCanvasAWT extends UITestCase {
static boolean singleBuffer = false;
@@ -162,7 +173,7 @@ public class TestOffscreenLayer02NewtCanvasAWT extends UITestCase {
}
setDemoFields(demo1, glWindow1, false);
glWindow1.addGLEventListener(demo1);
- glWindow1.addKeyListener(new NewtAWTReparentingKeyAdapter(frame1, newtCanvasAWT1, glWindow1, null));
+ glWindow1.addKeyListener(new NewtAWTReparentingKeyAdapter(frame1, newtCanvasAWT1, glWindow1));
frame1.setSize(frameSize0);
setupFrameAndShow(frame1, newtCanvasAWT1);
@@ -189,7 +200,7 @@ public class TestOffscreenLayer02NewtCanvasAWT extends UITestCase {
end(animator1, frame1, glWindow1);
if( waitForKey ) {
- UITestCase.waitForKey("Continue");
+ JunitTracer.waitForKey("Continue");
}
}
@@ -234,7 +245,7 @@ public class TestOffscreenLayer02NewtCanvasAWT extends UITestCase {
}
}
if(waitForKey) {
- UITestCase.waitForKey("Start");
+ JunitTracer.waitForKey("Start");
}
final String tstname = TestOffscreenLayer02NewtCanvasAWT.class.getName();
/*
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 aef64e4e9..ae9dac003 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
@@ -43,6 +43,7 @@ import org.junit.Test;
import org.junit.FixMethodOrder;
import org.junit.runners.MethodSorters;
+import com.jogamp.common.util.InterruptSource;
import com.jogamp.common.util.RunnableTask;
import com.jogamp.opengl.test.junit.util.UITestCase;
@@ -82,7 +83,7 @@ public class TestPBufferDeadlockAWT extends UITestCase {
System.err.println("BB.0: "+rTask.getSyncObject());
synchronized (rTask.getSyncObject()) {
System.err.println("BB.1: "+rTask.getSyncObject());
- new Thread(rTask, Thread.currentThread().getName()+"-Pbuffer_Creation").start();
+ new InterruptSource.Thread(null, rTask, Thread.currentThread().getName()+"-Pbuffer_Creation").start();
try {
System.err.println("BB.2");
rTask.getSyncObject().wait();
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedExternalContextAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedExternalContextAWT.java
index 81489df17..0987b2978 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedExternalContextAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedExternalContextAWT.java
@@ -14,6 +14,7 @@ import javax.swing.Timer;
import org.junit.Test;
import com.jogamp.common.os.Platform;
+import com.jogamp.common.util.InterruptSource;
import com.jogamp.common.util.locks.LockFactory;
import com.jogamp.common.util.locks.RecursiveLock;
import com.jogamp.opengl.*;
@@ -69,7 +70,7 @@ public class TestSharedExternalContextAWT {
// which is suppose to lie outside of the JVM.
// The thread is kept alive, since this detail
// may be required for the OpenGL driver implementation.
- final Thread thread = new Thread(runnable);
+ final Thread thread = new InterruptSource.Thread(null, runnable);
thread.setDaemon(true);
thread.start();
masterLatch.await(3, TimeUnit.SECONDS);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestVersionSemanticsNOUI.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestVersionSemanticsNOUI.java
index bbbd92e5e..07d9e2954 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestVersionSemanticsNOUI.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestVersionSemanticsNOUI.java
@@ -141,6 +141,44 @@ public class TestVersionSemanticsNOUI extends SingletonJunitCase {
curVersion.getClass(), currentCL, curVersionNumber,
excludesStereoPackageAndAppletUtils);
}
+ @Test
+ public void testVersionV231V23x_01patch() throws IllegalArgumentException, IOException, URISyntaxException {
+ // final Delta.CompatibilityType expectedCompatibilityType = Delta.CompatibilityType.NON_BACKWARD_COMPATIBLE;
+ // final Delta.CompatibilityType expectedCompatibilityType = Delta.CompatibilityType.BACKWARD_COMPATIBLE_USER;
+ final Delta.CompatibilityType expectedCompatibilityType = Delta.CompatibilityType.BACKWARD_COMPATIBLE_BINARY;
+
+ final VersionNumberString preVersionNumber = new VersionNumberString("2.3.1");
+ final File previousJar = new File("lib/v"+preVersionNumber.getVersionString()+"/"+jarFile);
+
+ final ClassLoader currentCL = TestVersionSemanticsNOUI.class.getClassLoader();
+
+ VersionSemanticsUtil.testVersion(diffCriteria, expectedCompatibilityType,
+ previousJar, preVersionNumber,
+ curVersion.getClass(), currentCL, curVersionNumber,
+ excludesStereoPackageAndAppletUtils);
+ }
+
+ @Test
+ public void testVersionV230V232() throws IllegalArgumentException, IOException, URISyntaxException {
+ testVersions(diffCriteria, Delta.CompatibilityType.BACKWARD_COMPATIBLE_BINARY, "2.3.0", "2.3.2", excludesStereoPackageAndAppletUtils);
+ }
+
+ // @Test
+ public void testVersionV232V24x0() throws IllegalArgumentException, IOException, URISyntaxException {
+ final Delta.CompatibilityType expectedCompatibilityType = Delta.CompatibilityType.NON_BACKWARD_COMPATIBLE;
+ // final Delta.CompatibilityType expectedCompatibilityType = Delta.CompatibilityType.BACKWARD_COMPATIBLE_USER;
+ // final Delta.CompatibilityType expectedCompatibilityType = Delta.CompatibilityType.BACKWARD_COMPATIBLE_BINARY;
+
+ final VersionNumberString preVersionNumber = new VersionNumberString("2.3.2");
+ final File previousJar = new File("lib/v"+preVersionNumber.getVersionString()+"/"+jarFile);
+
+ final ClassLoader currentCL = TestVersionSemanticsNOUI.class.getClassLoader();
+
+ VersionSemanticsUtil.testVersion(diffCriteria, expectedCompatibilityType,
+ previousJar, preVersionNumber,
+ curVersion.getClass(), currentCL, curVersionNumber,
+ excludesDefault);
+ }
public static void main(final String args[]) throws IOException {
final String tstname = TestVersionSemanticsNOUI.class.getName();
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/anim/Bug898AnimatorFromEDTAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/anim/Bug898AnimatorFromEDTAWT.java
index b30bb1192..4cdcbd10a 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/anim/Bug898AnimatorFromEDTAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/anim/Bug898AnimatorFromEDTAWT.java
@@ -30,6 +30,7 @@ package com.jogamp.opengl.test.junit.jogl.acore.anim;
import java.awt.BorderLayout;
import java.awt.Dimension;
+import com.jogamp.common.util.InterruptSource;
import com.jogamp.opengl.GLAutoDrawable;
import com.jogamp.opengl.GLCapabilities;
import com.jogamp.opengl.GLEventListener;
@@ -85,10 +86,10 @@ public class Bug898AnimatorFromEDTAWT extends javax.swing.JFrame {
lastTime = time;
animator.pause();
System.out.println(Thread.currentThread().getName()+": #"+step+" "+td+" ms: animator.pause(): paused "+animator);
- new Thread() {
+ new InterruptSource.Thread() {
public void run() {
try {
- Thread.sleep(1000);
+ java.lang.Thread.sleep(1000);
} catch (final InterruptedException e) {
e.printStackTrace();
}
@@ -98,9 +99,9 @@ public class Bug898AnimatorFromEDTAWT extends javax.swing.JFrame {
final long td = System.currentTimeMillis() - lastTime;
if (animator.isPaused()) {
animator.resume(); //Doesn't work on v2.0.2 or higher
- System.out.println(Thread.currentThread().getName()+": #"+step+" "+td+" ms: animator.resume(): animating "+animator);
+ System.out.println(java.lang.Thread.currentThread().getName()+": #"+step+" "+td+" ms: animator.resume(): animating "+animator);
} else {
- System.out.println(Thread.currentThread().getName()+": #"+step+" "+td+" ms: animator.resume(): Ooops - not paused! - animating "+animator);
+ System.out.println(java.lang.Thread.currentThread().getName()+": #"+step+" "+td+" ms: animator.resume(): Ooops - not paused! - animating "+animator);
}
} } );
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug1225EventQueueInterruptedAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug1225EventQueueInterruptedAWT.java
new file mode 100644
index 000000000..92dd7e344
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug1225EventQueueInterruptedAWT.java
@@ -0,0 +1,378 @@
+/**
+ * Copyright 2015 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.BorderLayout;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.GridLayout;
+import java.awt.Label;
+import java.lang.Thread.UncaughtExceptionHandler;
+import java.lang.reflect.InvocationTargetException;
+
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.SwingUtilities;
+
+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.MiscUtils;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+
+import org.junit.Assert;
+
+import com.jogamp.common.ExceptionUtils;
+import com.jogamp.common.util.InterruptedRuntimeException;
+import com.jogamp.common.util.SourcedInterruptedException;
+import com.jogamp.nativewindow.NativeWindowFactory;
+import com.jogamp.opengl.GLAutoDrawable;
+import com.jogamp.opengl.GLEventListener;
+import com.jogamp.opengl.awt.GLCanvas;
+
+import org.junit.Test;
+import org.junit.FixMethodOrder;
+import org.junit.runners.MethodSorters;
+
+/**
+ * Test to check if interrupt on AWT-EventQueue causes a malfunction in JOGL.
+ * <p>
+ * After tests are displaying an ever color rotating rectangle in an AWT component alone
+ * and with an additional GearsES2 within a GLCanvas.
+ * </p>
+ * <p>
+ * The AWT component is issuing an interrupt during paint on the AWT-EDT.
+ * </p>
+ * <p>
+ * The reporter claims that an interrupt on the AWT-EDT shall not disturb neither AWT nor JOGL's GLCanvas
+ * and rendering shall continue.
+ * <ul>
+ * <li>This seems to be true for JRE 1.8.0_60</li>
+ * <li>This seems to be false for JRE 1.7.0_45. This JRE's AWT-EDT even dies occasionally when interrupted.</li>
+ * </ul>
+ * </p>
+ * <p>
+ * The test passes on GNU/Linux and Windows using JRE 1.8.0_60.
+ * </p>
+ */
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class TestBug1225EventQueueInterruptedAWT extends UITestCase {
+ static long durationPerTest = 1000; // ms
+
+ private void setVisible(final JFrame frame, final boolean v) throws InterruptedException, InvocationTargetException {
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ frame.pack();
+ // frame.setSize(new Dimension(800, 600));
+ frame.setVisible(v);
+ }});
+ }
+ private void dispose(final JFrame jFrame) throws InterruptedException, InvocationTargetException {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ jFrame.dispose();
+ } } ) ;
+ }
+
+
+ @Test(timeout=180000) // TO 3 min
+ public void test01_NoGL() throws InterruptedException, InvocationTargetException {
+ testImpl(false);
+ }
+
+ @Test(timeout=180000) // TO 3 min
+ public void test02_WithGL() throws InterruptedException, InvocationTargetException {
+ testImpl(true);
+ }
+
+ class OurUncaughtExceptionHandler implements UncaughtExceptionHandler {
+ public volatile Thread thread = null;
+ public volatile Throwable exception = null;
+
+ @Override
+ public void uncaughtException(final Thread t, final Throwable e) {
+ thread = t;
+ exception = e;
+ System.err.println("*** UncaughtException (this Thread "+Thread.currentThread().getName()+") : Thread <"+t.getName()+">, "+e.getClass().getName()+": "+e.getMessage());
+ ExceptionUtils.dumpThrowable("", e);
+ }
+ }
+ void testImpl(final boolean useGL) throws InterruptedException, InvocationTargetException {
+ if( !AWTRobotUtil.isAWTEDTAlive() ) {
+ System.err.println("Test aborted: AWT not alive");
+ return;
+ }
+ // Assume.assumeTrue("AWT not alive", AWTRobotUtil.isAWTEDTAlive());
+ // Assert.assertTrue("AWT not alive", AWTRobotUtil.isAWTEDTAlive());
+ final OurUncaughtExceptionHandler uncaughtHandler = new OurUncaughtExceptionHandler();
+ Thread.setDefaultUncaughtExceptionHandler( uncaughtHandler );
+
+ final Dimension csize = new Dimension(800, 400);
+ final JPanel panel = new JPanel(new GridLayout(2, 1));
+ final GLCanvas glc;
+ final InterruptableGLEL iglel;
+ if( useGL ) {
+ glc = new GLCanvas();
+ {
+ final GearsES2 gears = new GearsES2();
+ gears.setVerbose(false);
+ glc.addGLEventListener(gears);
+ }
+ iglel = new InterruptableGLEL();
+ glc.addGLEventListener(iglel);
+ glc.setSize(csize);
+ glc.setPreferredSize(csize);
+ panel.add(glc);
+ } else {
+ NativeWindowFactory.initSingleton();
+ glc = null;
+ iglel = null;
+ final Label l = new Label("No GL Object");
+ l.setSize(csize);
+ l.setPreferredSize(csize);
+ panel.add(l);
+ }
+ final InterruptingComponent icomp = new InterruptingComponent();
+ panel.add(icomp);
+ icomp.setSize(csize);
+ icomp.setPreferredSize(csize);
+
+ final JFrame frame = new JFrame();
+ frame.setResizable(true);
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+ frame.getContentPane().add(panel, BorderLayout.CENTER);
+ setVisible(frame, true);
+ if( useGL ) {
+ Assert.assertTrue(AWTRobotUtil.waitForRealized(glc, true));
+ }
+ Assert.assertTrue(AWTRobotUtil.waitForRealized(icomp, true));
+
+ final InterruptableLoop loop = new InterruptableLoop(icomp, glc);
+ final Thread thread = new Thread(loop);
+
+ synchronized(loop) {
+ thread.start();
+ try {
+ loop.notifyAll(); // wake-up startup-block
+ while( !loop.isRunning && !loop.shallStop ) {
+ loop.wait(); // wait until started
+ }
+ loop.ack = true;
+ loop.notifyAll(); // wake-up startup-block
+ } catch (final InterruptedException e) {
+ Assert.assertNull("while starting loop", new InterruptedRuntimeException(e));
+ }
+ }
+
+ for(int i=0; thread.isAlive() && null == loop.exception && null == uncaughtHandler.exception && i<100; i++) {
+ icomp.interruptAWTEventQueue();
+ Thread.sleep(durationPerTest/100);
+ }
+
+ loop.shallStop = true;
+ synchronized(loop) {
+ try {
+ loop.notifyAll(); // wake-up pause-block (opt)
+ while( loop.isRunning ) {
+ loop.wait(); // wait until stopped
+ }
+ } catch (final InterruptedException e) {
+ Assert.assertNull("while stopping loop", new InterruptedRuntimeException(e));
+ }
+ }
+
+ //
+ // Notifications only!
+ //
+ // Note:
+ // On JRE 1.8.0_60: Interrupt is cleared on AWT-EDT
+ // On JRE 1.7.0_45: Interrupt is *NOT* cleared on AWT-EDT
+ //
+ if( null != iglel && null != iglel.exception ) {
+ ExceptionUtils.dumpThrowable("GLEventListener", iglel.exception);
+ }
+ if( null != icomp.exception ) {
+ ExceptionUtils.dumpThrowable("InterruptingComponent", icomp.exception);
+ }
+ if( null != loop.exception ) {
+ ExceptionUtils.dumpThrowable("loop", loop.exception);
+ }
+ if( null != uncaughtHandler.exception ) {
+ ExceptionUtils.dumpThrowable("uncaughtHandler", uncaughtHandler.exception);
+ }
+ if( !AWTRobotUtil.isAWTEDTAlive() ) {
+ System.err.println("AWT is not alive anymore!!! Ooops");
+ // cannot do anything anymore on AWT-EDT .. frame.dispose();
+ } else {
+ dispose(frame);
+ }
+
+ //
+ // Fail if interrupt was propagated to loop or uncaught handler
+ //
+ Assert.assertNull("Caught Exception in loop", loop.exception);
+ Assert.assertNull("Caught Exception via uncaughtHandler", uncaughtHandler.exception);
+ }
+
+ static class InterruptableLoop implements Runnable {
+ public volatile Exception exception = null;
+ public volatile boolean shallStop = false;
+ public volatile boolean isRunning = false;
+ public volatile boolean ack = false;
+ final InterruptingComponent icomp;
+ final GLCanvas glc;
+ boolean alt = false;;
+
+ InterruptableLoop(final InterruptingComponent icomp, final GLCanvas glc) {
+ this.icomp = icomp;
+ this.glc = glc;
+ }
+
+ public void stop() {
+ shallStop = true;
+ }
+
+ @Override
+ public void run()
+ {
+ synchronized ( this ) {
+ isRunning = true;
+ this.notifyAll();
+ try {
+ while( !ack ) {
+ this.wait(); // wait until ack
+ }
+ this.notifyAll();
+ } catch (final InterruptedException e) {
+ throw new InterruptedRuntimeException(e);
+ }
+ ack = false;
+ }
+ synchronized ( this ) {
+ try {
+ while( !shallStop ) {
+ if( alt ) {
+ icomp.repaint(); // issues paint of GLCanvas on AWT-EDT
+ } else if( null != glc ) {
+ // Avoid invokeAndWait(..) in GLCanvas.display() if AWT-EDT dies!
+ glc.repaint(); // issues paint of GLCanvas on AWT-EDT, which then issues display()!
+ }
+ alt = !alt;
+ Thread.sleep(16);
+ if( Thread.interrupted() ) {
+ final InterruptedRuntimeException e = new InterruptedRuntimeException(new InterruptedException("Interrupt detected in loop, thread: "+Thread.currentThread().getName()));
+ throw e;
+ }
+ }
+ } catch (final InterruptedException e) {
+ exception = SourcedInterruptedException.wrap(e);
+ ExceptionUtils.dumpThrowable("", exception);
+ } catch (final Exception e) {
+ exception = e;
+ ExceptionUtils.dumpThrowable("", exception);
+ } finally {
+ isRunning = false;
+ this.notifyAll();
+ }
+ }
+ }
+ }
+
+ static class InterruptableGLEL implements GLEventListener {
+ public volatile InterruptedException exception = null;
+ @Override
+ public void init(final GLAutoDrawable drawable) {
+ }
+ @Override
+ public void dispose(final GLAutoDrawable drawable) {
+ }
+ @Override
+ public void display(final GLAutoDrawable drawable) {
+ final Thread c = Thread.currentThread();
+ if( c.isInterrupted() && null == exception ) {
+ exception = new InterruptedException("Interrupt detected in GLEventListener, thread: "+c.getName());
+ drawable.removeGLEventListener(this);
+ }
+ }
+ @Override
+ public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height) {
+ }
+ }
+
+ static class InterruptingComponent extends Component {
+ private static final long serialVersionUID = 1L;
+ public volatile InterruptedException exception = null;
+
+ private volatile boolean doInterrupt = false;
+
+ private final Color[] colors =
+ new Color[] { Color.BLACK, Color.BLUE, Color.DARK_GRAY, Color.GRAY, Color.LIGHT_GRAY };
+ private int colorIdx = 0;
+
+ public InterruptingComponent() {
+ }
+
+ public void interruptAWTEventQueue() {
+ doInterrupt = true;
+ }
+
+ @Override
+ public void paint(final Graphics g)
+ {
+ final Thread c = Thread.currentThread();
+ if( c.isInterrupted() && null == exception ) {
+ exception = new InterruptedException("Interrupt detected in AWT Component, thread: "+c.getName());
+ }
+
+ g.setColor(colors[colorIdx++]);
+ if( colorIdx >= colors.length ) {
+ colorIdx = 0;
+ }
+ g.fillRect(0, 0, getWidth(), getHeight());
+
+ if(doInterrupt) {
+ System.err.println("Thread "+c.getName()+": *Interrupting*");
+ doInterrupt = false;
+ c.interrupt();
+ }
+ }
+ }
+
+ public static void main(final String[] args) {
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-time")) {
+ durationPerTest = MiscUtils.atol(args[++i], durationPerTest);
+ }
+ }
+ org.junit.runner.JUnitCore.main(TestBug1225EventQueueInterruptedAWT.class.getName());
+ }
+}
+
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug1245JTabbedPanelCrashAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug1245JTabbedPanelCrashAWT.java
new file mode 100644
index 000000000..bc52238bb
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug1245JTabbedPanelCrashAWT.java
@@ -0,0 +1,228 @@
+/**
+ * Copyright 2013 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.BorderLayout;
+import java.awt.Dimension;
+import java.awt.GridLayout;
+import java.lang.reflect.InvocationTargetException;
+
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JTabbedPane;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+import com.jogamp.opengl.GLEventListener;
+import com.jogamp.opengl.GLProfile;
+import com.jogamp.opengl.awt.GLCanvas;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.RedSquareES2;
+import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
+import com.jogamp.opengl.test.junit.util.GLEventListenerCounter;
+import com.jogamp.opengl.test.junit.util.MiscUtils;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+import com.jogamp.opengl.util.Animator;
+
+/**
+ * Bug 1245
+ * <p>
+ * https://jogamp.org/bugzilla/show_bug.cgi?id=1245
+ * </p>
+ */
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class TestBug1245JTabbedPanelCrashAWT extends UITestCase {
+
+ static long durationPerTest = 500*4; // ms
+ static boolean manual = false;
+
+ @SuppressWarnings("serial")
+ static class View3D extends JPanel {
+ final GLCanvas canvas;
+ final Animator animator;
+ final int num;
+
+ public View3D(final int num) {
+ this.num = num;
+ this.setLayout(new BorderLayout());
+ canvas = new GLCanvas();
+ canvas.setSize(new Dimension(100, 100));
+ canvas.setMinimumSize(new Dimension(100, 100));
+ add(canvas, BorderLayout.CENTER);
+ animator = new Animator();
+ animator.add(canvas);
+ // could do animator.start() here as well,
+ // just to be nice - we start/stop at add/remove Notify
+ }
+ @Override
+ public void addNotify() {
+ System.err.println("View3D["+num+"].addNotify()");
+ super.addNotify();
+ if( null != animator ) {
+ animator.start();
+ }
+ }
+ @Override
+ public void removeNotify() {
+ System.err.println("View3D["+num+"].removeNotify()");
+ if( null != animator ) {
+ animator.stop();
+ }
+ super.removeNotify();
+ }
+
+ public String getGLCanvasStats() {
+ return "GLCanvas: comp "+canvas.getBounds()+", visible "+canvas.isVisible()+", showing "+canvas.isShowing()+
+ ", displayable "+canvas.isDisplayable()+", "+canvas.getSurfaceWidth()+"x"+canvas.getSurfaceHeight()+
+ ", "+canvas.getChosenGLCapabilities()+", drawable 0x"+Long.toHexString(canvas.getHandle());
+ }
+ }
+
+ final GLEventListenerCounter glelCounter = new GLEventListenerCounter();
+
+ private JTabbedPane createAndShowGUI(final JFrame frame, final View3D[] views) {
+ final JPanel panel = new JPanel(new GridLayout(1, 1));
+ final JTabbedPane tabbedPanel = new JTabbedPane();
+ for(int i=0; i<views.length; i++) {
+ final GLEventListener demo;
+ if( i%2 == 0 ) {
+ final GearsES2 gears = new GearsES2(1);
+ gears.setVerbose(false);
+ demo = gears;
+ } else {
+ final RedSquareES2 red = new RedSquareES2(1);
+ red.setVerbose(false);
+ demo = red;
+ }
+ views[i] = new View3D(i);
+ views[i].canvas.addGLEventListener(glelCounter);
+ views[i].canvas.addGLEventListener(demo);
+ tabbedPanel.addTab("Tab "+i, null, views[i], "Does nothing");
+ }
+ tabbedPanel.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
+ tabbedPanel.addChangeListener(new javax.swing.event.ChangeListener() {
+ @Override
+ public void stateChanged(final javax.swing.event.ChangeEvent evt) {
+ final int idx = tabbedPanel.getSelectedIndex();
+ if( 0 <= idx && idx < views.length ) {
+ System.err.println("Pane["+idx+"]: State Changed: "+evt);
+ System.err.println("Pane["+idx+"]: "+views[idx].getGLCanvasStats());
+ }
+ }
+ });
+
+ panel.add(tabbedPanel);
+ frame.add(panel, BorderLayout.CENTER);
+ frame.setSize(640,480);
+
+ return tabbedPanel;
+ }
+
+ private static String id(final Object obj) { return "0x"+Integer.toHexString(obj.hashCode()); }
+
+ @BeforeClass
+ public static void startup() {
+ GLProfile.initSingleton();
+ }
+
+ @Test
+ public void test01() throws InterruptedException, InvocationTargetException {
+ final JFrame frame = new JFrame("Java3DApplication");
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+ final View3D[] views = new View3D[4];
+ final JTabbedPane[] tabbedPane = { null };
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ //Turn off metal's use of bold fonts
+ UIManager.put("swing.boldMetal", Boolean.FALSE);
+ tabbedPane[0] = createAndShowGUI(frame, views);
+ System.err.println("XXX SetVisible ON XXX");
+ frame.setVisible(true);
+ } } );
+ Assert.assertEquals(true, AWTRobotUtil.waitForVisible(frame, true));
+ for(int i=0; i<views.length; i++) {
+ System.err.printf("View "+i+": "+views[i]+",%n "+views[i].getGLCanvasStats()+"%n%n");
+ }
+
+ System.err.println("XXX POST.VISIBLE: "+glelCounter);
+ if(manual) {
+ Thread.sleep(durationPerTest);
+ System.err.println("XXX POST.ACTION: "+glelCounter);
+ } else {
+ final JTabbedPane tabbedPanel = tabbedPane[0];
+
+ for(int i=0; i<views.length; i++) {
+ Thread.sleep(durationPerTest/views.length);
+ switchTab(tabbedPanel, views, i, (i+1)%views.length);
+ }
+ Thread.sleep(durationPerTest/views.length);
+ switchTab(tabbedPanel, views, 0, 1);
+
+ Thread.sleep(durationPerTest/views.length);
+ switchTab(tabbedPanel, views, 1, 0);
+
+ System.err.println("XXX POST.ACTION: "+glelCounter);
+ Assert.assertTrue(glelCounter.initCount >= views.length);
+ }
+
+ SwingUtilities.invokeLater(new Runnable() {
+ public void run() {
+ System.err.println("XXX SetVisible OFF XXX");
+ frame.dispose();
+ } });
+ Assert.assertEquals(true, AWTRobotUtil.waitForVisible(frame, false));
+ System.err.println("XXX POST.DISPOSE: "+glelCounter);
+ }
+
+ void switchTab(final JTabbedPane tabbedPanel, final View3D[] views, final int thisId, final int nextId) throws InvocationTargetException, InterruptedException {
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ System.err.println("XXXX Panel("+id(views[thisId])+" -> Panel("+id(views[nextId])+") START");
+ tabbedPanel.setSelectedIndex(nextId);
+ }});
+ }
+
+ public static void main(final String args[]) {
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-time")) {
+ durationPerTest = MiscUtils.atoi(args[++i], (int)durationPerTest);
+ } else if(args[i].equals("-manual")) {
+ manual = true;
+ }
+ }
+ org.junit.runner.JUnitCore.main(TestBug1245JTabbedPanelCrashAWT.class.getName());
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestTranslucencyNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestTranslucencyNEWT.java
index f3c2734b5..dfd2489e2 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestTranslucencyNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestTranslucencyNEWT.java
@@ -28,6 +28,8 @@
package com.jogamp.opengl.test.junit.jogl.caps;
+import com.jogamp.common.util.InterruptSource;
+import com.jogamp.junit.util.JunitTracer;
import com.jogamp.newt.event.KeyAdapter;
import com.jogamp.newt.event.KeyEvent;
import com.jogamp.newt.opengl.GLWindow;
@@ -92,12 +94,12 @@ public class TestTranslucencyNEWT extends UITestCase {
return;
}
if(e.getKeyChar()=='f') {
- new Thread() {
+ new InterruptSource.Thread() {
public void run() {
f_glWindow.setFullscreen(!f_glWindow.isFullscreen());
} }.start();
} else if(e.getKeyChar()=='d') {
- new Thread() {
+ new InterruptSource.Thread() {
public void run() {
f_glWindow.setUndecorated(!f_glWindow.isUndecorated());
} }.start();
@@ -157,7 +159,7 @@ public class TestTranslucencyNEWT extends UITestCase {
}
}
if( waitForKey ) {
- UITestCase.waitForKey("main");
+ JunitTracer.waitForKey("main");
}
org.junit.runner.JUnitCore.main(TestTranslucencyNEWT.class.getName());
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/GLClearOnInitReshape.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/GLClearOnInitReshape.java
new file mode 100644
index 000000000..46be7ef0a
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/GLClearOnInitReshape.java
@@ -0,0 +1,64 @@
+/**
+ * Copyright 2015 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;
+
+import com.jogamp.opengl.GL;
+import com.jogamp.opengl.GLAutoDrawable;
+import com.jogamp.opengl.GLEventListener;
+
+public class GLClearOnInitReshape implements GLEventListener {
+ int lastWidth, lastHeight;
+ boolean doClear;
+
+ @Override
+ public void init(final GLAutoDrawable drawable) {
+ lastWidth = drawable.getSurfaceWidth();
+ lastHeight = drawable.getSurfaceHeight();
+ doClear = true;
+ }
+
+ @Override
+ public void dispose(final GLAutoDrawable drawable) { }
+
+ @Override
+ public void display(final GLAutoDrawable drawable) {
+ if( doClear ) {
+ drawable.getGL().glClear(GL.GL_COLOR_BUFFER_BIT);
+ doClear = false;
+ }
+ }
+
+ @Override
+ public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height) {
+ if( lastHeight != height || lastWidth != width ) {
+ doClear = true;
+ lastWidth = width;
+ lastHeight = height;
+ }
+ }
+}
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
index 7189db1f3..e8acb0baf 100644
--- 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
@@ -181,9 +181,7 @@ public class PointsDemoES1 extends PointsDemo {
// Thread.dumpStack();
final GL2ES1 gl = glad.getGL().getGL2ES1();
- if(-1 != swapInterval) {
- gl.setSwapInterval(swapInterval); // in case switching the drawable (impl. may bound attribute there)
- }
+ gl.setSwapInterval(swapInterval); // in case switching the drawable (impl. may bound attribute there)
// Set location in front of camera
gl.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
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 60ac6b233..7eebf4489 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
@@ -141,9 +141,7 @@ public class RedSquareES1 implements GLEventListener, TileRendererBase.TileRende
@Override
public void reshape(final GLAutoDrawable glad, final int x, final int y, final int width, final int height) {
final GL2ES1 gl = glad.getGL().getGL2ES1();
- if(-1 != swapInterval) {
- gl.setSwapInterval(swapInterval);
- }
+ gl.setSwapInterval(swapInterval);
reshapeImpl(gl, x, y, width, height, width, height);
}
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 771748a33..432652701 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
@@ -28,6 +28,7 @@
package com.jogamp.opengl.test.junit.jogl.demos.es1.newt;
+import com.jogamp.common.util.InterruptSource;
import com.jogamp.newt.event.KeyAdapter;
import com.jogamp.newt.event.KeyEvent;
import com.jogamp.newt.opengl.GLWindow;
@@ -92,12 +93,12 @@ public class TestGearsES1NEWT extends UITestCase {
return;
}
if(e.getKeyChar()=='f') {
- new Thread() {
+ new InterruptSource.Thread() {
public void run() {
f_glWindow.setFullscreen(!f_glWindow.isFullscreen());
} }.start();
} else if(e.getKeyChar()=='d') {
- new Thread() {
+ new InterruptSource.Thread() {
public void run() {
f_glWindow.setUndecorated(!f_glWindow.isUndecorated());
} }.start();
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 9bf04a75f..769183e82 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
@@ -28,6 +28,7 @@
package com.jogamp.opengl.test.junit.jogl.demos.es1.newt;
+import com.jogamp.common.util.InterruptSource;
import com.jogamp.newt.event.KeyAdapter;
import com.jogamp.newt.event.KeyEvent;
import com.jogamp.newt.opengl.GLWindow;
@@ -90,12 +91,12 @@ public class TestRedSquareES1NEWT extends UITestCase {
return;
}
if(e.getKeyChar()=='f') {
- new Thread() {
+ new InterruptSource.Thread() {
public void run() {
f_glWindow.setFullscreen(!f_glWindow.isFullscreen());
} }.start();
} else if(e.getKeyChar()=='d') {
- new Thread() {
+ new InterruptSource.Thread() {
public void run() {
f_glWindow.setUndecorated(!f_glWindow.isUndecorated());
} }.start();
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 ff88af50a..de2d3458a 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
@@ -267,9 +267,7 @@ public class FBOMix2DemosES2 implements GLEventListener {
public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height) {
final GL2ES2 gl = drawable.getGL().getGL2ES2();
- if(-1 != swapInterval) {
- gl.setSwapInterval(swapInterval); // in case switching the drawable (impl. may bound attribute there)
- }
+ gl.setSwapInterval(swapInterval); // in case switching the drawable (impl. may bound attribute there)
System.err.println("**** Reshape: "+width+"x"+height);
resetFBOs(gl, drawable);
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 e1abcc752..c0a4756e7 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
@@ -319,9 +319,7 @@ public class GearsES2 implements StereoGLEventListener, TileRendererBase.TileRen
public void reshape(final GLAutoDrawable glad, final int x, final int y, final int width, final int height) {
if( !isInit ) { return; }
final GL2ES2 gl = glad.getGL().getGL2ES2();
- if(-1 != swapInterval) {
- gl.setSwapInterval(swapInterval);
- }
+ gl.setSwapInterval(swapInterval);
reshapeImpl(gl, x, y, width, height, width, height);
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/LandscapeES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/LandscapeES2.java
index a504ec1ed..18c0ffd68 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/LandscapeES2.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/LandscapeES2.java
@@ -128,9 +128,7 @@ public class LandscapeES2 implements GLEventListener {
final GL2ES2 gl = drawable.getGL().getGL2ES2();
- if(-1 != swapInterval) {
- gl.setSwapInterval(swapInterval); // in case switching the drawable (impl. may bound attribute there)
- }
+ gl.setSwapInterval(swapInterval); // in case switching the drawable (impl. may bound attribute there)
shaderState.useProgram(gl, true);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/LineSquareXDemoES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/LineSquareXDemoES2.java
new file mode 100644
index 000000000..2169b93d0
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/LineSquareXDemoES2.java
@@ -0,0 +1,189 @@
+/**
+ * Copyright (C) 2015 JogAmp Community. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+package com.jogamp.opengl.test.junit.jogl.demos.es2;
+
+import com.jogamp.opengl.GL;
+import com.jogamp.opengl.GL2ES2;
+import com.jogamp.opengl.GLAutoDrawable;
+import com.jogamp.opengl.GLEventListener;
+import com.jogamp.opengl.GLUniformData;
+import com.jogamp.opengl.fixedfunc.GLMatrixFunc;
+
+import com.jogamp.opengl.util.ImmModeSink;
+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 LineSquareXDemoES2 implements GLEventListener {
+
+ private boolean multisample, clearBuffers;
+ private final ShaderState st;
+ private final PMVMatrix pmvMatrix;
+ private ShaderProgram sp0;
+ private GLUniformData pmvMatrixUniform;
+ private ImmModeSink immModeSink;
+
+ public LineSquareXDemoES2(final boolean multisample) {
+ this.multisample = multisample;
+ this.clearBuffers = true;
+ st = new ShaderState();
+ st.setVerbose(true);
+ pmvMatrix = new PMVMatrix();
+ }
+
+ public void setClearBuffers(final boolean v) { clearBuffers = v; }
+
+ public void init(final 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());
+ 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, LineSquareXDemoES2.class, "shader",
+ "shader/bin", "mgl_default_xxx", true);
+ final ShaderCode fp0 = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, LineSquareXDemoES2.class, "shader",
+ "shader/bin", "mgl_default_xxx", true);
+ vp0.defaultShaderCustomization(gl, true, true);
+ fp0.defaultShaderCustomization(gl, true, true);
+
+ sp0 = new ShaderProgram();
+ sp0.add(gl, vp0, System.err);
+ sp0.add(gl, fp0, System.err);
+ st.attachShaderProgram(gl, sp0, true);
+
+ pmvMatrixUniform = new GLUniformData("mgl_PMVMatrix", 4, 4, pmvMatrix.glGetPMvMatrixf());
+ st.ownUniform(pmvMatrixUniform);
+ st.uniform(gl, pmvMatrixUniform);
+
+ final float c = 0f;
+ final float eX = 0.5f;
+ final float eH = 0.98f;
+ final float e2 = 1f;
+
+ // Using predef array names, see
+ // GLPointerFuncUtil.getPredefinedArrayIndexName(glArrayIndex);
+ immModeSink = ImmModeSink.createGLSL(20*2,
+ 3, GL.GL_FLOAT, // vertex
+ 4, GL.GL_FLOAT, // color
+ 0, GL.GL_FLOAT, // normal
+ 0, GL.GL_FLOAT, // texCoords
+ GL.GL_STATIC_DRAW, st);
+ immModeSink.glBegin(GL.GL_LINES);
+
+ // Rectangle
+ immModeSink.glVertex3f(-eX, -eH, 0f); immModeSink.glColor4f( c, c, c, c );
+ immModeSink.glVertex3f(-eX, eH, 0f); immModeSink.glColor4f( c, c, c, c );
+ immModeSink.glVertex3f(-eX, eH, 0f); immModeSink.glColor4f( c, c, c, c );
+ immModeSink.glVertex3f( eX, eH, 0f); immModeSink.glColor4f( c, c, c, c );
+ immModeSink.glVertex3f( eX, eH, 0f); immModeSink.glColor4f( c, c, c, c );
+ immModeSink.glVertex3f( eX, -eH, 0f); immModeSink.glColor4f( c, c, c, c );
+ immModeSink.glVertex3f( eX, -eH, 0f); immModeSink.glColor4f( c, c, c, c );
+ immModeSink.glVertex3f(-eX, -eH, 0f); immModeSink.glColor4f( c, c, c, c );
+
+ // Square
+ immModeSink.glVertex3f(-eH, -eH, 0f); immModeSink.glColor4f( c, c, c, c );
+ immModeSink.glVertex3f(-eH, eH, 0f); immModeSink.glColor4f( c, c, c, c );
+ immModeSink.glVertex3f(-eH, eH, 0f); immModeSink.glColor4f( c, c, c, c );
+ immModeSink.glVertex3f( eH, eH, 0f); immModeSink.glColor4f( c, c, c, c );
+ immModeSink.glVertex3f( eH, eH, 0f); immModeSink.glColor4f( c, c, c, c );
+ immModeSink.glVertex3f( eH, -eH, 0f); immModeSink.glColor4f( c, c, c, c );
+ immModeSink.glVertex3f( eH, -eH, 0f); immModeSink.glColor4f( c, c, c, c );
+ immModeSink.glVertex3f(-eH, -eH, 0f); immModeSink.glColor4f( c, c, c, c );
+
+ // X
+ immModeSink.glVertex3f(-e2, -e2, 0f); immModeSink.glColor4f( c, c, c, c );
+ immModeSink.glVertex3f( e2, e2, 0f); immModeSink.glColor4f( c, c, c, c );
+ immModeSink.glVertex3f(-e2, e2, 0f); immModeSink.glColor4f( c, c, c, c );
+ immModeSink.glVertex3f( e2, -e2, 0f); immModeSink.glColor4f( c, c, c, c );
+
+ immModeSink.glEnd(gl, false);
+
+ st.useProgram(gl, false);
+ }
+
+ public void dispose(final GLAutoDrawable glad) {
+ final GL2ES2 gl = glad.getGL().getGL2ES2();
+ immModeSink.destroy(gl);
+ immModeSink = null;
+ st.destroy(gl);
+ }
+
+ public void display(final GLAutoDrawable glad) {
+ final GL2ES2 gl = glad.getGL().getGL2ES2();
+ if (multisample) {
+ gl.glEnable(GL.GL_MULTISAMPLE);
+ }
+ if( clearBuffers ) {
+ final float c = 0.9f;
+ gl.glClearColor(c, c, c, 0);
+ // gl.glEnable(GL.GL_DEPTH_TEST);
+ // gl.glDepthFunc(GL.GL_LESS);
+ gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
+ }
+
+ st.useProgram(gl, true);
+
+ immModeSink.draw(gl, true);
+
+ st.useProgram(gl, false);
+ }
+
+ // Unused routines
+ public void reshape(final GLAutoDrawable glad, final int x, final int y, final int width, final int height) {
+ System.err.println("reshape ..");
+ final GL2ES2 gl = glad.getGL().getGL2ES2();
+ pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
+ pmvMatrix.glLoadIdentity();
+ final float left, right, bottom, top;
+ if( height > width ) {
+ final float a = (float)height / (float)width;
+ left = -1.0f;
+ right = 1.0f;
+ bottom = -a;
+ top = a;
+ } else {
+ final float a = (float)width / (float)height;
+ left = -a;
+ right = a;
+ bottom = -1.0f;
+ top = 1.0f;
+ }
+ // pmvMatrix.glOrthof(-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f);
+ // pmvMatrix.glOrthof(-1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 10.0f);
+ pmvMatrix.glOrthof(left, right, top, bottom, 0.0f, 10.0f);
+ pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
+ pmvMatrix.glLoadIdentity();
+
+ st.useProgram(gl, true);
+ st.uniform(gl, pmvMatrixUniform);
+ st.useProgram(gl, false);
+ }
+
+ public void displayChanged(final GLAutoDrawable drawable, final boolean modeChanged, final boolean deviceChanged) {
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/Mix2TexturesES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/Mix2TexturesES2.java
index 6d202707e..3ec383ad8 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/Mix2TexturesES2.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/Mix2TexturesES2.java
@@ -181,9 +181,7 @@ public class Mix2TexturesES2 implements GLEventListener {
public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height) {
final GL2ES2 gl = drawable.getGL().getGL2ES2();
- if(-1 != swapInterval) {
- gl.setSwapInterval(swapInterval); // in case switching the drawable (impl. may bound attribute there)
- }
+ gl.setSwapInterval(swapInterval); // in case switching the drawable (impl. may bound attribute there)
pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
pmvMatrix.glLoadIdentity();
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/PointsDemoES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/PointsDemoES2.java
index 673552c5f..d59c1bb84 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/PointsDemoES2.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/PointsDemoES2.java
@@ -186,9 +186,7 @@ public class PointsDemoES2 extends PointsDemo {
// Thread.dumpStack();
final GL2ES2 gl = glad.getGL().getGL2ES2();
- if(-1 != swapInterval) {
- gl.setSwapInterval(swapInterval); // in case switching the drawable (impl. may bound attribute there)
- }
+ gl.setSwapInterval(swapInterval); // in case switching the drawable (impl. may bound attribute there)
st.useProgram(gl, true);
// Set location in front of camera
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 a0afef87a..eb96d1593 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
@@ -52,6 +52,7 @@ public class RedSquareES2 implements GLEventListener, TileRendererBase.TileRende
private int swapInterval = 0;
private float aspect = 1.0f;
private boolean doRotate = true;
+ private boolean verbose = true;
private boolean clearBuffers = true;
private TileRendererBase tileRendererInUse = null;
private boolean doRotateBeforePrinting;
@@ -87,16 +88,21 @@ public class RedSquareES2 implements GLEventListener, TileRendererBase.TileRende
public void setAspect(final float aspect) { this.aspect = aspect; }
public void setDoRotation(final boolean rotate) { this.doRotate = rotate; }
public void setClearBuffers(final boolean v) { clearBuffers = v; }
+ public void setVerbose(final boolean v) { verbose = v; }
@Override
public void init(final GLAutoDrawable glad) {
- System.err.println(Thread.currentThread()+" RedSquareES2.init: tileRendererInUse "+tileRendererInUse);
+ if(verbose) {
+ System.err.println(Thread.currentThread()+" RedSquareES2.init: tileRendererInUse "+tileRendererInUse);
+ }
final GL2ES2 gl = glad.getGL().getGL2ES2();
- 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(JoglVersion.getGLStrings(gl, null, false).toString());
+ if(verbose) {
+ 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(JoglVersion.getGLStrings(gl, null, false).toString());
+ }
if( !gl.hasGLSL() ) {
System.err.println("No GLSL available, no rendering.");
return;
@@ -149,7 +155,9 @@ public class RedSquareES2 implements GLEventListener, TileRendererBase.TileRende
st.useProgram(gl, false);
t0 = System.currentTimeMillis();
- System.err.println(Thread.currentThread()+" RedSquareES2.init FIN");
+ if(verbose) {
+ System.err.println(Thread.currentThread()+" RedSquareES2.init FIN");
+ }
}
@Override
@@ -192,9 +200,7 @@ public class RedSquareES2 implements GLEventListener, TileRendererBase.TileRende
@Override
public void reshape(final GLAutoDrawable glad, final int x, final int y, final int width, final int height) {
final GL2ES2 gl = glad.getGL().getGL2ES2();
- if(-1 != swapInterval) {
- gl.setSwapInterval(swapInterval);
- }
+ gl.setSwapInterval(swapInterval);
reshapeImpl(gl, x, y, width, height, width, height);
}
@@ -208,7 +214,9 @@ public class RedSquareES2 implements GLEventListener, TileRendererBase.TileRende
}
void reshapeImpl(final GL2ES2 gl, final int tileX, final int tileY, final int tileWidth, final int tileHeight, final int imageWidth, final int imageHeight) {
- System.err.println(Thread.currentThread()+" RedSquareES2.reshape "+tileX+"/"+tileY+" "+tileWidth+"x"+tileHeight+" of "+imageWidth+"x"+imageHeight+", swapInterval "+swapInterval+", drawable 0x"+Long.toHexString(gl.getContext().getGLDrawable().getHandle())+", tileRendererInUse "+tileRendererInUse);
+ if(verbose) {
+ System.err.println(Thread.currentThread()+" RedSquareES2.reshape "+tileX+"/"+tileY+" "+tileWidth+"x"+tileHeight+" of "+imageWidth+"x"+imageHeight+", swapInterval "+swapInterval+", drawable 0x"+Long.toHexString(gl.getContext().getGLDrawable().getHandle())+", tileRendererInUse "+tileRendererInUse);
+ }
// Thread.dumpStack();
if( !gl.hasGLSL() ) {
return;
@@ -249,7 +257,9 @@ public class RedSquareES2 implements GLEventListener, TileRendererBase.TileRende
@Override
public void dispose(final GLAutoDrawable glad) {
- System.err.println(Thread.currentThread()+" RedSquareES2.dispose: tileRendererInUse "+tileRendererInUse);
+ if(verbose) {
+ System.err.println(Thread.currentThread()+" RedSquareES2.dispose: tileRendererInUse "+tileRendererInUse);
+ }
final GL2ES2 gl = glad.getGL().getGL2ES2();
if( !gl.hasGLSL() ) {
return;
@@ -257,6 +267,8 @@ public class RedSquareES2 implements GLEventListener, TileRendererBase.TileRende
st.destroy(gl);
st = null;
pmvMatrix = null;
- System.err.println(Thread.currentThread()+" RedSquareES2.dispose FIN");
+ if(verbose) {
+ System.err.println(Thread.currentThread()+" RedSquareES2.dispose FIN");
+ }
}
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareMappedES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareMappedES2.java
index 9dab97d16..3b526401d 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareMappedES2.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareMappedES2.java
@@ -211,9 +211,7 @@ public class RedSquareMappedES2 implements GLEventListener, TileRendererBase.Til
@Override
public void reshape(final GLAutoDrawable glad, final int x, final int y, final int width, final int height) {
final GL2ES2 gl = glad.getGL().getGL2ES2();
- if(-1 != swapInterval) {
- gl.setSwapInterval(swapInterval);
- }
+ gl.setSwapInterval(swapInterval);
reshapeImpl(gl, x, y, width, height, width, height);
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureDraw02ES2ListenerFBO.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureDraw02ES2ListenerFBO.java
index 2d6745594..e360b5987 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureDraw02ES2ListenerFBO.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureDraw02ES2ListenerFBO.java
@@ -230,9 +230,7 @@ public class TextureDraw02ES2ListenerFBO implements GLEventListener {
public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height) {
final GL2ES2 gl = drawable.getGL().getGL2ES2();
- if(-1 != swapInterval) {
- gl.setSwapInterval(swapInterval); // in case switching the drawable (impl. may bound attribute there)
- }
+ gl.setSwapInterval(swapInterval); // in case switching the drawable (impl. may bound attribute there)
System.err.println("**** Reshape.Reset: "+width+"x"+height);
if( keepTextureBound ) {
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/CrossFadePlayer.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/CrossFadePlayer.java
index b2ebc7068..cc4096672 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/CrossFadePlayer.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/CrossFadePlayer.java
@@ -29,6 +29,7 @@
package com.jogamp.opengl.test.junit.jogl.demos.es2.av;
import com.jogamp.common.net.Uri;
+import com.jogamp.common.util.InterruptSource;
import com.jogamp.opengl.util.av.AudioSink;
import com.jogamp.opengl.util.av.GLMediaPlayer;
import com.jogamp.opengl.util.av.GLMediaPlayer.GLMediaEventListener;
@@ -73,7 +74,7 @@ public class CrossFadePlayer
System.out.println("Duration: " + mp.getDuration() + "ms");
System.out.println("Volume: " + mp.getAudioVolume());
System.out.println("player.initGL()...");
- new Thread() {
+ new InterruptSource.Thread() {
public void run() {
try {
mp.initGL(null);
@@ -98,7 +99,7 @@ public class CrossFadePlayer
stop = true;
} else {
System.err.println("Player State: EOS");
- new Thread() {
+ new InterruptSource.Thread() {
public void run() {
System.out.println("mp.setPlaySpeed(1f) returned: " + mp.setPlaySpeed(1f));
mp.seek(0);
@@ -112,7 +113,7 @@ public class CrossFadePlayer
if( null != se ) {
se.printStackTrace();
}
- new Thread() {
+ new InterruptSource.Thread() {
public void run() {
System.out.println("terminating...");
stop = true;
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieCube.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieCube.java
index b938adb53..a8dede526 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieCube.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieCube.java
@@ -42,10 +42,12 @@ import com.jogamp.opengl.GLException;
import com.jogamp.opengl.GLProfile;
import com.jogamp.common.net.Uri;
+import com.jogamp.common.util.InterruptSource;
import com.jogamp.graph.curve.Region;
import com.jogamp.graph.curve.opengl.GLRegion;
import com.jogamp.graph.curve.opengl.RegionRenderer;
import com.jogamp.graph.font.Font;
+import com.jogamp.junit.util.JunitTracer;
import com.jogamp.newt.Window;
import com.jogamp.newt.event.KeyAdapter;
import com.jogamp.newt.event.KeyEvent;
@@ -57,7 +59,6 @@ import com.jogamp.opengl.JoglVersion;
import com.jogamp.opengl.test.junit.graph.TextRendererGLELBase;
import com.jogamp.opengl.test.junit.jogl.demos.es2.TextureSequenceCubeES2;
import com.jogamp.opengl.test.junit.util.MiscUtils;
-import com.jogamp.opengl.test.junit.util.UITestCase;
import com.jogamp.opengl.util.Animator;
import com.jogamp.opengl.util.av.GLMediaPlayer;
import com.jogamp.opengl.util.av.GLMediaPlayer.GLMediaEventListener;
@@ -75,7 +76,7 @@ public class MovieCube implements GLEventListener {
private TextureSequenceCubeES2 cube=null;
private GLMediaPlayer mPlayer=null;
private int swapInterval = 1;
- private int swapIntervalSet = -1;
+ private boolean swapIntervalSet = true;
private long lastPerfPos = 0;
private volatile boolean resetGLState = false;
@@ -116,7 +117,7 @@ public class MovieCube implements GLEventListener {
resetGLState();
}
if( 0 != ( GLMediaEventListener.EVENT_CHANGE_EOS & event_mask ) ) {
- new Thread() {
+ new InterruptSource.Thread() {
public void run() {
// loop for-ever ..
mPlayer.seek(0);
@@ -246,7 +247,7 @@ public class MovieCube implements GLEventListener {
final String text1 = String.format("%0"+ptsPrec+"f/%0"+ptsPrec+"f s, %s (%01.2fx, vol %01.2f), a %01.2f, fps %02.1f -> %02.1f / %02.1f, v-sync %d",
pts, mPlayer.getDuration() / 1000f,
mPlayer.getState().toString().toLowerCase(), mPlayer.getPlaySpeed(), mPlayer.getAudioVolume(),
- aspect, mPlayer.getFramerate(), lfps, tfps, swapIntervalSet);
+ aspect, mPlayer.getFramerate(), lfps, tfps, swapInterval);
final String text2 = String.format("audio: id %d, kbps %d, codec %s",
mPlayer.getAID(), mPlayer.getAudioBitrate()/1000, mPlayer.getAudioCodec());
final String text3 = String.format("video: id %d, kbps %d, codec %s",
@@ -278,10 +279,13 @@ public class MovieCube implements GLEventListener {
int pts1 = 0;
switch(e.getKeySymbol()) {
case KeyEvent.VK_V: {
- switch(swapIntervalSet) {
- case 0: swapInterval = 1; break;
- default: swapInterval = 0; break;
+ switch(swapInterval) {
+ case 0: swapInterval = -1; break;
+ case -1: swapInterval = 1; break;
+ case 1: swapInterval = 0; break;
+ default: swapInterval = 1; break;
}
+ swapIntervalSet = true;
break;
}
case KeyEvent.VK_O: displayOSD = !displayOSD; break;
@@ -362,7 +366,7 @@ public class MovieCube implements GLEventListener {
cube = new TextureSequenceCubeES2(mPlayer, false, zoom0, rotx, roty);
if(waitForKey) {
- UITestCase.waitForKey("Init>");
+ JunitTracer.waitForKey("Init>");
}
if( GLMediaPlayer.State.Initialized == mPlayer.getState() ) {
@@ -433,12 +437,14 @@ public class MovieCube implements GLEventListener {
@Override
public void display(final GLAutoDrawable drawable) {
- if(-1 != swapInterval) {
+ if( swapIntervalSet ) {
final GL2ES2 gl = drawable.getGL().getGL2ES2();
- gl.setSwapInterval(swapInterval); // in case switching the drawable (impl. may bound attribute there)
+ final int _swapInterval = swapInterval;
+ gl.setSwapInterval(_swapInterval); // in case switching the drawable (impl. may bound attribute there)
drawable.getAnimator().resetFPSCounter();
- swapIntervalSet = swapInterval;
- swapInterval = -1;
+ swapInterval = gl.getSwapInterval();
+ System.err.println("Swap Interval: "+_swapInterval+" -> "+swapInterval);
+ swapIntervalSet = false;
}
if(null == mPlayer) { return; }
@@ -594,7 +600,7 @@ public class MovieCube implements GLEventListener {
if( null != se ) {
se.printStackTrace();
}
- new Thread() {
+ new InterruptSource.Thread() {
public void run() {
window.destroy();
} }.start();
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSBSStereo.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSBSStereo.java
index e936bf991..9b9073721 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSBSStereo.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSBSStereo.java
@@ -42,6 +42,7 @@ import com.jogamp.opengl.fixedfunc.GLMatrixFunc;
import com.jogamp.common.net.Uri;
import com.jogamp.common.os.Platform;
+import com.jogamp.common.util.InterruptSource;
import com.jogamp.graph.curve.Region;
import com.jogamp.graph.curve.opengl.GLRegion;
import com.jogamp.graph.curve.opengl.RegionRenderer;
@@ -800,7 +801,7 @@ public class MovieSBSStereo implements StereoGLEventListener {
static class StereoGLMediaEventListener implements GLMediaEventListener {
void destroyWindow(final Window window) {
- new Thread() {
+ new InterruptSource.Thread() {
public void run() {
window.destroy();
} }.start();
@@ -846,7 +847,7 @@ public class MovieSBSStereo implements StereoGLEventListener {
destroy = true;
} else {
System.err.println("MovieSimple State: EOS");
- new Thread() {
+ new InterruptSource.Thread() {
public void run() {
mp.setPlaySpeed(1f);
mp.seek(0);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java
index 22dfa923e..25ce93597 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java
@@ -47,10 +47,12 @@ import com.jogamp.opengl.fixedfunc.GLMatrixFunc;
import com.jogamp.common.net.Uri;
import com.jogamp.common.os.Platform;
+import com.jogamp.common.util.InterruptSource;
import com.jogamp.graph.curve.Region;
import com.jogamp.graph.curve.opengl.GLRegion;
import com.jogamp.graph.curve.opengl.RegionRenderer;
import com.jogamp.graph.font.Font;
+import com.jogamp.junit.util.JunitTracer;
import com.jogamp.newt.Window;
import com.jogamp.newt.event.KeyAdapter;
import com.jogamp.newt.event.KeyEvent;
@@ -65,7 +67,6 @@ import com.jogamp.opengl.GLExtensions;
import com.jogamp.opengl.JoglVersion;
import com.jogamp.opengl.test.junit.graph.TextRendererGLELBase;
import com.jogamp.opengl.test.junit.util.MiscUtils;
-import com.jogamp.opengl.test.junit.util.UITestCase;
import com.jogamp.opengl.util.Animator;
import com.jogamp.opengl.util.GLArrayDataServer;
import com.jogamp.opengl.util.PMVMatrix;
@@ -105,7 +106,7 @@ public class MovieSimple implements GLEventListener {
private int effects = EFFECT_NORMAL;
private float alpha = 1.0f;
private int swapInterval = 1;
- private int swapIntervalSet = -1;
+ private boolean swapIntervalSet = true;
private GLMediaPlayer mPlayer;
private final boolean mPlayerShared;
@@ -185,7 +186,7 @@ public class MovieSimple implements GLEventListener {
final float aspect = (float)mPlayer.getWidth() / (float)mPlayer.getHeight();
final String ptsPrec = null != regionFPS ? "3.1" : "3.0";
- final String text1 = String.format("%0"+ptsPrec+"f/%0"+ptsPrec+"f s, %s (%01.2fx, vol %01.2f), a %01.2f, fps %02.1f -> %02.1f / %02.1f, v-sync %d",
+ final String text1 = String.format("%0"+ptsPrec+"f/%0"+ptsPrec+"f s, %s (%01.2fx, vol %01.2f), a %01.2f, fps %02.1f -> %02.1f / %02.1f, v-sync %b",
pts, mPlayer.getDuration() / 1000f,
mPlayer.getState().toString().toLowerCase(), mPlayer.getPlaySpeed(), mPlayer.getAudioVolume(),
aspect, mPlayer.getFramerate(), lfps, tfps, swapIntervalSet);
@@ -265,10 +266,13 @@ public class MovieSimple implements GLEventListener {
int pts1 = 0;
switch(e.getKeySymbol()) {
case KeyEvent.VK_V: {
- switch(swapIntervalSet) {
- case 0: swapInterval = 1; break;
- default: swapInterval = 0; break;
+ switch(swapInterval) {
+ case 0: swapInterval = -1; break;
+ case -1: swapInterval = 1; break;
+ case 1: swapInterval = 0; break;
+ default: swapInterval = 1; break;
}
+ swapIntervalSet = true;
break;
}
case KeyEvent.VK_O: displayOSD = !displayOSD; break;
@@ -352,7 +356,7 @@ public class MovieSimple implements GLEventListener {
resetGLState();
}
if( 0 != ( GLMediaEventListener.EVENT_CHANGE_EOS & event_mask ) ) {
- new Thread() {
+ new InterruptSource.Thread() {
public void run() {
// loop for-ever ..
mPlayer.seek(0);
@@ -483,7 +487,7 @@ public class MovieSimple implements GLEventListener {
", "+drawable.getClass().getName()+", "+drawable);
if(waitForKey) {
- UITestCase.waitForKey("Init>");
+ JunitTracer.waitForKey("Init>");
}
final Texture tex;
try {
@@ -736,11 +740,13 @@ public class MovieSimple implements GLEventListener {
@Override
public void display(final GLAutoDrawable drawable) {
final GL2ES2 gl = drawable.getGL().getGL2ES2();
- if(-1 != swapInterval) {
- gl.setSwapInterval(swapInterval); // in case switching the drawable (impl. may bound attribute there)
+ if( swapIntervalSet ) {
+ final int _swapInterval = swapInterval;
+ gl.setSwapInterval(_swapInterval); // in case switching the drawable (impl. may bound attribute there)
drawable.getAnimator().resetFPSCounter();
- swapIntervalSet = swapInterval;
- swapInterval = -1;
+ swapInterval = gl.getSwapInterval();
+ System.err.println("Swap Interval: "+_swapInterval+" -> "+swapInterval);
+ swapIntervalSet = false;
}
if(null == mPlayer) { return; }
@@ -802,7 +808,7 @@ public class MovieSimple implements GLEventListener {
static class MyGLMediaEventListener implements GLMediaEventListener {
void destroyWindow(final Window window) {
- new Thread() {
+ new InterruptSource.Thread() {
public void run() {
window.destroy();
} }.start();
@@ -836,7 +842,7 @@ public class MovieSimple implements GLEventListener {
/**
* Kick off player w/o GLEventListener, i.e. for audio only.
*
- new Thread() {
+ new InterruptSource.Thread() {
public void run() {
try {
mp.initGL(null);
@@ -868,7 +874,7 @@ public class MovieSimple implements GLEventListener {
} else {
System.err.println("MovieSimple State: EOS");
if( loopEOS ) {
- new Thread() {
+ new InterruptSource.Thread() {
public void run() {
mp.setPlaySpeed(1f);
mp.seek(0);
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 2e805d8fd..503878c65 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
@@ -158,7 +158,15 @@ public class TestGearsES2AWT extends UITestCase {
private void setTitle(final Frame frame, final GLCanvas glc, final GLCapabilitiesImmutable caps) {
final String capsA = caps.isBackgroundOpaque() ? "opaque" : "transl";
final java.awt.Rectangle b = glc.getBounds();
- frame.setTitle("GLCanvas["+capsA+"], swapI "+swapInterval+", win: ["+b.x+"/"+b.y+" "+b.width+"x"+b.height+"], pix: "+glc.getSurfaceWidth()+"x"+glc.getSurfaceHeight());
+ final float[] minSurfacePixelScale = glc.getMinimumSurfaceScale(new float[2]);
+ final float[] maxSurfacePixelScale = glc.getMaximumSurfaceScale(new float[2]);
+ final float[] reqSurfacePixelScale = glc.getRequestedSurfaceScale(new float[2]);
+ final float[] hasSurfacePixelScale = glc.getCurrentSurfaceScale(new float[2]);
+ frame.setTitle("GLCanvas["+capsA+"], swapI "+swapInterval+", win: ["+b.x+"/"+b.y+" "+b.width+"x"+b.height+"], pix: "+glc.getSurfaceWidth()+"x"+glc.getSurfaceHeight()+
+ ", scale[min "+minSurfacePixelScale[0]+"x"+minSurfacePixelScale[1]+", max "+
+ maxSurfacePixelScale[0]+"x"+maxSurfacePixelScale[1]+", req "+
+ reqSurfacePixelScale[0]+"x"+reqSurfacePixelScale[1]+" -> has "+
+ hasSurfacePixelScale[0]+"x"+hasSurfacePixelScale[1]+"]");
}
protected void runTestGL(final GLCapabilities caps, final ResizeBy resizeBy, final FrameLayout frameLayout) throws InterruptedException, InvocationTargetException {
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2GLJPanelAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2GLJPanelAWT.java
index dfc2d1165..a41e4b9e7 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2GLJPanelAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2GLJPanelAWT.java
@@ -31,6 +31,8 @@ package com.jogamp.opengl.test.junit.jogl.demos.es2.awt;
import java.awt.AWTException;
import java.awt.BorderLayout;
import java.awt.Dimension;
+import java.awt.event.ComponentEvent;
+import java.awt.event.ComponentListener;
import java.lang.reflect.InvocationTargetException;
import com.jogamp.nativewindow.ScalableSurface;
@@ -63,6 +65,7 @@ import com.jogamp.newt.event.TraceKeyAdapter;
import com.jogamp.newt.event.TraceWindowAdapter;
import com.jogamp.newt.event.awt.AWTKeyAdapter;
import com.jogamp.newt.event.awt.AWTWindowAdapter;
+import com.jogamp.opengl.test.junit.jogl.demos.GLClearOnInitReshape;
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;
@@ -78,6 +81,7 @@ public class TestGearsES2GLJPanelAWT extends UITestCase {
static boolean forceES3 = false;
static boolean forceGL3 = false;
static boolean forceGLFFP = false;
+ static int demoType = 1;
static boolean shallUsePBuffer = false;
static boolean shallUseBitmap = false;
static boolean useMSAA = false;
@@ -118,17 +122,41 @@ public class TestGearsES2GLJPanelAWT extends UITestCase {
private void setTitle(final JFrame frame, final GLJPanel glc, final GLCapabilitiesImmutable caps) {
final String capsA = caps.isBackgroundOpaque() ? "opaque" : "transl";
final java.awt.Rectangle b = glc.getBounds();
- frame.setTitle("GLJPanel["+capsA+"], swapI "+swapInterval+", win: ["+b.x+"/"+b.y+" "+b.width+"x"+b.height+"], pix: "+glc.getSurfaceWidth()+"x"+glc.getSurfaceHeight());
+
+ final float[] minSurfacePixelScale = glc.getMinimumSurfaceScale(new float[2]);
+ final float[] maxSurfacePixelScale = glc.getMaximumSurfaceScale(new float[2]);
+ final float[] reqSurfacePixelScale = glc.getRequestedSurfaceScale(new float[2]);
+ final float[] hasSurfacePixelScale = glc.getCurrentSurfaceScale(new float[2]);
+ frame.setTitle("GLJPanel["+capsA+"], swapI "+swapInterval+", win: ["+b.x+"/"+b.y+" "+b.width+"x"+b.height+"], pix: "+glc.getSurfaceWidth()+"x"+glc.getSurfaceHeight()+
+ ", scale[min "+minSurfacePixelScale[0]+"x"+minSurfacePixelScale[1]+", max "+
+ maxSurfacePixelScale[0]+"x"+maxSurfacePixelScale[1]+", req "+
+ reqSurfacePixelScale[0]+"x"+reqSurfacePixelScale[1]+" -> has "+
+ hasSurfacePixelScale[0]+"x"+hasSurfacePixelScale[1]+"]");
}
- protected void runTestGL(final GLCapabilities caps)
+ protected GLEventListener createDemo(final GLCapabilities caps) {
+ final GLEventListener demo;
+ if( 1 == demoType ) {
+ if( caps.isBitmap() || caps.getGLProfile().isGL2() ) {
+ final Gears gears = new Gears(swapInterval);
+ gears.setFlipVerticalInGLOrientation(skipGLOrientationVerticalFlip);
+ demo = gears;
+ } else {
+ final GearsES2 gears = new GearsES2(swapInterval);
+ gears.setFlipVerticalInGLOrientation(skipGLOrientationVerticalFlip);
+ demo = gears;
+ }
+ } else if( 0 == demoType ) {
+ demo = new GLClearOnInitReshape();
+ } else {
+ demo = null;
+ }
+ return demo;
+ }
+
+ protected GLJPanel newGLJPanel(final JFrame frame, final GLCapabilities caps, final FPSAnimator animator, final SnapshotGLEventListener snap)
throws AWTException, InterruptedException, InvocationTargetException
{
- System.err.println("Requesting: "+caps);
-
- final JFrame frame = new JFrame("Swing GLJPanel");
- Assert.assertNotNull(frame);
-
final GLJPanel glJPanel = new GLJPanel(caps);
Assert.assertNotNull(glJPanel);
glJPanel.setSkipGLOrientationVerticalFlip(skipGLOrientationVerticalFlip);
@@ -136,18 +164,15 @@ public class TestGearsES2GLJPanelAWT extends UITestCase {
glJPanel.setPreferredSize(wsize);
glJPanel.setSize(wsize);
glJPanel.setSurfaceScale(reqSurfacePixelScale);
- final float[] valReqSurfacePixelScale = glJPanel.getRequestedSurfaceScale(new float[2]);
- if( caps.isBitmap() || caps.getGLProfile().isGL2() ) {
- final Gears gears = new Gears(swapInterval);
- gears.setFlipVerticalInGLOrientation(skipGLOrientationVerticalFlip);
- glJPanel.addGLEventListener(gears);
- } else {
- final GearsES2 gears = new GearsES2(swapInterval);
- gears.setFlipVerticalInGLOrientation(skipGLOrientationVerticalFlip);
- glJPanel.addGLEventListener(gears);
+ {
+ final GLEventListener demo = createDemo(caps);
+ if( null != demo ) {
+ glJPanel.addGLEventListener(demo);
+ }
+ }
+ if( null != snap ) {
+ glJPanel.addGLEventListener(snap);
}
- final SnapshotGLEventListener snap = new SnapshotGLEventListener();
- glJPanel.addGLEventListener(snap);
glJPanel.addGLEventListener(new GLEventListener() {
@Override
public void init(final GLAutoDrawable drawable) { }
@@ -159,42 +184,128 @@ public class TestGearsES2GLJPanelAWT extends UITestCase {
public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height) {
setTitle(frame, glJPanel, caps);
}
+
});
setTitle(frame, glJPanel, caps);
- frame.setLocation(xpos, ypos);
- final FPSAnimator animator = useAnimator ? new FPSAnimator(glJPanel, 60) : null;
+ frame.addComponentListener(new ComponentListener() {
+ @Override
+ public void componentResized(final ComponentEvent e) {
+ setTitle(frame, glJPanel, caps);
+ }
+
+ @Override
+ public void componentMoved(final ComponentEvent e) {
+ setTitle(frame, glJPanel, caps);
+ }
- SwingUtilities.invokeAndWait(new Runnable() {
- public void run() {
- frame.getContentPane().add(glJPanel, BorderLayout.CENTER);
- frame.getContentPane().validate();
- frame.pack();
- frame.setVisible(true);
- } } ) ;
- Assert.assertEquals(true, AWTRobotUtil.waitForVisible(frame, true));
- Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glJPanel, true));
+ @Override
+ public void componentShown(final ComponentEvent e) { }
- final Screen screen = NewtFactoryAWT.createScreen(glJPanel, true);
- screen.addReference(); // initial native creation - keep alive!
- System.err.println("GetPixelScale: AWT -> Screen: "+screen);
+ @Override
+ public void componentHidden(final ComponentEvent e) { }
+ });
- final float[] hasSurfacePixelScale1 = glJPanel.getCurrentSurfaceScale(new float[2]);
- System.err.println("HiDPI PixelScale: "+reqSurfacePixelScale[0]+"x"+reqSurfacePixelScale[1]+" (req) -> "+
- valReqSurfacePixelScale[0]+"x"+valReqSurfacePixelScale[1]+" (val) -> "+
- hasSurfacePixelScale1[0]+"x"+hasSurfacePixelScale1[1]+" (has)");
- setTitle(frame, glJPanel, caps);
+ if( SwingUtilities.isEventDispatchThread() ) {
+ frame.getContentPane().add(glJPanel, BorderLayout.CENTER);
+ frame.getContentPane().validate();
+ frame.pack();
+ frame.setVisible(true);
+ } else {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ frame.getContentPane().add(glJPanel, BorderLayout.CENTER);
+ frame.getContentPane().validate();
+ frame.pack();
+ frame.setVisible(true);
+ } } ) ;
+ Assert.assertEquals(true, AWTRobotUtil.waitForVisible(frame, true));
+ Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glJPanel, true));
+
+ final float[] minSurfacePixelScale = glJPanel.getMinimumSurfaceScale(new float[2]);
+ final float[] maxSurfacePixelScale = glJPanel.getMaximumSurfaceScale(new float[2]);
+ final float[] valReqSurfacePixelScale = glJPanel.getRequestedSurfaceScale(new float[2]);
+ final float[] hasSurfacePixelScale = glJPanel.getCurrentSurfaceScale(new float[2]);
+ System.err.println("HiDPI PixelScale: min "+
+ minSurfacePixelScale[0]+"x"+minSurfacePixelScale[1]+", max "+
+ maxSurfacePixelScale[0]+"x"+maxSurfacePixelScale[1]+", req "+
+ reqSurfacePixelScale[0]+"x"+reqSurfacePixelScale[1]+" -> val "+
+ valReqSurfacePixelScale[0]+"x"+valReqSurfacePixelScale[1]+" -> has "+
+ hasSurfacePixelScale[0]+"x"+hasSurfacePixelScale[1]);
+ setTitle(frame, glJPanel, caps);
+ }
- if( useAnimator ) {
+ if( null != animator ) {
+ animator.add(glJPanel);
animator.setUpdateFPSFrames(60, System.err);
+ }
+ return glJPanel;
+ }
+
+ protected void destroy(final JFrame frame, final GLJPanel glJPanel) {
+ try {
+ if( SwingUtilities.isEventDispatchThread() ) {
+ if( null != frame ) {
+ frame.setVisible(false);
+ if( null != glJPanel ) {
+ frame.getContentPane().remove(glJPanel);
+ }
+ frame.remove(glJPanel);
+ }
+ if( null != glJPanel ) {
+ glJPanel.destroy();
+ }
+ if( null != frame ) {
+ frame.dispose();
+ }
+ } else {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ if( null != frame ) {
+ frame.setVisible(false);
+ if( null != glJPanel ) {
+ frame.getContentPane().remove(glJPanel);
+ }
+ frame.remove(glJPanel);
+ }
+ if( null != glJPanel ) {
+ glJPanel.destroy();
+ }
+ if( null != frame ) {
+ frame.dispose();
+ }
+ } } );
+ }
+ } catch (final Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ protected void runTestGL(final GLCapabilities caps)
+ throws AWTException, InterruptedException, InvocationTargetException
+ {
+ final JFrame frame = new JFrame("Swing GLJPanel");
+ frame.setLocation(xpos, ypos);
+ Assert.assertNotNull(frame);
+
+ final FPSAnimator animator = useAnimator ? new FPSAnimator(60) : null;
+ final SnapshotGLEventListener snap = new SnapshotGLEventListener();
+ final GLJPanel glJPanel = newGLJPanel(frame, caps, animator, snap);
+ if( null != animator ) {
animator.start();
Assert.assertEquals(true, animator.isAnimating());
}
+ final Screen screen = NewtFactoryAWT.createScreen(glJPanel, true);
+ screen.addReference(); // initial native creation - keep alive!
+ System.err.println("GetPixelScale: AWT -> Screen: "+screen);
final QuitAdapter quitAdapter = new QuitAdapter();
new AWTKeyAdapter(new TraceKeyAdapter(quitAdapter), glJPanel).addTo(glJPanel);
new AWTWindowAdapter(new TraceWindowAdapter(quitAdapter), glJPanel).addTo(frame);
+ final JFrame[] frame2 = { null };
+ final GLJPanel[] glJPanel2 = { null };
+
final com.jogamp.newt.event.KeyListener kl = new com.jogamp.newt.event.KeyAdapter() {
@Override
public void keyPressed(final KeyEvent e) {
@@ -262,6 +373,33 @@ public class TestGearsES2GLJPanelAWT extends UITestCase {
glJPanel.setRequestedGLCapabilities(capsNew);
System.err.println("XXX-A2: "+animator.toString());
System.err.println("XXX: "+glJPanel.toString());
+ } else if(e.getKeyChar()=='n') {
+ System.err.println("XXX: frame2: "+frame2[0]);
+ if( null != frame2[0] ) {
+ System.err.println("XXX: frame2.isShowing: "+frame2[0].isShowing());
+ }
+ System.err.println("XXX: glJPanel2: "+glJPanel2[0]);
+ if( null != frame2[0] && frame2[0].isShowing() ) {
+ destroy(frame2[0], glJPanel2[0]);
+ frame2[0] = null;
+ glJPanel2[0] = null;
+ } else {
+ frame2[0] = new JFrame("GLJPanel2");
+ frame2[0].setLocation(frame.getX()+frame.getWidth()+64, frame.getY());
+ final FPSAnimator animator2 = useAnimator ? new FPSAnimator(60) : null;
+ if( null != animator2 ) {
+ animator2.start();
+ }
+ final SnapshotGLEventListener snap2 = new SnapshotGLEventListener();
+ try {
+ glJPanel2[0] = newGLJPanel(frame2[0], caps, animator2, snap2);
+ } catch (final Exception e2) {
+ e2.printStackTrace();
+ destroy(frame2[0], glJPanel2[0]);
+ frame2[0] = null;
+ glJPanel2[0] = null;
+ }
+ }
}
} };
new AWTKeyAdapter(kl, glJPanel).addTo(glJPanel);
@@ -300,15 +438,12 @@ public class TestGearsES2GLJPanelAWT extends UITestCase {
} else {
Assert.assertNull(animator);
}
- SwingUtilities.invokeAndWait(new Runnable() {
- public void run() {
- frame.setVisible(false);
- frame.getContentPane().remove(glJPanel);
- frame.remove(glJPanel);
- glJPanel.destroy();
- frame.dispose();
- } } );
+
screen.removeReference(); // final native destroy
+ destroy(frame, glJPanel);
+ if( null != frame2[0] ) {
+ destroy(frame2[0], glJPanel2[0]);
+ }
}
@Test
@@ -528,6 +663,9 @@ public class TestGearsES2GLJPanelAWT extends UITestCase {
shallUseBitmap = true;
} else if(args[i].equals("-manual")) {
manualTest = true;
+ } else if(args[i].equals("-demo")) {
+ i++;
+ demoType = MiscUtils.atoi(args[i], 0);
}
}
wsize = new Dimension(w, h);
@@ -547,6 +685,7 @@ public class TestGearsES2GLJPanelAWT extends UITestCase {
System.err.println("shallUsePBuffer "+shallUsePBuffer);
System.err.println("shallUseBitmap "+shallUseBitmap);
System.err.println("manualTest "+manualTest);
+ System.err.println("demoType "+demoType);
org.junit.runner.JUnitCore.main(TestGearsES2GLJPanelAWT.class.getName());
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestElektronenMultipliziererNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestElektronenMultipliziererNEWT.java
index 5ecda9e20..b389c9ac9 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestElektronenMultipliziererNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestElektronenMultipliziererNEWT.java
@@ -28,6 +28,7 @@
package com.jogamp.opengl.test.junit.jogl.demos.es2.newt;
+import com.jogamp.common.util.InterruptSource;
import com.jogamp.newt.event.KeyAdapter;
import com.jogamp.newt.event.KeyEvent;
import com.jogamp.newt.event.TraceWindowAdapter;
@@ -109,12 +110,12 @@ public class TestElektronenMultipliziererNEWT extends UITestCase {
return;
}
if(e.getKeyChar()=='f') {
- new Thread() {
+ new InterruptSource.Thread() {
public void run() {
f_glWindow.setFullscreen(!f_glWindow.isFullscreen());
} }.start();
} else if(e.getKeyChar()=='d') {
- new Thread() {
+ new InterruptSource.Thread() {
public void run() {
f_glWindow.setUndecorated(!f_glWindow.isUndecorated());
} }.start();
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 d5afdcfda..43417c317 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
@@ -33,34 +33,39 @@ import java.lang.reflect.InvocationTargetException;
import com.jogamp.junit.util.JunitTracer;
import com.jogamp.newt.Display;
-import com.jogamp.newt.Display.PointerIcon;
import com.jogamp.newt.NewtFactory;
import com.jogamp.newt.Screen;
import com.jogamp.newt.Window;
import com.jogamp.newt.event.WindowEvent;
+import com.jogamp.newt.event.KeyAdapter;
+import com.jogamp.newt.event.KeyEvent;
+import com.jogamp.newt.event.TraceMouseAdapter;
import com.jogamp.newt.event.WindowAdapter;
import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.newt.opengl.util.NEWTDemoListener;
import com.jogamp.newt.util.EDTUtil;
import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
import com.jogamp.opengl.test.junit.util.MiscUtils;
-import com.jogamp.opengl.test.junit.util.NEWTDemoListener;
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.AnimatorBase;
+import com.jogamp.opengl.test.junit.jogl.demos.GLClearOnInitReshape;
import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
-
+import com.jogamp.opengl.test.junit.jogl.demos.es2.LineSquareXDemoES2;
+import com.jogamp.opengl.test.junit.newt.parenting.NewtReparentingKeyAdapter;
import com.jogamp.nativewindow.NativeWindowFactory;
import com.jogamp.nativewindow.ScalableSurface;
import com.jogamp.nativewindow.util.Dimension;
import com.jogamp.nativewindow.util.Point;
import com.jogamp.nativewindow.util.PointImmutable;
import com.jogamp.nativewindow.util.DimensionImmutable;
+import com.jogamp.opengl.GL;
import com.jogamp.opengl.GLAnimatorControl;
import com.jogamp.opengl.GLAutoDrawable;
import com.jogamp.opengl.GLCapabilities;
import com.jogamp.opengl.GLCapabilitiesImmutable;
import com.jogamp.opengl.GLEventListener;
+import com.jogamp.opengl.GLPipelineFactory;
import com.jogamp.opengl.GLProfile;
import jogamp.newt.DefaultEDTUtil;
@@ -72,6 +77,14 @@ import org.junit.Test;
import org.junit.FixMethodOrder;
import org.junit.runners.MethodSorters;
+/**
+ * <p>
+ * The demo code uses {@link NEWTDemoListener} functionality.
+ * </p>
+ * <p>
+ * Manual invocation via main allows setting each tests's duration in milliseconds, e.g.{@code -duration 10000} and many more, see {@link #main(String[])}
+ * </p>
+ */
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class TestGearsES2NEWT extends UITestCase {
static int screenIdx = 0;
@@ -102,6 +115,10 @@ public class TestGearsES2NEWT extends UITestCase {
static boolean forceES3 = false;
static boolean forceGL3 = false;
static boolean forceGL2 = false;
+ static boolean forceDebug = false;
+ static boolean forceTrace = false;
+ static int demoType = 1;
+ static boolean traceMouse = false;
static boolean manualTest = false;
static boolean exclusiveContext = false;
static boolean useAnimator = true;
@@ -142,10 +159,50 @@ public class TestGearsES2NEWT extends UITestCase {
glWindow.setPointerVisible(mouseVisible);
glWindow.confinePointer(mouseConfined);
- final GearsES2 demo = new GearsES2(swapInterval);
- demo.setUseMappedBuffers(useMappedBuffers);
- demo.setValidateBuffers(true);
- glWindow.addGLEventListener(demo);
+ final GLEventListener demo;
+ if( 2 == demoType ) {
+ final LineSquareXDemoES2 demo2 = new LineSquareXDemoES2(false);
+ demo = demo2;
+ } else if( 1 == demoType ) {
+ final GearsES2 gearsES2 = new GearsES2(swapInterval);
+ gearsES2.setUseMappedBuffers(useMappedBuffers);
+ gearsES2.setValidateBuffers(true);
+ demo = gearsES2;
+ } else if( 0 == demoType ) {
+ demo = new GLClearOnInitReshape();
+ } else {
+ demo = null;
+ }
+ if( forceDebug || forceTrace ) {
+ glWindow.addGLEventListener(new GLEventListener() {
+ @Override
+ public void init(final GLAutoDrawable drawable) {
+ GL _gl = drawable.getGL();
+ if(forceDebug) {
+ try {
+ _gl = _gl.getContext().setGL( GLPipelineFactory.create("com.jogamp.opengl.Debug", null, _gl, null) );
+ } catch (final Exception e) {e.printStackTrace();}
+ }
+
+ if(forceTrace) {
+ try {
+ // Trace ..
+ _gl = _gl.getContext().setGL( GLPipelineFactory.create("com.jogamp.opengl.Trace", null, _gl, new Object[] { System.err } ) );
+ } catch (final Exception e) {e.printStackTrace();}
+ }
+ }
+ @Override
+ public void dispose(final GLAutoDrawable drawable) {}
+ @Override
+ public void display(final GLAutoDrawable drawable) {}
+ @Override
+ public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height) {}
+ });
+ }
+
+ if( null != demo ) {
+ glWindow.addGLEventListener(demo);
+ }
final SnapshotGLEventListener snap = new SnapshotGLEventListener();
glWindow.addGLEventListener(snap);
@@ -172,32 +229,51 @@ public class TestGearsES2NEWT extends UITestCase {
animator.setExclusiveContext(exclusiveContext);
}
- final QuitAdapter quitAdapter = new QuitAdapter();
- //glWindow.addKeyListener(new TraceKeyAdapter(quitAdapter));
- //glWindow.addWindowListener(new TraceWindowAdapter(quitAdapter));
- glWindow.addKeyListener(quitAdapter);
- glWindow.addWindowListener(quitAdapter);
-
glWindow.addWindowListener(new WindowAdapter() {
public void windowResized(final WindowEvent e) {
- System.err.println("window resized: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getSurfaceWidth()+"x"+glWindow.getSurfaceHeight());
+ System.err.println("window resized: "+glWindow.getBounds()+" "+glWindow.getSurfaceWidth()+"x"+glWindow.getSurfaceHeight());
NEWTDemoListener.setTitle(glWindow);
}
public void windowMoved(final WindowEvent e) {
- System.err.println("window moved: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getSurfaceWidth()+"x"+glWindow.getSurfaceHeight());
+ System.err.println("window moved: "+glWindow.getBounds()+" "+glWindow.getSurfaceWidth()+"x"+glWindow.getSurfaceHeight());
NEWTDemoListener.setTitle(glWindow);
}
});
- final PointerIcon[] pointerIcons = NEWTDemoListener.createPointerIcons(glWindow);
- if( setPointerIcon ) {
- glWindow.setPointerIcon(pointerIcons[0]);
- System.err.println("Set PointerIcon: "+glWindow.getPointerIcon());
- }
+ final GLWindow[] glWindow2 = { null };
- final NEWTDemoListener newtDemoListener = new NEWTDemoListener(glWindow, pointerIcons);
+ final NEWTDemoListener newtDemoListener = new NEWTDemoListener(glWindow);
+ newtDemoListener.quitAdapterEnable(true);
glWindow.addKeyListener(newtDemoListener);
+ if( traceMouse ) {
+ glWindow.addMouseListener(new TraceMouseAdapter());
+ }
glWindow.addMouseListener(newtDemoListener);
+ glWindow.addWindowListener(newtDemoListener);
+ glWindow.addKeyListener(new KeyAdapter() {
+ @Override
+ public void keyPressed(final KeyEvent e) {
+ if( e.isAutoRepeat() ) {
+ return;
+ }
+ if(e.getKeyChar()=='n') {
+ if( null != glWindow2[0] && glWindow2[0].isNativeValid() ) {
+ glWindow2[0].destroy();
+ glWindow2[0] = null;
+ } else {
+ glWindow2[0] = GLWindow.create(screen, caps);
+ glWindow2[0].setTitle("GLWindow2");
+ glWindow2[0].setPosition(glWindow.getX()+glWindow.getWidth()+64, glWindow.getY());
+ glWindow2[0].setSize(glWindow.getWidth(), glWindow.getHeight());
+ glWindow2[0].addGLEventListener(new LineSquareXDemoES2(false));
+ final Animator animator2 = useAnimator ? new Animator(glWindow2[0]) : null;
+ if( null != animator2 ) {
+ animator2.start();
+ }
+ glWindow2[0].setVisible(true);
+ }
+ }
+ } } );
if( useAnimator ) {
animator.add(glWindow);
@@ -231,7 +307,7 @@ public class TestGearsES2NEWT extends UITestCase {
final EDTUtil edt = ((Window)upstream).getScreen().getDisplay().getEDTUtil();
System.err.println("EDT invokeAndWaitError: edt type "+edt.getClass().getName());
if( edt instanceof DefaultEDTUtil ) {
- quitAdapter.doQuit();
+ newtDemoListener.doQuit();
((DefaultEDTUtil)edt).invokeAndWaitError(new Runnable() {
public void run() {
throw new RuntimeException("XXX Should never ever be seen! - "+Thread.currentThread());
@@ -255,6 +331,8 @@ public class TestGearsES2NEWT extends UITestCase {
animator.setUpdateFPSFrames(60, showFPS ? System.err : null);
}
+ System.err.println("Window Current State : "+glWindow.getStateMaskString());
+ System.err.println("Window Supported States: "+glWindow.getSupportedStateMaskString());
System.err.println("NW chosen: "+glWindow.getDelegatedWindow().getChosenCapabilities());
System.err.println("GL chosen: "+glWindow.getChosenCapabilities());
System.err.println("window pos/siz: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getSurfaceWidth()+"x"+glWindow.getSurfaceHeight()+", "+glWindow.getInsets());
@@ -277,7 +355,7 @@ public class TestGearsES2NEWT extends UITestCase {
final long t0 = System.currentTimeMillis();
long t1 = t0;
- while(!quitAdapter.shouldQuit() && t1-t0<duration) {
+ while(!newtDemoListener.shouldQuit() && t1-t0<duration) {
Thread.sleep(100);
t1 = System.currentTimeMillis();
if( SysExit.testError == sysExit || SysExit.testExit == sysExit || SysExit.testEDTError == sysExit) {
@@ -292,7 +370,7 @@ public class TestGearsES2NEWT extends UITestCase {
final EDTUtil edt = glWindow.getScreen().getDisplay().getEDTUtil();
System.err.println("EDT invokeAndWaitError: edt type "+edt.getClass().getName());
if( edt instanceof DefaultEDTUtil ) {
- quitAdapter.doQuit();
+ newtDemoListener.doQuit();
((DefaultEDTUtil)edt).invokeAndWaitError(new Runnable() {
public void run() {
throw new RuntimeException("XXX Should never ever be seen!");
@@ -312,6 +390,10 @@ public class TestGearsES2NEWT extends UITestCase {
}
Assert.assertEquals(null, glWindow.getExclusiveContextThread());
glWindow.destroy();
+ if( null != glWindow2[0] && glWindow2[0].isNativeValid() ) {
+ glWindow2[0].destroy();
+ glWindow2[0] = null;
+ }
if( NativeWindowFactory.isAWTAvailable() ) {
Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glWindow, false));
}
@@ -426,6 +508,10 @@ public class TestGearsES2NEWT extends UITestCase {
forceGL3 = true;
} else if(args[i].equals("-gl2")) {
forceGL2 = true;
+ } else if(args[i].equals("-debug")) {
+ forceDebug = true;
+ } else if(args[i].equals("-trace")) {
+ forceTrace = true;
} else if(args[i].equals("-mappedBuffers")) {
useMappedBuffers = true;
} else if(args[i].equals("-wait")) {
@@ -476,6 +562,11 @@ public class TestGearsES2NEWT extends UITestCase {
sysExit = SysExit.valueOf(args[i]);
} else if(args[i].equals("-manual")) {
manualTest = true;
+ } else if(args[i].equals("-demo")) {
+ i++;
+ demoType = MiscUtils.atoi(args[i], 0);
+ } else if(args[i].equals("-traceMouse")) {
+ traceMouse = true;
}
}
wsize = new Dimension(w, h);
@@ -509,11 +600,15 @@ public class TestGearsES2NEWT extends UITestCase {
System.err.println("forceES3 "+forceES3);
System.err.println("forceGL3 "+forceGL3);
System.err.println("forceGL2 "+forceGL2);
+ System.err.println("forceDebug "+forceDebug);
+ System.err.println("forceTrace "+forceTrace);
System.err.println("swapInterval "+swapInterval);
System.err.println("exclusiveContext "+exclusiveContext);
System.err.println("useAnimator "+useAnimator);
System.err.println("sysExitWithin "+sysExit);
System.err.println("mappedBuffers "+useMappedBuffers);
+ System.err.println("demoType "+demoType);
+ System.err.println("traceMouse "+traceMouse);
if(waitForKey) {
JunitTracer.waitForKey("Start");
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NewtCanvasAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NewtCanvasAWT.java
index 39d13f6a3..77c4bf8f3 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NewtCanvasAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NewtCanvasAWT.java
@@ -47,14 +47,15 @@ import com.jogamp.newt.awt.NewtCanvasAWT;
import com.jogamp.newt.event.WindowEvent;
import com.jogamp.newt.event.WindowAdapter;
import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.newt.opengl.util.NEWTDemoListener;
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.test.junit.util.QuitAdapter;
import com.jogamp.opengl.util.Animator;
import com.jogamp.opengl.util.AnimatorBase;
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.newt.parenting.NewtReparentingKeyAdapter;
import com.jogamp.nativewindow.ScalableSurface;
import com.jogamp.nativewindow.util.Dimension;
@@ -74,6 +75,14 @@ import org.junit.Test;
import org.junit.FixMethodOrder;
import org.junit.runners.MethodSorters;
+/**
+ * <p>
+ * The demo code uses {@link NewtReparentingKeyAdapter} including {@link NEWTDemoListener} functionality.
+ * </p>
+ * <p>
+ * Manual invocation via main allows setting each tests's duration in milliseconds, e.g.{@code -duration 10000}, and many more, see {@link #main(String[])}
+ * </p>
+ */
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class TestGearsES2NewtCanvasAWT extends UITestCase {
public enum FrameLayout { None, TextOnBottom, BorderBottom, BorderBottom2, BorderCenter, BorderCenterSurrounded, DoubleBorderCenterSurrounded };
@@ -82,7 +91,7 @@ public class TestGearsES2NewtCanvasAWT extends UITestCase {
static int screenIdx = 0;
static PointImmutable wpos;
static DimensionImmutable wsize, rwsize = null;
- static FrameLayout frameLayout = FrameLayout.None;
+ static FrameLayout frameLayout = FrameLayout.BorderCenterSurrounded;
static ResizeBy resizeBy = ResizeBy.Component;
static float[] reqSurfacePixelScale = new float[] { ScalableSurface.AUTOMAX_PIXELSCALE, ScalableSurface.AUTOMAX_PIXELSCALE };
@@ -248,17 +257,21 @@ public class TestGearsES2NewtCanvasAWT extends UITestCase {
final GearsES2 demo = new GearsES2(swapInterval);
glWindow.addGLEventListener(demo);
+ final NewtAWTReparentingKeyAdapter newtDemoListener = new NewtAWTReparentingKeyAdapter(frame, newtCanvasAWT, glWindow);
+ newtDemoListener.quitAdapterEnable(true);
+ glWindow.addKeyListener(newtDemoListener);
+ glWindow.addMouseListener(newtDemoListener);
+ glWindow.addWindowListener(newtDemoListener);
+
frame.addComponentListener(new ComponentListener() {
@Override
public void componentResized(final ComponentEvent e) {
- NewtAWTReparentingKeyAdapter.setTitle(frame, newtCanvasAWT, glWindow);
+ newtDemoListener.setTitle();
}
-
@Override
public void componentMoved(final ComponentEvent e) {
- NewtAWTReparentingKeyAdapter.setTitle(frame, newtCanvasAWT, glWindow);
+ newtDemoListener.setTitle();
}
-
@Override
public void componentShown(final ComponentEvent e) { }
@@ -272,12 +285,6 @@ public class TestGearsES2NewtCanvasAWT extends UITestCase {
animator.setExclusiveContext(exclusiveContext);
}
- final QuitAdapter quitAdapter = new QuitAdapter();
- //glWindow.addKeyListener(new TraceKeyAdapter(quitAdapter));
- //glWindow.addWindowListener(new TraceWindowAdapter(quitAdapter));
- glWindow.addKeyListener(quitAdapter);
- glWindow.addWindowListener(quitAdapter);
-
glWindow.addWindowListener(new WindowAdapter() {
public void windowResized(final WindowEvent e) {
System.err.println("window resized: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getSurfaceWidth()+"x"+glWindow.getSurfaceHeight());
@@ -287,10 +294,6 @@ public class TestGearsES2NewtCanvasAWT extends UITestCase {
}
});
- final NewtAWTReparentingKeyAdapter newtDemoListener = new NewtAWTReparentingKeyAdapter(frame, newtCanvasAWT, glWindow, quitAdapter);
- glWindow.addKeyListener(newtDemoListener);
- glWindow.addMouseListener(newtDemoListener);
-
if( useAnimator ) {
animator.add(glWindow);
animator.start();
@@ -324,7 +327,7 @@ public class TestGearsES2NewtCanvasAWT extends UITestCase {
System.err.println("HiDPI PixelScale: "+reqSurfacePixelScale[0]+"x"+reqSurfacePixelScale[1]+" (req) -> "+
valReqSurfacePixelScale[0]+"x"+valReqSurfacePixelScale[1]+" (val) -> "+
hasSurfacePixelScale1[0]+"x"+hasSurfacePixelScale1[1]+" (has)");
- NewtAWTReparentingKeyAdapter.setTitle(frame, newtCanvasAWT, glWindow);
+ newtDemoListener.setTitle();
if( null != rwsize ) {
Thread.sleep(500); // 500ms delay
@@ -334,7 +337,7 @@ public class TestGearsES2NewtCanvasAWT extends UITestCase {
final long t0 = System.currentTimeMillis();
long t1 = t0;
- while(!quitAdapter.shouldQuit() && t1-t0<duration) {
+ while(!newtDemoListener.shouldQuit() && t1-t0<duration) {
Thread.sleep(100);
t1 = System.currentTimeMillis();
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NewtCanvasSWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NewtCanvasSWT.java
index 8dcffc662..ee72e1e6f 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NewtCanvasSWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NewtCanvasSWT.java
@@ -31,6 +31,7 @@ package com.jogamp.opengl.test.junit.jogl.demos.es2.newt;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
+import com.jogamp.common.util.InterruptSource;
import com.jogamp.nativewindow.swt.SWTAccessor;
import com.jogamp.newt.NewtFactory;
import com.jogamp.newt.event.KeyAdapter;
@@ -184,14 +185,12 @@ public class TestGearsES2NewtCanvasSWT extends UITestCase {
return;
}
if(e.getKeyChar()=='f') {
- new Thread() {
+ glWindow.invokeOnNewThread(null, false, new Runnable() {
public void run() {
- final Thread t = glWindow.setExclusiveContextThread(null);
System.err.println("[set fullscreen pre]: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getSurfaceWidth()+"x"+glWindow.getSurfaceHeight()+", f "+glWindow.isFullscreen()+", a "+glWindow.isAlwaysOnTop()+", "+glWindow.getInsets());
glWindow.setFullscreen(!glWindow.isFullscreen());
System.err.println("[set fullscreen post]: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getSurfaceWidth()+"x"+glWindow.getSurfaceHeight()+", f "+glWindow.isFullscreen()+", a "+glWindow.isAlwaysOnTop()+", "+glWindow.getInsets());
- glWindow.setExclusiveContextThread(t);
- } }.start();
+ } } );
}
}
});
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2SimpleNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2SimpleNEWT.java
index d109c56cf..6aebeb91b 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2SimpleNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2SimpleNEWT.java
@@ -40,14 +40,14 @@ import com.jogamp.newt.Window;
import com.jogamp.newt.event.WindowEvent;
import com.jogamp.newt.event.WindowAdapter;
import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.newt.opengl.util.NEWTDemoListener;
import com.jogamp.opengl.test.junit.util.UITestCase;
import com.jogamp.opengl.test.junit.util.MiscUtils;
-import com.jogamp.opengl.test.junit.util.NEWTDemoListener;
import com.jogamp.opengl.test.junit.util.QuitAdapter;
import com.jogamp.opengl.util.Animator;
import com.jogamp.opengl.util.PNGPixelRect;
import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
-
+import com.jogamp.opengl.test.junit.newt.parenting.NewtReparentingKeyAdapter;
import com.jogamp.nativewindow.ScalableSurface;
import com.jogamp.nativewindow.util.Dimension;
import com.jogamp.nativewindow.util.DimensionImmutable;
@@ -61,6 +61,14 @@ import org.junit.Test;
import org.junit.FixMethodOrder;
import org.junit.runners.MethodSorters;
+/**
+ * <p>
+ * The demo code uses {@link NEWTDemoListener} functionality.
+ * </p>
+ * <p>
+ * Manual invocation via main allows setting each tests's duration in milliseconds, e.g.{@code -duration 10000} and using a translucent window {@code -translucent}.
+ * </p>
+ */
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class TestGearsES2SimpleNEWT extends UITestCase {
static final DimensionImmutable wsize = new Dimension(800, 600);
@@ -118,7 +126,7 @@ public class TestGearsES2SimpleNEWT extends UITestCase {
int idx = 0;
{
PointerIcon _pointerIcon = null;
- final IOUtil.ClassResources res = new IOUtil.ClassResources(glWindow.getClass(), new String[] { "newt/data/cross-grey-alpha-16x16.png" } );
+ final IOUtil.ClassResources res = new IOUtil.ClassResources(new String[] { "newt/data/cross-grey-alpha-16x16.png" }, glWindow.getClass().getClassLoader(), null);
try {
_pointerIcon = disp.createPointerIcon(res, 8, 8);
System.err.printf("Create PointerIcon #%02d: %s%n", idx, _pointerIcon.toString());
@@ -130,7 +138,7 @@ public class TestGearsES2SimpleNEWT extends UITestCase {
idx++;
{
PointerIcon _pointerIcon = null;
- final IOUtil.ClassResources res = new IOUtil.ClassResources(glWindow.getClass(), new String[] { "newt/data/pointer-grey-alpha-16x24.png" } );
+ final IOUtil.ClassResources res = new IOUtil.ClassResources(new String[] { "newt/data/pointer-grey-alpha-16x24.png" }, glWindow.getClass().getClassLoader(), null);
try {
_pointerIcon = disp.createPointerIcon(res, 0, 0);
System.err.printf("Create PointerIcon #%02d: %s%n", idx, _pointerIcon.toString());
@@ -142,7 +150,7 @@ public class TestGearsES2SimpleNEWT extends UITestCase {
idx++;
{
PointerIcon _pointerIcon = null;
- final IOUtil.ClassResources res = new IOUtil.ClassResources(glWindow.getClass(), new String[] { "arrow-red-alpha-64x64.png" } );
+ final IOUtil.ClassResources res = new IOUtil.ClassResources(new String[] { "arrow-red-alpha-64x64.png" }, glWindow.getClass().getClassLoader(), null);
try {
_pointerIcon = disp.createPointerIcon(res, 0, 0);
System.err.printf("Create PointerIcon #%02d: %s%n", idx, _pointerIcon.toString());
@@ -154,7 +162,7 @@ public class TestGearsES2SimpleNEWT extends UITestCase {
idx++;
{
PointerIcon _pointerIcon = null;
- final IOUtil.ClassResources res = new IOUtil.ClassResources(glWindow.getClass(), new String[] { "arrow-blue-alpha-64x64.png" } );
+ final IOUtil.ClassResources res = new IOUtil.ClassResources(new String[] { "arrow-blue-alpha-64x64.png" }, glWindow.getClass().getClassLoader(), null);
try {
_pointerIcon = disp.createPointerIcon(res, 0, 0);
System.err.printf("Create PointerIcon #%02d: %s%n", idx, _pointerIcon.toString());
@@ -166,7 +174,7 @@ public class TestGearsES2SimpleNEWT extends UITestCase {
idx++;
if( PNGIcon.isAvailable() ) {
PointerIcon _pointerIcon = null;
- final IOUtil.ClassResources res = new IOUtil.ClassResources(glWindow.getClass(), new String[] { "jogamp-pointer-64x64.png" } );
+ final IOUtil.ClassResources res = new IOUtil.ClassResources(new String[] { "jogamp-pointer-64x64.png" }, glWindow.getClass().getClassLoader(), null);
try {
final URLConnection urlConn = res.resolve(0);
final PNGPixelRect image = PNGPixelRect.read(urlConn.getInputStream(), null, false /* directBuffer */, 0 /* destMinStrideInBytes */, false /* destIsGLOriented */);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestLandscapeES2NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestLandscapeES2NEWT.java
index 79c8cb39a..2c5b6028c 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestLandscapeES2NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestLandscapeES2NEWT.java
@@ -87,15 +87,15 @@ public class TestLandscapeES2NEWT extends UITestCase {
return;
}
if(e.getKeyChar()=='f') {
- new Thread() {
+ glWindow.invokeOnNewThread(null, false, new Runnable() {
public void run() {
glWindow.setFullscreen(!glWindow.isFullscreen());
- } }.start();
+ } } );
} else if(e.getKeyChar()=='d') {
- new Thread() {
+ glWindow.invokeOnNewThread(null, false, new Runnable() {
public void run() {
glWindow.setUndecorated(!glWindow.isUndecorated());
- } }.start();
+ } } );
}
}
});
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestLandscapeES2NewtCanvasAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestLandscapeES2NewtCanvasAWT.java
index 12ea6dbb3..c5bbecbc7 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestLandscapeES2NewtCanvasAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestLandscapeES2NewtCanvasAWT.java
@@ -39,13 +39,14 @@ import com.jogamp.newt.awt.NewtCanvasAWT;
import com.jogamp.newt.event.WindowEvent;
import com.jogamp.newt.event.WindowAdapter;
import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.newt.opengl.util.NEWTDemoListener;
import com.jogamp.opengl.test.junit.util.MiscUtils;
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.AnimatorBase;
import com.jogamp.opengl.test.junit.jogl.demos.es2.LandscapeES2;
import com.jogamp.opengl.test.junit.newt.parenting.NewtAWTReparentingKeyAdapter;
+import com.jogamp.opengl.test.junit.newt.parenting.NewtReparentingKeyAdapter;
import com.jogamp.nativewindow.util.Dimension;
import com.jogamp.nativewindow.util.DimensionImmutable;
@@ -58,6 +59,14 @@ import org.junit.Test;
import org.junit.FixMethodOrder;
import org.junit.runners.MethodSorters;
+/**
+ * <p>
+ * The demo code uses {@link NewtReparentingKeyAdapter} including {@link NEWTDemoListener} functionality.
+ * </p>
+ * <p>
+ * Manual invocation via main allows setting each tests's duration in milliseconds, e.g.{@code -duration 10000}, and many more, see {@link #main(String[])}
+ * </p>
+ */
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class TestLandscapeES2NewtCanvasAWT extends UITestCase {
static DimensionImmutable wsize = new Dimension(500, 290);
@@ -104,12 +113,6 @@ public class TestLandscapeES2NewtCanvasAWT extends UITestCase {
animator.setExclusiveContext(exclusiveContext);
}
- final QuitAdapter quitAdapter = new QuitAdapter();
- //glWindow.addKeyListener(new TraceKeyAdapter(quitAdapter));
- //glWindow.addWindowListener(new TraceWindowAdapter(quitAdapter));
- glWindow.addKeyListener(quitAdapter);
- glWindow.addWindowListener(quitAdapter);
-
glWindow.addWindowListener(new WindowAdapter() {
public void windowResized(final WindowEvent e) {
System.err.println("window resized: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getSurfaceWidth()+"x"+glWindow.getSurfaceHeight());
@@ -119,7 +122,11 @@ public class TestLandscapeES2NewtCanvasAWT extends UITestCase {
}
});
- glWindow.addKeyListener(new NewtAWTReparentingKeyAdapter(frame, newtCanvasAWT, glWindow, quitAdapter));
+ final NewtReparentingKeyAdapter newtDemoListener = new NewtAWTReparentingKeyAdapter(frame, newtCanvasAWT, glWindow);
+ newtDemoListener.quitAdapterEnable(true);
+ glWindow.addKeyListener(newtDemoListener);
+ glWindow.addMouseListener(newtDemoListener);
+ glWindow.addWindowListener(newtDemoListener);
if( useAnimator ) {
animator.add(glWindow);
@@ -143,7 +150,7 @@ public class TestLandscapeES2NewtCanvasAWT extends UITestCase {
final long t0 = System.currentTimeMillis();
long t1 = t0;
- while(!quitAdapter.shouldQuit() && t1-t0<duration) {
+ while(!newtDemoListener.shouldQuit() && t1-t0<duration) {
Thread.sleep(100);
t1 = System.currentTimeMillis();
}
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 e8e3741aa..976025c14 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
@@ -110,15 +110,15 @@ public class TestRedSquareES2NEWT extends UITestCase {
return;
}
if(e.getKeyChar()=='f') {
- new Thread() {
+ glWindow.invokeOnNewThread(null, false, new Runnable() {
public void run() {
glWindow.setFullscreen(!glWindow.isFullscreen());
- } }.start();
+ } } );
} else if(e.getKeyChar()=='d') {
- new Thread() {
+ glWindow.invokeOnNewThread(null, false, new Runnable() {
public void run() {
glWindow.setUndecorated(!glWindow.isUndecorated());
- } }.start();
+ } } );
}
}
});
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 c2761f694..a144ff1ff 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
@@ -230,9 +230,7 @@ public class Gears implements GLEventListener, TileRendererBase.TileRendererList
public void reshape(final GLAutoDrawable glad, final int x, final int y, final int width, final int height) {
if( !isInit ) { return; }
final GL2 gl = glad.getGL().getGL2();
- if(-1 != swapInterval) {
- gl.setSwapInterval(swapInterval);
- }
+ gl.setSwapInterval(swapInterval);
reshape(gl, x, y, width, height, width, height);
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/Teapot.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/Teapot.java
index 22d24b67b..159fad9da 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/Teapot.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/Teapot.java
@@ -72,7 +72,7 @@ public class Teapot implements GLEventListener {
gl.glClearColor(0.5f, 0.5f, 0.5f, 0.0f);
try {
- final URLConnection urlConn = IOUtil.getResource(PNGTstFiles.class, "test-ntscP_3-01-160x90.png");
+ final URLConnection urlConn = IOUtil.getResource("test-ntscP_3-01-160x90.png", PNGTstFiles.class.getClassLoader(), PNGTstFiles.class);
tex = TextureIO.newTexture(gl, TextureIO.newTextureData(gl.getGLProfile(), urlConn.getInputStream(), false, TextureIO.PNG));
} catch (final Exception e) {
e.printStackTrace();
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/newt/TestGearsNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/newt/TestGearsNEWT.java
index 0f3011c3d..0ab9308c2 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/newt/TestGearsNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/newt/TestGearsNEWT.java
@@ -28,16 +28,15 @@
package com.jogamp.opengl.test.junit.jogl.demos.gl2.newt;
-import com.jogamp.newt.event.KeyAdapter;
-import com.jogamp.newt.event.KeyEvent;
import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.newt.opengl.util.NEWTDemoListener;
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.gl2.Gears;
-
+import com.jogamp.opengl.test.junit.newt.parenting.NewtReparentingKeyAdapter;
import com.jogamp.opengl.GLCapabilities;
import com.jogamp.opengl.GLProfile;
@@ -48,6 +47,14 @@ import org.junit.Test;
import org.junit.FixMethodOrder;
import org.junit.runners.MethodSorters;
+/**
+ * <p>
+ * The demo code uses {@link NEWTDemoListener} functionality.
+ * </p>
+ * <p>
+ * Manual invocation via main allows setting each tests's duration in milliseconds, e.g.{@code -duration 10000}.
+ * </p>
+ */
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class TestGearsNEWT extends UITestCase {
static GLProfile glp;
@@ -84,25 +91,9 @@ public class TestGearsNEWT extends UITestCase {
glWindow.addKeyListener(quitAdapter);
glWindow.addWindowListener(quitAdapter);
- final GLWindow f_glWindow = glWindow;
- glWindow.addKeyListener(new KeyAdapter() {
- public void keyReleased(final KeyEvent e) {
- if( !e.isPrintableKey() || e.isAutoRepeat() ) {
- return;
- }
- 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();
- }
- }
- });
+ final NEWTDemoListener newtDemoListener = new NEWTDemoListener(glWindow);
+ glWindow.addKeyListener(newtDemoListener);
+ glWindow.addMouseListener(newtDemoListener);
glWindow.setSize(width, height);
glWindow.setVisible(true);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl3/GeomShader01TextureGL3.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl3/GeomShader01TextureGL3.java
index a4a665e5b..668d8877c 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl3/GeomShader01TextureGL3.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl3/GeomShader01TextureGL3.java
@@ -193,7 +193,7 @@ public class GeomShader01TextureGL3 implements GLEventListener {
}
private Texture createTestTexture(final GL3 gl) throws IOException {
- final URLConnection urlConn = IOUtil.getResource(this.getClass(), "../../util/texture/test-ntscN_3-01-160x90.png");
+ final URLConnection urlConn = IOUtil.getResource("../../util/texture/test-ntscN_3-01-160x90.png", this.getClass().getClassLoader(), this.getClass());
if(null == urlConn) { return null; }
final InputStream istream = urlConn.getInputStream();
if(null == istream) { return null; }
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/javafx/PureJFXApp01.java b/src/test/com/jogamp/opengl/test/junit/jogl/javafx/PureJFXApp01.java
new file mode 100644
index 000000000..d2a3b8073
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/javafx/PureJFXApp01.java
@@ -0,0 +1,54 @@
+/**
+ * Copyright 2019 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.javafx;
+
+import javafx.application.Application;
+import javafx.scene.Group;
+import javafx.scene.Scene;
+import javafx.scene.text.Font;
+import javafx.scene.text.Text;
+import javafx.stage.Stage;
+
+public class PureJFXApp01 extends Application {
+
+ @Override public void start(Stage stage) {
+ Text text = new Text(10, 40, "Pure JFX App 01");
+ text.setFont(new Font(40));
+ Scene scene = new Scene(new Group(text));
+
+ stage.setTitle("JavaFX Stage");
+ stage.setScene(scene);
+ stage.sizeToScene();
+ stage.show();
+ }
+
+ public static void main(String[] args) {
+ Application.launch(args);
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/javafx/TestNewtCanvasJFXGLn.java b/src/test/com/jogamp/opengl/test/junit/jogl/javafx/TestNewtCanvasJFXGLn.java
new file mode 100644
index 000000000..27ce49af4
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/javafx/TestNewtCanvasJFXGLn.java
@@ -0,0 +1,516 @@
+/**
+ * Copyright 2019 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.javafx;
+
+import com.jogamp.opengl.GLAutoDrawable;
+import com.jogamp.opengl.GLCapabilities;
+import com.jogamp.opengl.GLCapabilitiesImmutable;
+import com.jogamp.opengl.GLEventListener;
+import com.jogamp.opengl.GLProfile;
+
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Test;
+import org.junit.FixMethodOrder;
+import org.junit.runners.MethodSorters;
+
+import com.jogamp.common.util.RunnableTask;
+import com.jogamp.nativewindow.javafx.JFXAccessor;
+import com.jogamp.newt.NewtFactory;
+import com.jogamp.newt.Screen;
+import com.jogamp.newt.event.WindowAdapter;
+import com.jogamp.newt.event.WindowEvent;
+import com.jogamp.newt.javafx.NewtCanvasJFX;
+import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.newt.opengl.util.NEWTDemoListener;
+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.newt.parenting.NewtJFXReparentingKeyAdapter;
+import com.jogamp.opengl.test.junit.newt.parenting.NewtReparentingKeyAdapter;
+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;
+import com.jogamp.opengl.util.GLReadBufferUtil;
+import com.jogamp.opengl.util.texture.TextureIO;
+
+import javafx.application.Application;
+import javafx.application.Platform;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.scene.Group;
+import javafx.scene.Scene;
+import javafx.scene.canvas.Canvas;
+import javafx.scene.canvas.GraphicsContext;
+import javafx.scene.paint.Color;
+import javafx.scene.text.Font;
+import javafx.scene.text.Text;
+import javafx.stage.Stage;
+
+/**
+ * {@link NewtCanvasJFX} basic functional integration test
+ * of its native parented NEWT child {@link GLWindow} attached to JavaFX's {@link Canvas}.
+ * <p>
+ * {@link NewtCanvasJFX} allows utilizing custom {@link GLCapabilities} settings independent from the JavaFX's window
+ * as well as independent rendering from JavaFX's thread.
+ * </p>
+ * <p>
+ * This unit tests also tests {@link NewtCanvasJFX} native parenting operations before and after
+ * it's belonging Group's Scene has been attached to the JavaFX {@link javafx.stage.Window Window}'s actual native window,
+ * i.e. becoming fully realized and visible.
+ * </p>
+ * <p>
+ * Note that {@link JFXAccessor#runOnJFXThread(boolean, Runnable)} is still used to for certain
+ * mandatory JavaFX lifecycle operation on the JavaFX thread.
+ * </p>
+ * <p>
+ * The demo code uses {@link NewtReparentingKeyAdapter} including {@link NEWTDemoListener} functionality.
+ * </p>
+ * <p>
+ * Manual invocation via main allows running a single test, e.g. {@code -test 21}, and setting each tests's duration in milliseconds, e.g.{@code -time 10000}.
+ * </p>
+ */
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class TestNewtCanvasJFXGLn extends UITestCase {
+
+ static int duration = 5000; // 250;
+ static int manualTestID = -1;
+
+ com.jogamp.newt.Display jfxNewtDisplay = null;
+
+ public static class JFXApp extends Application {
+ static Stage stage;
+
+ final static Object sync = new Object();
+ static volatile boolean isLaunched = false;
+
+ public JFXApp() {
+ }
+
+ @Override public void init() throws Exception {
+ // pre JFX thread
+ System.err.println("JFX init ...: "+Thread.currentThread());
+ }
+
+ @Override public void start(final Stage stage) {
+ System.err.println("JFX start.0 ...: "+Thread.currentThread());
+ synchronized(sync) {
+ try {
+ // on JFX thread
+ final Scene scene = new Scene(new Group(), defWidth, defHeight);
+ stage.setTitle(TestNewtCanvasJFXGLn.class.getSimpleName());
+ stage.setScene(scene);
+ stage.sizeToScene();
+ {
+ final long h = JFXAccessor.getWindowHandle(stage);
+ System.err.println("t1 - Native window: 0x"+Long.toHexString(h));
+ }
+ stage.show();
+ {
+ final long h = JFXAccessor.getWindowHandle(stage);
+ System.err.println("t2 - Native window: 0x"+Long.toHexString(h));
+ }
+ JFXApp.stage = stage;
+ } finally {
+ isLaunched = true;
+ sync.notifyAll();
+ }
+ }
+ System.err.println("JFX start.X ...: "+Thread.currentThread());
+ }
+ @Override public void stop() throws Exception {
+ System.err.println("JFX stop ...: "+Thread.currentThread());
+ }
+ public static void startup() throws InterruptedException {
+ System.out.println( "GLProfile " + GLProfile.glAvailabilityToString() );
+ System.err.println("JFX Available: "+JFXAccessor.isJFXAvailable());
+ if( JFXAccessor.isJFXAvailable() ) {
+ Platform.setImplicitExit(false); // FIXME: Default for all NEWT cases?
+ synchronized(sync) {
+ final Thread ct = Thread.currentThread();
+ RunnableTask.invokeOnNewThread(ct.getThreadGroup(), ct.getName()+"JFXLauncher", false,
+ new Runnable() {
+ public void run() {
+ Application.launch(JFXApp.class);
+ }
+ });
+ while(!isLaunched) {
+ sync.wait();
+ }
+ }
+ System.err.println("JFX launched ...");
+ }
+ }
+ public static void shutdown() {
+ JFXAccessor.runOnJFXThread(true, new Runnable() {
+ public void run() {
+ if( null != stage ) {
+ stage.close();
+ }
+ } });
+ }
+ }
+
+ @BeforeClass
+ public static void startup() throws InterruptedException {
+ JFXApp.startup();
+ }
+
+ @AfterClass
+ public static void shutdown() {
+ JFXApp.shutdown();
+ Platform.exit();
+ }
+
+ @Before
+ public void init() {
+ jfxNewtDisplay = NewtFactory.createDisplay(null, false); // no-reuse
+ }
+
+ @After
+ public void release() {
+ jfxNewtDisplay = null;
+ }
+
+ class WaitAction implements Runnable {
+ private final long sleepMS;
+
+ WaitAction(final long sleepMS) {
+ this.sleepMS = sleepMS;
+ }
+ public void run() {
+ // blocks on linux .. display.sleep();
+ try {
+ Thread.sleep(sleepMS);
+ } catch (final InterruptedException e) { }
+ }
+ }
+ final WaitAction awtRobotWaitAction = new WaitAction(AWTRobotUtil.TIME_SLICE);
+ final WaitAction generalWaitAction = new WaitAction(10);
+
+ static final int defWidth = 800, defHeight = 600;
+
+ static void populateScene(final Scene scene, final boolean postAttach,
+ final GLWindow glWindow,
+ final int width, final int height, final boolean useBorder,
+ final NewtCanvasJFX[] res) {
+ final javafx.stage.Window w = scene.getWindow();
+ final boolean isShowing = null != w && w.isShowing();
+ final Group g = new Group();
+
+ final int cx, cy, cw, ch, bw, bh;
+ if( useBorder ) {
+ bw = width/5; bh = height/5;
+ cx = bw; cy = bh; cw = width-bw-bw; ch = height-bh-bh;
+ } else {
+ bw = 0; bh = 0;
+ cx = 0; cy = 0; cw = width; ch = height;
+ }
+ System.err.println("Scene "+width+"x"+height+", isShowing "+isShowing+", postAttach "+postAttach);
+ System.err.println("Scene.canvas "+cx+"/"+cy+" "+cw+"x"+ch);
+ System.err.println("Scene.border "+bw+"x"+bh);
+
+ if( !postAttach ) {
+ if(isShowing) {
+ JFXAccessor.runOnJFXThread(true, new Runnable() {
+ @Override
+ public void run() {
+ scene.setRoot(g);
+ }});
+ } else {
+ scene.setRoot(g);
+ }
+ }
+
+ final Canvas canvas0;
+ if( null == res ) {
+ canvas0 = new Canvas();
+ } else {
+ res[0] = new NewtCanvasJFX( glWindow );
+ canvas0 = res[0];
+ }
+ canvas0.setWidth(cw);
+ canvas0.setHeight(ch);
+ if( null == res ) {
+ final GraphicsContext gc = canvas0.getGraphicsContext2D();
+ gc.setFill(Color.BLUE);
+ gc.fillRect(0, 0, cw, ch);
+ }
+ canvas0.relocate(cx, cy);
+
+ final Text text0 = new Text(0, 0, "left");
+ {
+ text0.setFont(new Font(40));
+ text0.relocate(0, height/2);
+ }
+ final Text text1 = new Text(0, 0, "above");
+ {
+ text1.setFont(new Font(40));
+ text1.relocate(width/2, bh-40);
+ }
+ final Text text2 = new Text(0, 0, "right");
+ {
+ text2.setFont(new Font(40));
+ text2.relocate(width-bw, height/2);
+ }
+ final Text text3 = new Text(0, 0, "below");
+ {
+ text3.setFont(new Font(40));
+ text3.relocate(width/2, height-bh);
+ }
+ final Runnable attach2Group = new Runnable() {
+ @Override
+ public void run() {
+ g.getChildren().add(text0);
+ g.getChildren().add(text1);
+ g.getChildren().add(canvas0);
+ g.getChildren().add(text2);
+ g.getChildren().add(text3);
+ } };
+ if( !postAttach && isShowing ) {
+ JFXAccessor.runOnJFXThread(true, attach2Group);
+ } else {
+ attach2Group.run();
+ }
+ if( postAttach ) {
+ if(isShowing) {
+ JFXAccessor.runOnJFXThread(true, new Runnable() {
+ @Override
+ public void run() {
+ scene.setRoot(g);
+ }});
+ } else {
+ scene.setRoot(g);
+ }
+ }
+ }
+
+ protected void runTestAGL( final GLCapabilitiesImmutable caps, final GLEventListener demo,
+ final boolean postAttachNewtCanvas, final boolean postAttachGLWindow,
+ final boolean useAnimator ) throws InterruptedException {
+ if( !JFXAccessor.isJFXAvailable() ) {
+ System.err.println("JFX not available");
+ return;
+ }
+ final GLReadBufferUtil screenshot = new GLReadBufferUtil(false, false);
+ final GLWindow glWindow1;
+ if( null == demo ) {
+ glWindow1 = null;
+ } else {
+ final Screen screen = NewtFactory.createScreen(jfxNewtDisplay, 0);
+ glWindow1 = GLWindow.create(screen, caps);
+ Assert.assertNotNull(glWindow1);
+ Assert.assertEquals(false, glWindow1.isVisible());
+ Assert.assertEquals(false, glWindow1.isNativeValid());
+ Assert.assertNull(glWindow1.getParent());
+ glWindow1.addGLEventListener(demo);
+ glWindow1.addGLEventListener(new GLEventListener() {
+ int displayCount = 0;
+ public void init(final GLAutoDrawable drawable) { }
+ 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(displayCount++, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
+ }
+ }
+ public void dispose(final GLAutoDrawable drawable) { }
+ });
+ }
+
+ final NewtCanvasJFX[] glCanvas = null==demo? null : new NewtCanvasJFX[]{null};
+
+ final Scene scene = new Scene(new Group(), defWidth, defHeight);
+ if(!postAttachNewtCanvas) {
+ System.err.println("Stage set.A0");
+ JFXAccessor.runOnJFXThread(true, new Runnable() {
+ public void run() {
+ System.err.println("Stage set.A1");
+ JFXApp.stage.setScene(scene);
+ JFXApp.stage.sizeToScene();
+ System.err.println("Stage set.AX");
+ } });
+ }
+ populateScene( scene, postAttachNewtCanvas, postAttachGLWindow?null:glWindow1, defWidth, defHeight, true, glCanvas);
+ if(postAttachNewtCanvas) {
+ System.err.println("Stage set.B0");
+ JFXAccessor.runOnJFXThread(true, new Runnable() {
+ public void run() {
+ System.err.println("Stage set.B1");
+ JFXApp.stage.setScene(scene);
+ JFXApp.stage.sizeToScene();
+ System.err.println("Stage set.BX");
+ } });
+ }
+
+ if(postAttachGLWindow && null != demo) {
+ glCanvas[0].setNEWTChild(glWindow1);
+ }
+
+ if( null != glWindow1 ) {
+ Assert.assertTrue("GLWindow didn't become visible natively!", AWTRobotUtil.waitForRealized(glWindow1, awtRobotWaitAction, true));
+ System.err.println("GLWindow LOS.0: "+glWindow1.getLocationOnScreen(null));
+ glWindow1.addWindowListener(new WindowAdapter() {
+ public void windowResized(final WindowEvent e) {
+ System.err.println("window resized: "+glWindow1.getX()+"/"+glWindow1.getY()+" "+glWindow1.getSurfaceWidth()+"x"+glWindow1.getSurfaceHeight());
+ }
+ public void windowMoved(final WindowEvent e) {
+ System.err.println("window moved: "+glWindow1.getX()+"/"+glWindow1.getY()+" "+glWindow1.getSurfaceWidth()+"x"+glWindow1.getSurfaceHeight());
+ }
+ });
+ final NewtReparentingKeyAdapter newtDemoListener = new NewtJFXReparentingKeyAdapter(JFXApp.stage, glCanvas[0], glWindow1);
+ newtDemoListener.quitAdapterEnable(true);
+ glWindow1.addKeyListener(newtDemoListener);
+ glWindow1.addMouseListener(newtDemoListener);
+ glWindow1.addWindowListener(newtDemoListener);
+
+ final ChangeListener<Number> sizeListener = new ChangeListener<Number>() {
+ @Override public void changed(final ObservableValue<? extends Number> observable, final Number oldValue, final Number newValue) {
+ newtDemoListener.setTitle();
+ } };
+ JFXApp.stage.widthProperty().addListener(sizeListener);
+ JFXApp.stage.heightProperty().addListener(sizeListener);
+
+ }
+ if( null != demo ) {
+ System.err.println("NewtCanvasJFX LOS.0: "+glCanvas[0].getNativeWindow().getLocationOnScreen(null));
+ }
+
+ Animator anim;
+ if(useAnimator && null != demo) {
+ anim = new Animator(glWindow1);
+ anim.start();
+ } else {
+ anim = null;
+ }
+
+ final long lStartTime = System.currentTimeMillis();
+ final long lEndTime = lStartTime + duration;
+ try {
+ while( (System.currentTimeMillis() < lEndTime) ) {
+ generalWaitAction.run();
+ }
+ } catch( final Throwable throwable ) {
+ throwable.printStackTrace();
+ Assume.assumeNoException( throwable );
+ }
+ if(null != anim) {
+ anim.stop();
+ }
+
+ JFXAccessor.runOnJFXThread(true, new Runnable() {
+ public void run() {
+ populateScene( JFXApp.stage.getScene(), false, null, defWidth, defHeight, true, null);
+ JFXApp.stage.sizeToScene();
+ } });
+ }
+
+ @Test
+ public void test00() throws InterruptedException {
+ if( 0 > manualTestID || 0 == manualTestID ) {
+ runTestAGL( null, null,
+ false /* postAttachNewtCanvas */, false /* postAttach */, false /* animator */);
+ }
+ }
+
+ @Test
+ public void test11_preAttachNewtGL_NoAnim() throws InterruptedException {
+ if( 0 > manualTestID || 11 == manualTestID ) {
+ runTestAGL( new GLCapabilities(GLProfile.getGL2ES2()), new GearsES2(),
+ false /* postAttachNewtCanvas */, false /* postAttachGLWindow */, false /* animator */);
+ }
+ }
+
+ @Test
+ public void test12_postAttachNewt_NoAnim() throws InterruptedException {
+ if( 0 > manualTestID || 12 == manualTestID ) {
+ runTestAGL( new GLCapabilities(GLProfile.getGL2ES2()), new GearsES2(),
+ true /* postAttachNewtCanvas */, false /* postAttachGLWindow */, false /* animator */);
+ }
+ }
+
+ @Test
+ public void test13_postAttachGL_NoAnim() throws InterruptedException {
+ if( 0 > manualTestID || 13 == manualTestID ) {
+ runTestAGL( new GLCapabilities(GLProfile.getGL2ES2()), new GearsES2(),
+ false /* postAttachNewtCanvas */, true /* postAttachGLWindow */, false /* animator */);
+ }
+ }
+
+ @Test
+ public void test14_postAttachNewtGL_NoAnim() throws InterruptedException {
+ if( 0 > manualTestID || 14 == manualTestID ) {
+ runTestAGL( new GLCapabilities(GLProfile.getGL2ES2()), new GearsES2(),
+ true /* postAttachNewtCanvas */, true /* postAttachGLWindow */, false /* animator */);
+ }
+ }
+
+ @Test
+ public void test21_preAttachNewtGL_DoAnim() throws InterruptedException {
+ if( 0 > manualTestID || 21 == manualTestID ) {
+ runTestAGL( new GLCapabilities(GLProfile.getGL2ES2()), new GearsES2(),
+ false /* postAttachNewtCanvas */, false /* postAttachGLWindow */, true /* animator */);
+ }
+ }
+
+ @Test
+ public void test22_postAttachNewt_DoAnim() throws InterruptedException {
+ if( 0 > manualTestID || 22 == manualTestID ) {
+ runTestAGL( new GLCapabilities(GLProfile.getGL2ES2()), new GearsES2(),
+ true /* postAttachNewtCanvas */, false /* postAttachGLWindow */, true /* animator */);
+ }
+ }
+
+ @Test
+ public void test30_MultisampleAndAlpha() throws InterruptedException {
+ if( 0 > manualTestID || 30 == manualTestID ) {
+ final GLCapabilities caps = new GLCapabilities(GLProfile.getGL2ES2());
+ caps.setSampleBuffers(true);
+ caps.setNumSamples(2);
+ runTestAGL( caps, new MultisampleDemoES2(true),
+ false /* postAttachNewtCanvas */, false /* postAttachGLWindow */, false /* animator */);
+ }
+ }
+
+ public static void main(final String args[]) {
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-time")) {
+ duration = MiscUtils.atoi(args[++i], duration);
+ }
+ if(args[i].equals("-test")) {
+ manualTestID = MiscUtils.atoi(args[++i], -1);
+ }
+ }
+ System.out.println("durationPerTest: "+duration+", test "+manualTestID);
+ org.junit.runner.JUnitCore.main(TestNewtCanvasJFXGLn.class.getName());
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/math/TestPMVMatrix01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/math/TestPMVMatrix01NEWT.java
index 1e65b15bc..04413315a 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/math/TestPMVMatrix01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/math/TestPMVMatrix01NEWT.java
@@ -47,7 +47,6 @@ import org.junit.Test;
import org.junit.FixMethodOrder;
import org.junit.runners.MethodSorters;
-import com.jogamp.common.os.Platform;
import com.jogamp.opengl.math.FloatUtil;
import com.jogamp.opengl.math.geom.Frustum;
import com.jogamp.opengl.test.junit.util.MiscUtils;
@@ -102,6 +101,7 @@ public class TestPMVMatrix01NEWT extends UITestCase {
0.0f, 0.0f, 0.0f, 1.0f } );
@Test
+ @SuppressWarnings("deprecation")
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();
@@ -328,7 +328,6 @@ public class TestPMVMatrix01NEWT extends UITestCase {
// System.err.println("P2: "+pmv.toString());
}
- @SuppressWarnings("unused")
@Test
public void test03MvTranslate() {
final FloatBuffer pmvMv;
@@ -367,7 +366,6 @@ public class TestPMVMatrix01NEWT extends UITestCase {
// System.err.println("pmvMvit: "+Platform.NEWLINE+PMVMatrix.matrixToString(null, "%10.5f", pmvMvit));
}
- @SuppressWarnings("unused")
@Test
public void test04MvTranslateRotate() {
final FloatBuffer pmvMv;
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestBug672NewtCanvasSWTSashForm.java b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestBug672NewtCanvasSWTSashForm.java
index aec728cad..eec31b064 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestBug672NewtCanvasSWTSashForm.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestBug672NewtCanvasSWTSashForm.java
@@ -198,14 +198,14 @@ public class TestBug672NewtCanvasSWTSashForm extends UITestCase {
return;
}
if(e.getKeyChar()=='f') {
- new Thread() {
+ glWindow.invokeOnNewThread(null, false, new Runnable() {
public void run() {
final Thread t = glWindow.setExclusiveContextThread(null);
System.err.println("[set fullscreen pre]: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getSurfaceWidth()+"x"+glWindow.getSurfaceHeight()+", f "+glWindow.isFullscreen()+", a "+glWindow.isAlwaysOnTop()+", "+glWindow.getInsets());
glWindow.setFullscreen(!glWindow.isFullscreen());
System.err.println("[set fullscreen post]: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getSurfaceWidth()+"x"+glWindow.getSurfaceHeight()+", f "+glWindow.isFullscreen()+", a "+glWindow.isAlwaysOnTop()+", "+glWindow.getInsets());
glWindow.setExclusiveContextThread(t);
- } }.start();
+ } } );
}
}
});
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestBug672NewtCanvasSWTSashFormComposite.java b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestBug672NewtCanvasSWTSashFormComposite.java
index 0578492e2..fdd6d6458 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestBug672NewtCanvasSWTSashFormComposite.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestBug672NewtCanvasSWTSashFormComposite.java
@@ -205,14 +205,14 @@ public class TestBug672NewtCanvasSWTSashFormComposite extends UITestCase {
return;
}
if(e.getKeyChar()=='f') {
- new Thread() {
+ glWindow.invokeOnNewThread(null, false, new Runnable() {
public void run() {
final Thread t = glWindow.setExclusiveContextThread(null);
System.err.println("[set fullscreen pre]: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getSurfaceWidth()+"x"+glWindow.getSurfaceHeight()+", f "+glWindow.isFullscreen()+", a "+glWindow.isAlwaysOnTop()+", "+glWindow.getInsets());
glWindow.setFullscreen(!glWindow.isFullscreen());
System.err.println("[set fullscreen post]: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getSurfaceWidth()+"x"+glWindow.getSurfaceHeight()+", f "+glWindow.isFullscreen()+", a "+glWindow.isAlwaysOnTop()+", "+glWindow.getInsets());
glWindow.setExclusiveContextThread(t);
- } }.start();
+ } } );
}
}
});
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestNewtCanvasSWTBug628ResizeDeadlockAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestNewtCanvasSWTBug628ResizeDeadlockAWT.java
index 9a422f411..22053483e 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestNewtCanvasSWTBug628ResizeDeadlockAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestNewtCanvasSWTBug628ResizeDeadlockAWT.java
@@ -50,7 +50,8 @@ import com.jogamp.opengl.GLCapabilities ;
import com.jogamp.opengl.GLEventListener ;
import com.jogamp.opengl.GLProfile;
import com.jogamp.opengl.fixedfunc.GLMatrixFunc;
-
+import com.jogamp.common.util.InterruptSource;
+import com.jogamp.common.util.InterruptedRuntimeException;
import com.jogamp.nativewindow.swt.SWTAccessor;
import com.jogamp.newt.NewtFactory;
import com.jogamp.newt.event.KeyAdapter;
@@ -143,14 +144,13 @@ public class TestNewtCanvasSWTBug628ResizeDeadlockAWT extends UITestCase {
////////////////////////////////////////////////////////////////////////////////
- static class ResizeThread extends Thread {
+ static class ResizeThread extends InterruptSource.Thread {
volatile boolean shallStop = false;
private final Shell _shell ;
private int _n ;
public ResizeThread( final Shell shell )
{
- super();
_shell = shell ;
}
@@ -196,9 +196,9 @@ public class TestNewtCanvasSWTBug628ResizeDeadlockAWT extends UITestCase {
display.asyncExec( resizeAction );
display.wake();
- Thread.sleep( 50L ) ;
+ java.lang.Thread.sleep( 50L ) ;
} catch( final InterruptedException e ) {
- break ;
+ throw new InterruptedRuntimeException(e);
}
}
System.err.println("*R-Exit* shallStop "+shallStop+", disposed "+_shell.isDisposed());
@@ -207,7 +207,7 @@ public class TestNewtCanvasSWTBug628ResizeDeadlockAWT extends UITestCase {
////////////////////////////////////////////////////////////////////////////////
- static class KeyfireThread extends Thread
+ static class KeyfireThread extends InterruptSource.Thread
{
volatile boolean shallStop = false;
Display _display;
@@ -216,6 +216,7 @@ public class TestNewtCanvasSWTBug628ResizeDeadlockAWT extends UITestCase {
public KeyfireThread(final Robot robot, final Display display)
{
+ super();
_robot = robot;
_display = display;
}
@@ -231,7 +232,7 @@ public class TestNewtCanvasSWTBug628ResizeDeadlockAWT extends UITestCase {
AWTRobotUtil.waitForIdle(_robot);
AWTRobotUtil.newtKeyPress(_n, _robot, true, KeyEvent.VK_0, 10);
AWTRobotUtil.newtKeyPress(_n, _robot, false, KeyEvent.VK_0, 0);
- Thread.sleep( 40L ) ;
+ java.lang.Thread.sleep( 40L ) ;
_n++;
if(!_display.isDisposed()) {
_display.wake();
@@ -368,7 +369,7 @@ public class TestNewtCanvasSWTBug628ResizeDeadlockAWT extends UITestCase {
}
{
- final Thread t = new Thread(new Runnable() {
+ final Thread t = new InterruptSource.Thread(null, new Runnable() {
@Override
public void run() {
try {
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTBug643AsyncExec.java b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTBug643AsyncExec.java
index 7072ed9ea..9b2e46d44 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTBug643AsyncExec.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTBug643AsyncExec.java
@@ -51,6 +51,7 @@ import com.jogamp.opengl.GLProfile;
import jogamp.newt.swt.SWTEDTUtil;
import jogamp.newt.swt.event.SWTNewtEventFactory;
+import com.jogamp.common.util.InterruptSource;
import com.jogamp.nativewindow.swt.SWTAccessor;
import com.jogamp.newt.NewtFactory;
import com.jogamp.newt.opengl.GLWindow ;
@@ -110,7 +111,7 @@ public class TestSWTBug643AsyncExec extends UITestCase {
////////////////////////////////////////////////////////////////////////////////
- static class AsyncExecEDTFeederThread extends Thread {
+ static class AsyncExecEDTFeederThread extends InterruptSource.Thread {
volatile boolean shallStop = false;
private final Display swtDisplay ;
private final jogamp.newt.DisplayImpl newtDisplay;
@@ -118,7 +119,6 @@ public class TestSWTBug643AsyncExec extends UITestCase {
public AsyncExecEDTFeederThread( final Display swtDisplay, final com.jogamp.newt.Display newtDisplay )
{
- super();
this.swtDisplay = swtDisplay ;
this.newtDisplay = (jogamp.newt.DisplayImpl)newtDisplay;
}
@@ -152,7 +152,7 @@ public class TestSWTBug643AsyncExec extends UITestCase {
// only perform async exec on valid and already running NEWT EDT!
newtDisplay.runOnEDTIfAvail(false, newtAsyncAction);
}
- Thread.sleep( 50L ) ;
+ java.lang.Thread.sleep( 50L ) ;
} catch( final InterruptedException e ) {
break ;
}
@@ -275,7 +275,7 @@ public class TestSWTBug643AsyncExec extends UITestCase {
}
{
- final Thread t = new Thread(new Runnable() {
+ final Thread t = new InterruptSource.Thread(null, new Runnable() {
@Override
public void run() {
try {
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
index f90b32009..572871233 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/util/DemoGL2ES1TextureImmModeSink.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/DemoGL2ES1TextureImmModeSink.java
@@ -97,7 +97,7 @@ public class DemoGL2ES1TextureImmModeSink implements GLEventListener, TextureDra
}
final GL2ES1 gl = FixedFuncUtil.wrapFixedFuncEmul(_gl, ShaderSelectionMode.AUTO, null, forceFFPEmu, verboseFFPEmu);
- final URLConnection testTextureUrlConn = IOUtil.getResource(PNGTstFiles.class, "test-ntscP_3-01-160x90.png");
+ final URLConnection testTextureUrlConn = IOUtil.getResource("test-ntscP_3-01-160x90.png", PNGTstFiles.class.getClassLoader(), PNGTstFiles.class);
try {
final InputStream testTextureStream = testTextureUrlConn.getInputStream();
textureData = TextureIO.newTextureData(gl.getGLProfile(), testTextureStream , false /* mipmap */, TextureIO.PNG);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/ImageTstFiles.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/ImageTstFiles.java
new file mode 100644
index 000000000..25bb7e788
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/ImageTstFiles.java
@@ -0,0 +1,128 @@
+/**
+ * Copyright 2014 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.texture;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URLConnection;
+import java.util.ArrayList;
+
+import com.jogamp.common.util.IOUtil;
+
+public class ImageTstFiles {
+ public static final String[] pngFileNames = new String[] {
+ "bug724-transparent-grey_gimpexp.png",
+ "bug724-transparent-grey_orig.png",
+ "cross-grey-alpha-16x16.png",
+ "grayscale_texture.png",
+ "pointer-grey-alpha-16x24.png",
+ "test-ntscI_3-01-160x90.png",
+ "test-ntscI_4-01-160x90.png",
+ "test-ntscIG3-01-160x90.png",
+ "test-ntscIG4-01-160x90.png",
+ "test-ntscN_3-01-160x90.png",
+ "test-ntscN_4-01-160x90.png",
+ "test-ntscNG4-01-160x90.png",
+ "test-ntscP_3-01-160x90.png",
+ "test-ntscP_4-01-160x90.png"
+ };
+
+ public static final String[] jpgFileNames = new String[] {
+ "bug745_qttdef_post_frame.jpg",
+ "darwin_03_N_4-YCCK-640x452.jpg", // local
+ "darwin_03_N_4-YCCK.jpg", // local
+ "j1-baseline.jpg",
+ "j2-progressive.jpg",
+ "j3-baseline_gray.jpg",
+ "test-cmyk-01.jpg",
+ "test-ntscN_3-01-160x90-60pct-yuv422h-base.jpg",
+ "test-ntscN_3-01-160x90-60pct-yuv422h-prog.jpg",
+ "test-ntscN_3-01-160x90-90pct-yuv444-base.jpg",
+ "test-ntscN_3-01-160x90-90pct-yuv444-prog.jpg",
+ "test-ycck-01.jpg" };
+
+ public static final String[] tgaFileNames = new String[] {
+ "bug744-rle32.tga",
+ "bug982.rle32.256x256.tga",
+ "test-u32.tga"
+ };
+ public static final String[] ddsFileNames = new String[] {
+ "test-64x32_DXT1.dds",
+ "test-64x32_DXT5.dds",
+ "test-64x32_uncompressed.dds"
+ };
+
+ public static class NamedInputStream {
+ final String fullPath;
+ final String basePath;
+ final InputStream stream;
+ public NamedInputStream(final String fullPath, final String basePath, final InputStream stream) {
+ this.fullPath = fullPath;
+ this.basePath = basePath;
+ this.stream = stream;
+ }
+ }
+ public ArrayList<NamedInputStream> pngStreams;
+ public ArrayList<NamedInputStream> jpgStreams;
+ public ArrayList<NamedInputStream> tgaStreams;
+ public ArrayList<NamedInputStream> ddsStreams;
+ public ArrayList<NamedInputStream> allStreams;
+
+ private final ArrayList<NamedInputStream> init(final String[] source) throws IOException {
+ final ArrayList<NamedInputStream> sink = new ArrayList<NamedInputStream>();
+ for(int i=0; i<source.length; i++) {
+ final URLConnection testTextureUrlConn = IOUtil.getResource(source[i], this.getClass().getClassLoader(), this.getClass());
+ if( null != testTextureUrlConn ) {
+ final InputStream s = testTextureUrlConn.getInputStream();
+ if( null != s ) {
+ sink.add(new NamedInputStream(testTextureUrlConn.getURL().toString(), source[i], s));
+ }
+ }
+ }
+ return sink;
+ }
+
+ public void init() throws IOException {
+ pngStreams = init(pngFileNames);
+ jpgStreams = init(jpgFileNames);
+ tgaStreams = init(tgaFileNames);
+ ddsStreams = init(ddsFileNames);
+ allStreams = new ArrayList<NamedInputStream>();
+ allStreams.addAll(pngStreams);
+ allStreams.addAll(jpgStreams);
+ allStreams.addAll(tgaStreams);
+ allStreams.addAll(ddsStreams);
+ }
+ public void clear() {
+ pngStreams.clear();
+ jpgStreams.clear();
+ tgaStreams.clear();
+ ddsStreams.clear();
+ allStreams.clear();
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestBug362DDSImageCreateFromData.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestBug362DDSImageCreateFromData.java
index a585e9eaf..71233d07c 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestBug362DDSImageCreateFromData.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestBug362DDSImageCreateFromData.java
@@ -56,7 +56,7 @@ public class TestBug362DDSImageCreateFromData {
}
private File initFile(final String filename) throws URISyntaxException {
- final URLConnection connection = IOUtil.getResource(getClass(), filename);
+ final URLConnection connection = IOUtil.getResource(filename, getClass().getClassLoader(), getClass());
Assert.assertNotNull(connection);
final URL url = connection.getURL();
final File file = new File(url.toURI());
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 8339831a0..7fc14a609 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
@@ -28,6 +28,7 @@
package com.jogamp.opengl.test.junit.jogl.util.texture;
+import com.jogamp.common.util.InterruptSource;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.GLAutoDrawable;
@@ -99,7 +100,7 @@ public class TestGLReadBufferUtilTextureIOWrite02NEWT extends UITestCase {
c=0;
snapshot(i++, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
dw_old = dw;
- new Thread() {
+ new InterruptSource.Thread() {
@Override
public void run() {
glWindow.setSize(2*dw, 2*dh);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestImageTypeNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestImageTypeNEWT.java
new file mode 100644
index 000000000..952d54443
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestImageTypeNEWT.java
@@ -0,0 +1,92 @@
+/**
+ * Copyright 2015 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.texture;
+
+import com.jogamp.opengl.test.junit.util.UITestCase;
+import com.jogamp.opengl.util.texture.ImageType;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.FixMethodOrder;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class TestImageTypeNEWT extends UITestCase {
+ ImageTstFiles imageTstFiles;
+
+ @Before
+ public void initTest() throws IOException {
+ imageTstFiles = new ImageTstFiles();
+ imageTstFiles.init();
+ }
+
+ @After
+ public void cleanupTest() {
+ imageTstFiles.clear();
+ }
+
+ public void testImpl(final List<ImageTstFiles.NamedInputStream> streams, final ImageType expImageType) throws InterruptedException, IOException {
+ for(int i=0; i<streams.size(); i++) {
+ final ImageTstFiles.NamedInputStream s = streams.get(i);
+ final ImageType t = new ImageType(s.stream);
+ System.err.printf("Test %3d: path %s, exp-type %s, has-type %s%n", i, s.basePath, expImageType, t);
+ Assert.assertEquals(expImageType, t);
+ }
+ }
+
+ @Test
+ public void test01AllPNG() throws InterruptedException, IOException {
+ testImpl(imageTstFiles.pngStreams, new ImageType(ImageType.T_PNG));
+ }
+
+ @Test
+ public void test02AllJPG() throws InterruptedException, IOException {
+ testImpl(imageTstFiles.jpgStreams, new ImageType(ImageType.T_JPG));
+ }
+
+ // TGA cannot be detected
+ // @Test
+ public void test03AllTGA() throws InterruptedException, IOException {
+ testImpl(imageTstFiles.tgaStreams, new ImageType(ImageType.T_TGA));
+ }
+
+ @Test
+ public void test04AllDDS() throws InterruptedException, IOException {
+ testImpl(imageTstFiles.ddsStreams, new ImageType(ImageType.T_DDS));
+ }
+
+ public static void main(final String args[]) throws IOException {
+ org.junit.runner.JUnitCore.main(TestImageTypeNEWT.class.getName());
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestJPEGImage01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestJPEGImage01NEWT.java
index 925382901..8ccc73f34 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestJPEGImage01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestJPEGImage01NEWT.java
@@ -146,7 +146,7 @@ public class TestJPEGImage01NEWT extends UITestCase {
@Test
public void testReadES2_RGBn() throws InterruptedException, IOException, MalformedURLException {
final String fname = null == _fname ? "test-ntscN_3-01-160x90-90pct-yuv444-base.jpg" : _fname;
- final URLConnection urlConn = IOUtil.getResource(this.getClass(), fname);
+ final URLConnection urlConn = IOUtil.getResource(fname, this.getClass().getClassLoader(), this.getClass());
testImpl(urlConn.getInputStream());
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestJPEGJoglAWTBenchmarkNewtAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestJPEGJoglAWTBenchmarkNewtAWT.java
index 4fc774463..87a993de4 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestJPEGJoglAWTBenchmarkNewtAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestJPEGJoglAWTBenchmarkNewtAWT.java
@@ -64,7 +64,7 @@ public class TestJPEGJoglAWTBenchmarkNewtAWT extends UITestCase {
{
final long t0 = System.currentTimeMillis();
for(int i = 0; i< loops; i++ ) {
- final URLConnection urlConn = IOUtil.getResource(this.getClass(), fname);
+ final URLConnection urlConn = IOUtil.getResource(fname, this.getClass().getClassLoader(), this.getClass());
final InputStream istream = urlConn.getInputStream();
final JPEGImage image = JPEGImage.read(istream); // parsing & completion done !!!
final int internalFormat = (image.getBytesPerPixel()==4)?GL.GL_RGBA:GL.GL_RGB;
@@ -92,7 +92,7 @@ public class TestJPEGJoglAWTBenchmarkNewtAWT extends UITestCase {
{
final long t0 = System.currentTimeMillis();
for(int i = 0; i< loops; i++ ) {
- final URLConnection urlConn = IOUtil.getResource(this.getClass(), fname);
+ final URLConnection urlConn = IOUtil.getResource(fname, this.getClass().getClassLoader(), this.getClass());
final InputStream istream = urlConn.getInputStream();
final JPEGImage image = JPEGImage.read(istream, TextureData.ColorSpace.YCbCr); // parsing & completion done !!!
final int internalFormat = (image.getBytesPerPixel()==4)?GL.GL_RGBA:GL.GL_RGB;
@@ -120,7 +120,7 @@ public class TestJPEGJoglAWTBenchmarkNewtAWT extends UITestCase {
{
final long t0 = System.currentTimeMillis();
for(int i = 0; i< loops; i++ ) {
- final URLConnection urlConn = IOUtil.getResource(this.getClass(), fname);
+ final URLConnection urlConn = IOUtil.getResource(fname, this.getClass().getClassLoader(), this.getClass());
final InputStream istream = urlConn.getInputStream();
Buffer data = null;
try {
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestJPEGJoglAWTCompareNewtAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestJPEGJoglAWTCompareNewtAWT.java
index d5c80553d..b48000046 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestJPEGJoglAWTCompareNewtAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestJPEGJoglAWTCompareNewtAWT.java
@@ -101,7 +101,7 @@ public class TestJPEGJoglAWTCompareNewtAWT extends UITestCase {
}
GLWindow testJOGLJpeg(final String fname) throws InterruptedException, IOException {
- final URLConnection testTextureUrlConn = IOUtil.getResource(this.getClass(), fname);
+ final URLConnection testTextureUrlConn = IOUtil.getResource(fname, this.getClass().getClassLoader(), this.getClass());
Assert.assertNotNull(testTextureUrlConn);
final InputStream istream = testTextureUrlConn.getInputStream();
Assert.assertNotNull(istream);
@@ -160,7 +160,7 @@ public class TestJPEGJoglAWTCompareNewtAWT extends UITestCase {
}
GLWindow testAWTJpeg(final String fname, final int xpos) throws InterruptedException, IOException {
- final URLConnection testTextureUrlConn = IOUtil.getResource(this.getClass(), fname);
+ final URLConnection testTextureUrlConn = IOUtil.getResource(fname, this.getClass().getClassLoader(), this.getClass());
Assert.assertNotNull(testTextureUrlConn);
final InputStream istream = testTextureUrlConn.getInputStream();
Assert.assertNotNull(istream);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestJPEGTextureFromFileNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestJPEGTextureFromFileNEWT.java
index 114561666..b43fba479 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestJPEGTextureFromFileNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestJPEGTextureFromFileNEWT.java
@@ -82,63 +82,63 @@ public class TestJPEGTextureFromFileNEWT extends UITestCase {
@Before
public void initTest() throws IOException {
{
- final URLConnection testTextureUrlConn = IOUtil.getResource(this.getClass(), "test-ntscN_3-01-160x90-90pct-yuv444-base.jpg");
+ final URLConnection testTextureUrlConn = IOUtil.getResource("test-ntscN_3-01-160x90-90pct-yuv444-base.jpg", this.getClass().getClassLoader(), this.getClass());
Assert.assertNotNull(testTextureUrlConn);
testTextureStream01YUV444_Base = testTextureUrlConn.getInputStream();
Assert.assertNotNull(testTextureStream01YUV444_Base);
}
{
- final URLConnection testTextureUrlConn = IOUtil.getResource(this.getClass(), "test-ntscN_3-01-160x90-90pct-yuv444-prog.jpg");
+ final URLConnection testTextureUrlConn = IOUtil.getResource("test-ntscN_3-01-160x90-90pct-yuv444-prog.jpg", this.getClass().getClassLoader(), this.getClass());
Assert.assertNotNull(testTextureUrlConn);
testTextureStream01YUV444_Prog = testTextureUrlConn.getInputStream();
Assert.assertNotNull(testTextureStream01YUV444_Prog);
}
{
- final URLConnection testTextureUrlConn = IOUtil.getResource(this.getClass(), "test-ntscN_3-01-160x90-60pct-yuv422h-base.jpg");
+ final URLConnection testTextureUrlConn = IOUtil.getResource("test-ntscN_3-01-160x90-60pct-yuv422h-base.jpg", this.getClass().getClassLoader(), this.getClass());
Assert.assertNotNull(testTextureUrlConn);
testTextureStream01YUV422h_Base = testTextureUrlConn.getInputStream();
Assert.assertNotNull(testTextureStream01YUV422h_Base);
}
{
- final URLConnection testTextureUrlConn = IOUtil.getResource(this.getClass(), "test-ntscN_3-01-160x90-60pct-yuv422h-prog.jpg");
+ final URLConnection testTextureUrlConn = IOUtil.getResource("test-ntscN_3-01-160x90-60pct-yuv422h-prog.jpg", this.getClass().getClassLoader(), this.getClass());
Assert.assertNotNull(testTextureUrlConn);
testTextureStream01YUV422h_Prog = testTextureUrlConn.getInputStream();
Assert.assertNotNull(testTextureStream01YUV422h_Prog);
}
{
- final URLConnection testTextureUrlConn = IOUtil.getResource(this.getClass(), "j1-baseline.jpg");
+ final URLConnection testTextureUrlConn = IOUtil.getResource("j1-baseline.jpg", this.getClass().getClassLoader(), this.getClass());
Assert.assertNotNull(testTextureUrlConn);
testTextureStream02YUV420_Base = testTextureUrlConn.getInputStream();
Assert.assertNotNull(testTextureStream02YUV420_Base);
}
{
- final URLConnection testTextureUrlConn = IOUtil.getResource(this.getClass(), "j2-progressive.jpg");
+ final URLConnection testTextureUrlConn = IOUtil.getResource("j2-progressive.jpg", this.getClass().getClassLoader(), this.getClass());
Assert.assertNotNull(testTextureUrlConn);
testTextureStream02YUV420_Prog = testTextureUrlConn.getInputStream();
Assert.assertNotNull(testTextureStream02YUV420_Prog);
}
{
- final URLConnection testTextureUrlConn = IOUtil.getResource(this.getClass(), "j3-baseline_gray.jpg");
+ final URLConnection testTextureUrlConn = IOUtil.getResource("j3-baseline_gray.jpg", this.getClass().getClassLoader(), this.getClass());
Assert.assertNotNull(testTextureUrlConn);
testTextureStream02YUV420_BaseGray = testTextureUrlConn.getInputStream();
Assert.assertNotNull(testTextureStream02YUV420_BaseGray);
}
{
- final URLConnection testTextureUrlConn = IOUtil.getResource(this.getClass(), "test-cmyk-01.jpg");
+ final URLConnection testTextureUrlConn = IOUtil.getResource("test-cmyk-01.jpg", this.getClass().getClassLoader(), this.getClass());
Assert.assertNotNull(testTextureUrlConn);
testTextureStream03CMYK_01 = testTextureUrlConn.getInputStream();
Assert.assertNotNull(testTextureStream03CMYK_01);
}
{
- final URLConnection testTextureUrlConn = IOUtil.getResource(this.getClass(), "test-ycck-01.jpg");
+ final URLConnection testTextureUrlConn = IOUtil.getResource("test-ycck-01.jpg", this.getClass().getClassLoader(), this.getClass());
Assert.assertNotNull(testTextureUrlConn);
testTextureStream03YCCK_01 = testTextureUrlConn.getInputStream();
Assert.assertNotNull(testTextureStream03YCCK_01);
}
{
- final URLConnection testTextureUrlConn = IOUtil.getResource(this.getClass(), "bug745_qttdef_post_frame.jpg");
+ final URLConnection testTextureUrlConn = IOUtil.getResource("bug745_qttdef_post_frame.jpg", this.getClass().getClassLoader(), this.getClass());
Assert.assertNotNull(testTextureUrlConn);
testTextureStream04QTTDefPostFrame = testTextureUrlConn.getInputStream();
Assert.assertNotNull(testTextureStream04QTTDefPostFrame);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGPixelRect00NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGPixelRect00NEWT.java
index 3918b6cb7..0506f840e 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGPixelRect00NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGPixelRect00NEWT.java
@@ -128,7 +128,7 @@ public class TestPNGPixelRect00NEWT extends UITestCase {
final File out2F_f=new File(getSimpleTestName(".")+"-02-"+basename+"-flipped.png");
final File out2R_f=new File(getSimpleTestName(".")+"-03-"+basename+"-reversed.png");
final File out2RF_f=new File(getSimpleTestName(".")+"-04-"+basename+"-reversed_flipped.png");
- final URLConnection urlConn = IOUtil.getResource(this.getClass(), pathname+basename+".png");
+ final URLConnection urlConn = IOUtil.getResource(pathname+basename+".png", this.getClass().getClassLoader(), this.getClass());
if( null == urlConn ) {
throw new IOException("Cannot find "+pathname+basename+".png");
}
@@ -205,7 +205,7 @@ public class TestPNGPixelRect00NEWT extends UITestCase {
System.err.println("Test02: "+pathname+basename+".png, destFmt "+destFmt+", destMinStrideInBytes "+destMinStrideInBytes+", destIsGLOriented "+destIsGLOriented);
final File out1_f=new File(getSimpleTestName(".")+"-"+basename+"-orig.png");
- final URLConnection urlConn = IOUtil.getResource(this.getClass(), pathname+basename+".png");
+ final URLConnection urlConn = IOUtil.getResource(pathname+basename+".png", this.getClass().getClassLoader(), this.getClass());
final PNGPixelRect image1 = PNGPixelRect.read(urlConn.getInputStream(), destFmt, false /* directBuffer */, destMinStrideInBytes, destIsGLOriented);
System.err.println("PNGPixelRect - Orig: "+image1);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGPixelRect01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGPixelRect01NEWT.java
index e299932b3..b6a047d03 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGPixelRect01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGPixelRect01NEWT.java
@@ -156,7 +156,7 @@ public class TestPNGPixelRect01NEWT extends UITestCase {
if( null == _fname ) {
return;
}
- final URLConnection urlConn = IOUtil.getResource(this.getClass(), _fname);
+ final URLConnection urlConn = IOUtil.getResource(_fname, this.getClass().getClassLoader(), this.getClass());
if( null == urlConn ) {
throw new IOException("Cannot find "+_fname+".png");
}
@@ -170,7 +170,7 @@ public class TestPNGPixelRect01NEWT extends UITestCase {
}
for(int i=0; i<PNGTstFiles.allBasenames.length; i++) {
final String basename = PNGTstFiles.allBasenames[i];
- final URLConnection urlConn = IOUtil.getResource(this.getClass(), basename+".png");
+ final URLConnection urlConn = IOUtil.getResource(basename+".png", this.getClass().getClassLoader(), this.getClass());
if( null == urlConn ) {
throw new IOException("Cannot find "+basename+".png");
}
@@ -184,7 +184,7 @@ public class TestPNGPixelRect01NEWT extends UITestCase {
}
for(int i=0; i<PNGTstFiles.greyBasenames.length; i++) {
final String basename = PNGTstFiles.greyBasenames[i];
- final URLConnection urlConn = IOUtil.getResource(this.getClass(), basename+".png");
+ final URLConnection urlConn = IOUtil.getResource(basename+".png", this.getClass().getClassLoader(), this.getClass());
if( null == urlConn ) {
throw new IOException("Cannot find "+basename+".png");
}
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 2d6b6da71..157fffb90 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
@@ -86,7 +86,7 @@ public class TestPNGTextureFromFileAWT extends UITestCase {
grayTextureStream = TestPNGTextureFromFileAWT.class.getResourceAsStream( "grayscale_texture.png" );
Assert.assertNotNull(grayTextureStream);
{
- final URLConnection testTextureUrlConn = IOUtil.getResource(this.getClass(), "test-ntscN_3-01-160x90.png");
+ final URLConnection testTextureUrlConn = IOUtil.getResource("test-ntscN_3-01-160x90.png", this.getClass().getClassLoader(), this.getClass());
Assert.assertNotNull(testTextureUrlConn);
testTextureStream = testTextureUrlConn.getInputStream();
Assert.assertNotNull(testTextureStream);
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 a82767f9a..d7017465e 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
@@ -82,44 +82,44 @@ public class TestPNGTextureFromFileNEWT extends UITestCase {
grayTextureStream = TestPNGTextureFromFileNEWT.class.getResourceAsStream( "grayscale_texture.png" );
Assert.assertNotNull(grayTextureStream);
{
- final URLConnection testTextureUrlConn = IOUtil.getResource(this.getClass(), "test-ntscN_3-01-160x90.png");
+ final URLConnection testTextureUrlConn = IOUtil.getResource("test-ntscN_3-01-160x90.png", this.getClass().getClassLoader(), this.getClass());
Assert.assertNotNull(testTextureUrlConn);
testTextureStreamN_3 = testTextureUrlConn.getInputStream();
Assert.assertNotNull(testTextureStreamN_3);
}
{
- final URLConnection testTextureUrlConn = IOUtil.getResource(this.getClass(), "test-ntscN_4-01-160x90.png");
+ final URLConnection testTextureUrlConn = IOUtil.getResource("test-ntscN_4-01-160x90.png", this.getClass().getClassLoader(), this.getClass());
Assert.assertNotNull(testTextureUrlConn);
testTextureStreamN_4 = testTextureUrlConn.getInputStream();
Assert.assertNotNull(testTextureStreamN_4);
}
{
- final URLConnection testTextureUrlConn = IOUtil.getResource(this.getClass(), "test-ntscNG4-01-160x90.png");
+ final URLConnection testTextureUrlConn = IOUtil.getResource("test-ntscNG4-01-160x90.png", this.getClass().getClassLoader(), this.getClass());
Assert.assertNotNull(testTextureUrlConn);
testTextureStreamNG4 = testTextureUrlConn.getInputStream();
Assert.assertNotNull(testTextureStreamNG4);
}
{
- final URLConnection testTextureUrlConn = IOUtil.getResource(this.getClass(), "test-ntscI_3-01-160x90.png");
+ final URLConnection testTextureUrlConn = IOUtil.getResource("test-ntscI_3-01-160x90.png", this.getClass().getClassLoader(), this.getClass());
Assert.assertNotNull(testTextureUrlConn);
testTextureStreamI_3 = testTextureUrlConn.getInputStream();
Assert.assertNotNull(testTextureStreamI_3);
}
{
- final URLConnection testTextureUrlConn = IOUtil.getResource(this.getClass(), "test-ntscIG3-01-160x90.png");
+ final URLConnection testTextureUrlConn = IOUtil.getResource("test-ntscIG3-01-160x90.png", this.getClass().getClassLoader(), this.getClass());
Assert.assertNotNull(testTextureUrlConn);
testTextureStreamIG3 = testTextureUrlConn.getInputStream();
Assert.assertNotNull(testTextureStreamIG3);
}
{
- final URLConnection testTextureUrlConn = IOUtil.getResource(this.getClass(), "test-ntscI_4-01-160x90.png");
+ final URLConnection testTextureUrlConn = IOUtil.getResource("test-ntscI_4-01-160x90.png", this.getClass().getClassLoader(), this.getClass());
Assert.assertNotNull(testTextureUrlConn);
testTextureStreamI_4 = testTextureUrlConn.getInputStream();
Assert.assertNotNull(testTextureStreamI_4);
}
{
- final URLConnection testTextureUrlConn = IOUtil.getResource(this.getClass(), "test-ntscIG4-01-160x90.png");
+ final URLConnection testTextureUrlConn = IOUtil.getResource("test-ntscIG4-01-160x90.png", this.getClass().getClassLoader(), this.getClass());
Assert.assertNotNull(testTextureUrlConn);
testTextureStreamIG4 = testTextureUrlConn.getInputStream();
Assert.assertNotNull(testTextureStreamIG4);
@@ -127,13 +127,13 @@ public class TestPNGTextureFromFileNEWT extends UITestCase {
{
- final URLConnection testTextureUrlConn = IOUtil.getResource(this.getClass(), "test-ntscP_3-01-160x90.png");
+ final URLConnection testTextureUrlConn = IOUtil.getResource("test-ntscP_3-01-160x90.png", this.getClass().getClassLoader(), this.getClass());
Assert.assertNotNull(testTextureUrlConn);
testTextureStreamP_3 = testTextureUrlConn.getInputStream();
Assert.assertNotNull(testTextureStreamP_3);
}
{
- final URLConnection testTextureUrlConn = IOUtil.getResource(this.getClass(), "test-ntscP_4-01-160x90.png");
+ final URLConnection testTextureUrlConn = IOUtil.getResource("test-ntscP_4-01-160x90.png", this.getClass().getClassLoader(), this.getClass());
Assert.assertNotNull(testTextureUrlConn);
testTextureStreamP_4 = testTextureUrlConn.getInputStream();
Assert.assertNotNull(testTextureStreamP_4);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPixelFormatUtil01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPixelFormatUtil01NEWT.java
index 618797e66..653ccadfd 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPixelFormatUtil01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPixelFormatUtil01NEWT.java
@@ -83,7 +83,7 @@ public class TestPixelFormatUtil01NEWT extends UITestCase {
{
System.err.println("Test01: "+pathname+basename+".png, srcFmt "+srcFmt+", destMinStrideInBytes "+destMinStrideInBytes+", destIsGLOriented "+destIsGLOriented);
- final URLConnection urlConn = IOUtil.getResource(this.getClass(), pathname+basename+".png");
+ final URLConnection urlConn = IOUtil.getResource(pathname+basename+".png", this.getClass().getClassLoader(), this.getClass());
final PNGPixelRect image1 = PNGPixelRect.read(urlConn.getInputStream(), srcFmt, false /* directBuffer */, destMinStrideInBytes, false /* isGLOriented */);
System.err.println("PNGPixelRect - Orig: "+image1);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestTGATextureFromFileNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestTGATextureFromFileNEWT.java
index 6e0af17da..23f4593d8 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestTGATextureFromFileNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestTGATextureFromFileNEWT.java
@@ -69,19 +69,19 @@ public class TestTGATextureFromFileNEWT extends UITestCase {
@Before
public void initTest() throws IOException {
{
- final URLConnection testTextureUrlConn = IOUtil.getResource(this.getClass(), "test-u32.tga");
+ final URLConnection testTextureUrlConn = IOUtil.getResource("test-u32.tga", this.getClass().getClassLoader(), this.getClass());
Assert.assertNotNull(testTextureUrlConn);
testTextureStream01U32 = testTextureUrlConn.getInputStream();
Assert.assertNotNull(testTextureStream01U32);
}
{
- final URLConnection testTextureUrlConn = IOUtil.getResource(this.getClass(), "bug744-rle32.tga");
+ final URLConnection testTextureUrlConn = IOUtil.getResource("bug744-rle32.tga", this.getClass().getClassLoader(), this.getClass());
Assert.assertNotNull(testTextureUrlConn);
testTextureStream02RLE32 = testTextureUrlConn.getInputStream();
Assert.assertNotNull(testTextureStream02RLE32);
}
{
- final URLConnection testTextureUrlConn = IOUtil.getResource(this.getClass(), "bug982.rle32.256x256.tga");
+ final URLConnection testTextureUrlConn = IOUtil.getResource("bug982.rle32.256x256.tga", this.getClass().getClassLoader(), this.getClass());
Assert.assertNotNull(testTextureUrlConn);
testTextureStream03RLE32 = testTextureUrlConn.getInputStream();
Assert.assertNotNull(testTextureStream03RLE32);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestTextureIONEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestTextureIONEWT.java
new file mode 100644
index 000000000..56d9d481e
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestTextureIONEWT.java
@@ -0,0 +1,165 @@
+/**
+ * Copyright 2015 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.texture;
+
+import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.GLAutoDrawable;
+import com.jogamp.opengl.GLCapabilities;
+import com.jogamp.opengl.GLEventListener;
+import com.jogamp.opengl.GLProfile;
+import com.jogamp.opengl.test.junit.jogl.demos.TextureDraw01Accessor;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.TextureDraw01ES2Listener;
+import com.jogamp.opengl.test.junit.jogl.demos.gl2.TextureDraw01GL2Listener;
+import com.jogamp.opengl.test.junit.util.MiscUtils;
+import com.jogamp.opengl.test.junit.util.QuitAdapter;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+import com.jogamp.opengl.util.Animator;
+import com.jogamp.opengl.util.GLReadBufferUtil;
+import com.jogamp.opengl.util.texture.ImageType;
+import com.jogamp.opengl.util.texture.TextureData;
+import com.jogamp.opengl.util.texture.TextureIO;
+
+import org.junit.Assert;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.FixMethodOrder;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class TestTextureIONEWT extends UITestCase {
+ static long duration = 100; // ms
+
+ ImageTstFiles imageTstFiles;
+
+ @Before
+ public void initTest() throws IOException {
+ imageTstFiles = new ImageTstFiles();
+ imageTstFiles.init();
+ }
+
+ @After
+ public void cleanupTest() {
+ imageTstFiles.clear();
+ }
+
+ public void testImpl(final List<ImageTstFiles.NamedInputStream> streams, final ImageType expImageType) throws InterruptedException, IOException {
+ for(int i=0; i<streams.size(); i++) {
+ final ImageTstFiles.NamedInputStream s = streams.get(i);
+ System.err.printf("Test %3d: path %s, exp-type %s%n", i, s.basePath, expImageType);
+ testImpl(s.stream, expImageType);
+ }
+ }
+ public void testImpl(final InputStream istream, final ImageType expImageType) throws InterruptedException, IOException {
+ final GLReadBufferUtil screenshot = new GLReadBufferUtil(true, false);
+ final GLProfile glp = GLProfile.isAvailable(GLProfile.GL2ES2) ? GLProfile.getGL2ES2() : GLProfile.getDefault();
+ final GLCapabilities caps = new GLCapabilities(glp);
+ caps.setAlphaBits(1);
+
+ final TextureData texData = TextureIO.newTextureData(glp, istream, false /* mipmap */, expImageType.type);
+ System.err.println("TextureData: "+texData);
+ Assert.assertEquals(expImageType, texData.getSourceImageType());
+
+ final GLWindow glad = GLWindow.create(caps);
+ glad.setTitle("TestTextureIONEWT."+expImageType.type);
+ // Size OpenGL to Video Surface
+ glad.setSize(texData.getWidth(), texData.getHeight());
+
+ // load texture from file inside current GL context to match the way
+ // the bug submitter was doing it
+ final GLEventListener gle = glp.isGL2ES2() ? new TextureDraw01ES2Listener( texData, 0 ) : new TextureDraw01GL2Listener( texData ) ;
+ glad.addGLEventListener(gle);
+ glad.addGLEventListener(new GLEventListener() {
+ boolean shot = false;
+
+ @Override public void init(final GLAutoDrawable drawable) {}
+
+ public void display(final GLAutoDrawable drawable) {
+ // 1 snapshot
+ if(null!=((TextureDraw01Accessor)gle).getTexture() && !shot) {
+ shot = true;
+ snapshot(0, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
+ }
+ }
+
+ @Override public void dispose(final GLAutoDrawable drawable) { }
+ @Override public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height) { }
+ });
+
+ final Animator animator = new Animator(glad);
+ animator.setUpdateFPSFrames(60, null);
+ final QuitAdapter quitAdapter = new QuitAdapter();
+ glad.addKeyListener(quitAdapter);
+ glad.addWindowListener(quitAdapter);
+ glad.setVisible(true);
+ animator.start();
+
+ while(!quitAdapter.shouldQuit() && animator.isAnimating() && animator.getTotalFPSDuration()<duration) {
+ Thread.sleep(100);
+ }
+
+ animator.stop();
+ glad.destroy();
+ }
+
+ @Test
+ public void test01AllPNG() throws InterruptedException, IOException {
+ testImpl(imageTstFiles.pngStreams, new ImageType(ImageType.T_PNG));
+ }
+
+ @Test
+ public void test02AllJPG() throws InterruptedException, IOException {
+ testImpl(imageTstFiles.jpgStreams, new ImageType(ImageType.T_JPG));
+ }
+
+ @Test
+ public void test03AllTGA() throws InterruptedException, IOException {
+ testImpl(imageTstFiles.tgaStreams, new ImageType(ImageType.T_TGA));
+ }
+
+ @Test
+ public void test04AllDDS() throws InterruptedException, IOException {
+ testImpl(imageTstFiles.ddsStreams, new ImageType(ImageType.T_DDS));
+ }
+
+ public static void main(final String args[]) throws IOException {
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-time")) {
+ i++;
+ duration = MiscUtils.atol(args[i], duration);
+ }
+ }
+ org.junit.runner.JUnitCore.main(TestTextureIONEWT.class.getName());
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestBug1211IRQ00NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestBug1211IRQ00NEWT.java
new file mode 100644
index 000000000..186c3a79a
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestBug1211IRQ00NEWT.java
@@ -0,0 +1,324 @@
+/**
+ * Copyright 2015 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 java.io.IOException;
+
+import org.junit.Assert;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+import com.jogamp.common.ExceptionUtils;
+import com.jogamp.common.util.InterruptSource;
+import com.jogamp.common.util.SourcedInterruptedException;
+import com.jogamp.common.util.VersionUtil;
+import com.jogamp.junit.util.SingletonJunitCase;
+import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.newt.util.EDTUtil;
+import com.jogamp.opengl.GLCapabilities;
+import com.jogamp.opengl.GLCapabilitiesImmutable;
+import com.jogamp.opengl.GLProfile;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+import com.jogamp.opengl.util.Animator;
+
+/**
+ * Unit test to identify Thread.interrupt() caller for DefaultEDTUtil.invokeImpl(..) wait interruption.
+ * <ul>
+ * <li>resize</li>
+ * <li>create/destroy</li>
+ * </ul>
+ */
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class TestBug1211IRQ00NEWT extends SingletonJunitCase {
+ static long durationTest00 = 1000; // ms
+ static long durationTest01 = 1000; // ms
+ static int width = 800;
+ static int height = 600;
+
+ static GLWindow createWindow(final GLCapabilitiesImmutable caps) {
+ Assert.assertNotNull(caps);
+ //
+ // Create native windowing resources .. X11/Win/OSX
+ //
+ final GLWindow glWindow = GLWindow.create(caps);
+ Assert.assertNotNull(glWindow);
+ glWindow.setSize(width, height);
+
+ glWindow.setUpdateFPSFrames(1, null);
+
+ final GearsES2 demo = new GearsES2();
+ demo.setVerbose(false);
+ glWindow.addGLEventListener(demo);
+
+ return glWindow;
+ }
+
+ static void destroyWindow(final GLWindow glWindow) throws InterruptedException {
+ if(null!=glWindow) {
+ glWindow.destroy();
+ Assert.assertEquals(false,glWindow.isNativeValid());
+ }
+ }
+
+ static class MyThread extends InterruptSource.Thread implements Thread.UncaughtExceptionHandler {
+ volatile boolean myThreadStarted = false;
+ volatile boolean myThreadStopped = false;
+
+ public MyThread(final Runnable target, final String name) {
+ super(null, target, name);
+ setUncaughtExceptionHandler(this);
+ }
+
+ public static void testInterrupted1() throws InterruptedException {
+ if( java.lang.Thread.interrupted() ) {
+ throw SourcedInterruptedException.wrap(
+ new InterruptedException(java.lang.Thread.currentThread().getName()+".testInterrupted -> TRUE (silent interruption)"));
+ }
+ }
+ public synchronized void testInterrupted(final boolean ignore) throws InterruptedException {
+ if( isInterrupted() ) {
+ final boolean current;
+ if( this == java.lang.Thread.currentThread() ) {
+ java.lang.Thread.interrupted(); // clear!
+ current = true;
+ } else {
+ current = false;
+ }
+ final int counter = getInterruptCounter(false);
+ final Throwable source = getInterruptSource(true);
+ final InterruptedException e = new SourcedInterruptedException(
+ getName()+".testInterrupted -> TRUE (current "+current+", counter "+counter+")",
+ null, source);
+ if( !ignore ) {
+ throw e;
+ } else {
+ ExceptionUtils.dumpThrowable("Ignored", e);
+ }
+ }
+ }
+
+ @Override
+ public void run() {
+ myThreadStarted = true;
+ try {
+ super.run();
+ } finally {
+ myThreadStopped = true;
+ }
+ }
+
+ @Override
+ public void uncaughtException(final java.lang.Thread t, final Throwable e) {
+ System.err.println("UncaughtException on Thread "+t.getName()+": "+e.getMessage());
+ ExceptionUtils.dumpThrowable("UncaughtException", e);
+ }
+ }
+
+
+ volatile boolean interrupt1 = false;
+ volatile boolean interrupt2 = false;
+ volatile boolean interruptInit0 = false;
+
+ public void initTest() {
+ interrupt1 = false;
+ interrupt2 = false;
+ }
+
+ /**
+ * Test whether resize triggers DefaultEDTUtil.invokeImpl(..) wait interruption.
+ */
+ public void subTest00() {
+ final MyThread t = (MyThread)Thread.currentThread();
+ final GLCapabilities caps = new GLCapabilities(GLProfile.getDefault());
+ Assert.assertNotNull(caps);
+ final GLWindow window1 = createWindow(caps); // local
+ final EDTUtil edt = window1.getScreen().getDisplay().getEDTUtil();
+ final Animator anim = new Animator(window1);
+ try {
+ window1.setVisible(true);
+ Assert.assertEquals(true,window1.isVisible());
+ Assert.assertEquals(true,window1.isNativeValid());
+ anim.start();
+ boolean ok = true;
+ for(int i=0; ok && i*100<durationTest00; i++) {
+ Thread.sleep(100);
+ final int ow = window1.getWidth();
+ final int oh = window1.getHeight();
+ final int nw, nh;
+ if( 0 == i % 2 ) {
+ nw = ow + 100;
+ nh = oh + 100;
+ } else {
+ nw = ow - 100;
+ nh = oh - 100;
+ }
+ System.err.println("test00.resize["+i+"]: "+ow+"x"+oh+" -> "+nw+"x"+nh);
+ window1.setSize(nw, nh);
+ ok = 0==t.getInterruptCounter(false) && !t.isInterrupted() && edt.isRunning() && anim.isAnimating();
+ t.testInterrupted(false);
+ }
+ } catch (final InterruptedException e) {
+ ExceptionUtils.dumpThrowable("InterruptedException-1", e);
+ interrupt1 = true;
+ }
+ try {
+ anim.stop();
+ destroyWindow(window1);
+ t.testInterrupted(false);
+ } catch (final InterruptedException e) {
+ ExceptionUtils.dumpThrowable("InterruptedException-2", e);
+ interrupt2 = true;
+ }
+ Assert.assertEquals("interruptCounter not zero", 0, t.getInterruptCounter(false));
+ Assert.assertFalse("interrupt() occured!", t.isInterrupted());
+ Assert.assertFalse("Interrupt-1 occured!", interrupt1);
+ Assert.assertFalse("Interrupt-2 occured!", interrupt2);
+ }
+
+ /**
+ * Test whether create/destroy triggers DefaultEDTUtil.invokeImpl(..) wait interruption.
+ */
+ public void subTest01() {
+ final MyThread t = (MyThread)Thread.currentThread();
+ GLWindow lastWindow = null;
+ try {
+ final boolean ok = true;
+ for(int i=0; ok && i*100<durationTest01; i++) {
+ final GLCapabilities caps = new GLCapabilities(GLProfile.getDefault());
+ Assert.assertNotNull(caps);
+ final GLWindow window1 = createWindow(caps); // local
+ lastWindow = window1;
+ window1.setVisible(true);
+ Assert.assertEquals(true,window1.isVisible());
+ Assert.assertEquals(true,window1.isNativeValid());
+ System.err.println("test01.create["+i+"]: "+window1.getStateMaskString()+", "+window1.getWidth()+"x"+window1.getHeight());
+ final Animator anim = new Animator(window1);
+ anim.start();
+ Thread.sleep(100);
+ anim.stop();
+ destroyWindow(window1);
+ t.testInterrupted(false);
+ }
+ } catch (final InterruptedException e) {
+ ExceptionUtils.dumpThrowable("InterruptedException-1", e);
+ interrupt1 = true;
+ }
+ try {
+ destroyWindow(lastWindow);
+ t.testInterrupted(false);
+ } catch (final InterruptedException e) {
+ ExceptionUtils.dumpThrowable("InterruptedException-2", e);
+ interrupt2 = true;
+ }
+ Assert.assertEquals("interruptCounter not zero", 0, t.getInterruptCounter(false));
+ Assert.assertFalse("interrupt() occured!", t.isInterrupted());
+ Assert.assertFalse("Interrupt-1 occured!", interrupt1);
+ Assert.assertFalse("Interrupt-2 occured!", interrupt2);
+ }
+
+ @Test
+ public void testAll() {
+ interruptInit0 = false;
+ final MyThread t = new MyThread(new Runnable() {
+ public void run() {
+ final MyThread t = (MyThread)Thread.currentThread();
+ TestBug1211IRQ00NEWT test = null;
+ try {
+ System.err.println(VersionUtil.getPlatformInfo());
+ GLProfile.initSingleton();
+ test = new TestBug1211IRQ00NEWT();
+ t.testInterrupted(false);
+ } catch (final InterruptedException e) {
+ ExceptionUtils.dumpThrowable("InterruptedException-Init0", e);
+ interruptInit0 = true;
+ test = null;
+ }
+ t.clearInterruptSource();
+ if( null != test ) {
+ test.initTest();
+ test.subTest00();
+
+ test.initTest();
+ test.subTest01();
+ }
+ }
+ }, "MyMainThread");
+ t.start();
+ boolean interrupted = false;
+ try {
+ MyThread.testInterrupted1();
+ while( !t.myThreadStarted ) {
+ Thread.yield();
+ MyThread.testInterrupted1();
+ }
+ while( !t.myThreadStopped ) {
+ Thread.yield();
+ MyThread.testInterrupted1();
+ }
+ MyThread.testInterrupted1();
+ } catch (final InterruptedException e) {
+ ExceptionUtils.dumpThrowable("InterruptedException-All", e);
+ interrupted = true;
+ }
+ Assert.assertFalse("Thread Interrupt-All occured!", interrupted);
+ Assert.assertFalse("Interrupt-Init0 occured!", interruptInit0);
+ }
+
+ static int atoi(final String a) {
+ int i=0;
+ try {
+ i = Integer.parseInt(a);
+ } catch (final Exception ex) { ex.printStackTrace(); }
+ return i;
+ }
+
+ public static void main(final String args[]) throws IOException {
+ // We like to allow concurrent manual tests!
+ SingletonJunitCase.enableSingletonLock(false);
+
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-time00")) {
+ durationTest00 = atoi(args[++i]);
+ } else if(args[i].equals("-time01")) {
+ durationTest01 = atoi(args[++i]);
+ } else if(args[i].equals("-width")) {
+ width = atoi(args[++i]);
+ } else if(args[i].equals("-height")) {
+ height = atoi(args[++i]);
+ }
+ }
+ System.out.println("durationTest00: "+durationTest00);
+ System.out.println("durationTest01: "+durationTest01);
+ System.out.println("defaultSize : "+width+"x"+height);
+ final String tstname = TestBug1211IRQ00NEWT.class.getName();
+ org.junit.runner.JUnitCore.main(tstname);
+ }
+
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestGLWindows00NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestGLWindows00NEWT.java
index 9dd96acdd..38620ad92 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestGLWindows00NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestGLWindows00NEWT.java
@@ -49,6 +49,8 @@ import com.jogamp.nativewindow.AbstractGraphicsDevice;
public class TestGLWindows00NEWT extends UITestCase {
static GLProfile glp;
static int width, height;
+ static boolean manual = false;
+ static int loopVisibleToggle = 10;
static long durationPerTest = 100; // ms
@BeforeClass
@@ -58,7 +60,7 @@ public class TestGLWindows00NEWT extends UITestCase {
glp = GLProfile.getDefault();
}
- static GLWindow createWindow(final Screen screen, final GLCapabilitiesImmutable caps)
+ static GLWindow createWindow(final Screen screen, final GLCapabilitiesImmutable caps, final boolean undecor)
throws InterruptedException
{
Assert.assertNotNull(caps);
@@ -78,7 +80,9 @@ public class TestGLWindows00NEWT extends UITestCase {
final GLEventListener demo = new GearsES2();
glWindow.addGLEventListener(demo);
+ glWindow.setUndecorated(undecor);
glWindow.setSize(512, 512);
+ System.err.println("XXX VISIBLE.0 -> TRUE");
glWindow.setVisible(true);
Assert.assertEquals(true,glWindow.isVisible());
Assert.assertEquals(true,glWindow.isNativeValid());
@@ -90,25 +94,103 @@ public class TestGLWindows00NEWT extends UITestCase {
if(null!=glWindow) {
glWindow.destroy();
Assert.assertEquals(false,glWindow.isNativeValid());
+ Assert.assertEquals(false,glWindow.isVisible());
}
}
@Test
- public void testWindow00() throws InterruptedException {
+ public void test01WindowCreateSimple() throws InterruptedException {
+ if( manual ) {
+ return;
+ }
final GLCapabilities caps = new GLCapabilities(glp);
Assert.assertNotNull(caps);
- final GLWindow window1 = createWindow(null, caps); // local
- Assert.assertEquals(true,window1.isNativeValid());
- Assert.assertEquals(true,window1.isVisible());
- final AbstractGraphicsDevice device1 = window1.getScreen().getDisplay().getGraphicsDevice();
+ final GLWindow window = createWindow(null, caps, false /* undecor */); // local
+ Assert.assertEquals(true,window.isNativeValid());
+ Assert.assertEquals(true,window.isVisible());
+ final AbstractGraphicsDevice device1 = window.getScreen().getDisplay().getGraphicsDevice();
System.err.println("GLProfiles window1: "+device1.getConnection()+": "+GLProfile.glAvailabilityToString(device1));
for(int state=0; state*100<durationPerTest; state++) {
Thread.sleep(100);
}
- destroyWindow(window1);
+ destroyWindow(window);
+ }
+
+ @Test
+ public void test02WindowCreateUndecor() throws InterruptedException {
+ if( manual ) {
+ return;
+ }
+ final GLCapabilities caps = new GLCapabilities(glp);
+ Assert.assertNotNull(caps);
+ final GLWindow window = createWindow(null, caps, true /* undecor */); // local
+ Assert.assertEquals(true,window.isNativeValid());
+ Assert.assertEquals(true,window.isVisible());
+
+ final AbstractGraphicsDevice device1 = window.getScreen().getDisplay().getGraphicsDevice();
+ System.err.println("GLProfiles window1: "+device1.getConnection()+": "+GLProfile.glAvailabilityToString(device1));
+
+ for(int state=0; state*100<durationPerTest; state++) {
+ Thread.sleep(100);
+ }
+
+ destroyWindow(window);
+ }
+
+ @Test
+ public void test11WindowSimpleToggleVisibility() throws InterruptedException {
+ test1xWindowToggleVisibility(false /* undecor */, loopVisibleToggle);
+ }
+ @Test
+ public void test12WindowUndecorToggleVisibility() throws InterruptedException {
+ if( manual ) {
+ return;
+ }
+ test1xWindowToggleVisibility(true /* undecor */, loopVisibleToggle);
+ }
+ private void test1xWindowToggleVisibility(final boolean undecor, final int loopVisibleToggle) throws InterruptedException {
+ final GLCapabilities caps = new GLCapabilities(glp);
+ Assert.assertNotNull(caps);
+ final GLWindow window = createWindow(null, caps, undecor); // local
+ Assert.assertEquals(true,window.isNativeValid());
+ Assert.assertEquals(true,window.isVisible());
+
+ window.display();
+ Assert.assertEquals(true,window.isNativeValid());
+ Assert.assertEquals(true,window.isVisible());
+ for(int state=0; state*100<durationPerTest; state++) {
+ Thread.sleep(100);
+ }
+
+ for(int i=1; i<=loopVisibleToggle; i++) {
+ System.err.println("XXX VISIBLE."+i+" -> FALSE");
+ window.setVisible(false);
+ Assert.assertEquals(true,window.isNativeValid());
+ Assert.assertEquals(false,window.isVisible());
+ for(int state=0; state*100<durationPerTest; state++) {
+ Thread.sleep(100);
+ }
+
+ window.display();
+ Assert.assertEquals(true,window.isNativeValid());
+ Assert.assertEquals(false,window.isVisible());
+
+ System.err.println("XXX VISIBLE."+i+" -> TRUE");
+ window.setVisible(true);
+ Assert.assertEquals(true,window.isNativeValid());
+ Assert.assertEquals(true,window.isVisible());
+ for(int state=0; state*100<durationPerTest; state++) {
+ Thread.sleep(100);
+ }
+ window.display();
+ Assert.assertEquals(true,window.isNativeValid());
+ Assert.assertEquals(true,window.isVisible());
+ }
+
+ destroyWindow(window);
}
static int atoi(final String a) {
@@ -123,6 +205,10 @@ public class TestGLWindows00NEWT extends UITestCase {
for(int i=0; i<args.length; i++) {
if(args[i].equals("-time")) {
durationPerTest = atoi(args[++i]);
+ } else if(args[i].equals("-loopvt")) {
+ loopVisibleToggle = atoi(args[++i]);
+ } else if(args[i].equals("-manual")) {
+ manual = true;
}
}
System.out.println("durationPerTest: "+durationPerTest);
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestGLWindows01NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestGLWindows01NEWT.java
index ab8304504..00b31f400 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestGLWindows01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestGLWindows01NEWT.java
@@ -59,8 +59,7 @@ public class TestGLWindows01NEWT extends UITestCase {
}
static GLWindow createWindow(final Screen screen, final GLCapabilities caps,
- final int width, final int height, final boolean onscreen, final boolean undecorated,
- final boolean addGLEventListenerAfterVisible)
+ final int width, final int height, final boolean onscreen, final boolean addGLEventListenerAfterVisible)
throws InterruptedException
{
Assert.assertNotNull(caps);
@@ -79,7 +78,6 @@ public class TestGLWindows01NEWT extends UITestCase {
Assert.assertNotNull(glWindow);
}
- glWindow.setUndecorated(onscreen && undecorated);
Assert.assertEquals(false,glWindow.isVisible());
Assert.assertEquals(false,glWindow.isNativeValid());
@@ -122,16 +120,47 @@ public class TestGLWindows01NEWT extends UITestCase {
if(null!=glWindow) {
glWindow.destroy();
Assert.assertEquals(false,glWindow.isNativeValid());
+ Assert.assertEquals(false,glWindow.isVisible());
}
}
+
+ @Test
+ public void test01WindowSimple() throws InterruptedException {
+ final GLCapabilities caps = new GLCapabilities(glp);
+ Assert.assertNotNull(caps);
+ final GLWindow window = createWindow(null, caps, width, height,
+ true /* onscreen */, false /*addGLEventListenerAfterVisible*/);
+ System.out.println("Created: "+window);
+ int state;
+ for(state=0; state*100<durationPerTest; state++) {
+ Thread.sleep(100);
+ }
+ System.out.println("duration: "+window.getTotalFPSDuration());
+ destroyWindow(window);
+ }
+
+ @Test
+ public void test02WindowSimple() throws InterruptedException {
+ final GLCapabilities caps = new GLCapabilities(glp);
+ Assert.assertNotNull(caps);
+ final GLWindow window = createWindow(null, caps, width, height,
+ true /* onscreen */, true /*addGLEventListenerAfterVisible*/);
+ System.out.println("Created: "+window);
+ int state;
+ for(state=0; state*100<durationPerTest; state++) {
+ Thread.sleep(100);
+ }
+ System.out.println("duration: "+window.getTotalFPSDuration());
+ destroyWindow(window);
+ }
+
@Test
- public void testWindowNativeRecreate01aSimple() throws InterruptedException {
+ public void test10WindowNativeRecreateSimple() throws InterruptedException {
final GLCapabilities caps = new GLCapabilities(glp);
Assert.assertNotNull(caps);
final GLWindow window = createWindow(null, caps, width, height,
- true /* onscreen */, false /* undecorated */,
- false /*addGLEventListenerAfterVisible*/);
+ true /* onscreen */, false /*addGLEventListenerAfterVisible*/);
Assert.assertEquals(true,window.isNativeValid());
Assert.assertEquals(true,window.isVisible());
@@ -155,12 +184,11 @@ public class TestGLWindows01NEWT extends UITestCase {
}
@Test
- public void testWindowNativeRecreate01bSimple() throws InterruptedException {
+ public void test11WindowNativeRecreateSimple() throws InterruptedException {
final GLCapabilities caps = new GLCapabilities(glp);
Assert.assertNotNull(caps);
final GLWindow window = createWindow(null, caps, width, height,
- true /* onscreen */, false /* undecorated */,
- true /*addGLEventListenerAfterVisible*/);
+ true /* onscreen */, true /*addGLEventListenerAfterVisible*/);
Assert.assertEquals(true,window.isNativeValid());
Assert.assertEquals(true,window.isVisible());
@@ -184,44 +212,11 @@ public class TestGLWindows01NEWT extends UITestCase {
}
@Test
- public void testWindowDecor01aSimple() throws InterruptedException {
- final GLCapabilities caps = new GLCapabilities(glp);
- Assert.assertNotNull(caps);
- final GLWindow window = createWindow(null, caps, width, height,
- true /* onscreen */, false /* undecorated */,
- false /*addGLEventListenerAfterVisible*/);
- System.out.println("Created: "+window);
- int state;
- for(state=0; state*100<durationPerTest; state++) {
- Thread.sleep(100);
- }
- System.out.println("duration: "+window.getTotalFPSDuration());
- destroyWindow(window);
- }
-
- @Test
- public void testWindowDecor01bSimple() throws InterruptedException {
- final GLCapabilities caps = new GLCapabilities(glp);
- Assert.assertNotNull(caps);
- final GLWindow window = createWindow(null, caps, width, height,
- true /* onscreen */, false /* undecorated */,
- true /*addGLEventListenerAfterVisible*/);
- System.out.println("Created: "+window);
- int state;
- for(state=0; state*100<durationPerTest; state++) {
- Thread.sleep(100);
- }
- System.out.println("duration: "+window.getTotalFPSDuration());
- destroyWindow(window);
- }
-
- @Test
- public void testWindowDecor02DestroyWinTwiceA() throws InterruptedException {
+ public void test21WindowDestroyWinTwiceA() throws InterruptedException {
final GLCapabilities caps = new GLCapabilities(glp);
Assert.assertNotNull(caps);
final GLWindow window = createWindow(null, caps, width, height,
- true /* onscreen */, false /* undecorated */,
- false /*addGLEventListenerAfterVisible*/);
+ true /* onscreen */, false /*addGLEventListenerAfterVisible*/);
int state;
for(state=0; state*100<durationPerTest; state++) {
Thread.sleep(100);
@@ -231,7 +226,7 @@ public class TestGLWindows01NEWT extends UITestCase {
}
@Test
- public void testWindowDecor03TwoWinOneDisplay() throws InterruptedException {
+ public void test22WindowTwoWinOneDisplay() throws InterruptedException {
final GLCapabilities caps = new GLCapabilities(glp);
Assert.assertNotNull(caps);
@@ -241,13 +236,11 @@ public class TestGLWindows01NEWT extends UITestCase {
final Screen screen = NewtFactory.createScreen(display, 0); // screen 0
Assert.assertNotNull(screen);
final GLWindow window1 = createWindow(screen, caps, width, height,
- true /* onscreen */, false /* undecorated */,
- false /*addGLEventListenerAfterVisible*/);
+ true /* onscreen */, false /*addGLEventListenerAfterVisible*/);
Assert.assertNotNull(window1);
final GLWindow window2 = createWindow(screen, caps, width, height,
- true /* onscreen */, false /* undecorated */,
- false /*addGLEventListenerAfterVisible*/);
+ true /* onscreen */, false /*addGLEventListenerAfterVisible*/);
Assert.assertNotNull(window2);
Assert.assertEquals(1,Display.getActiveDisplayNumber());
@@ -281,7 +274,7 @@ public class TestGLWindows01NEWT extends UITestCase {
}
@Test
- public void testWindowDecor03TwoWinTwoDisplays() throws InterruptedException {
+ public void test23WindowTwoWinTwoDisplays() throws InterruptedException {
final GLCapabilities caps = new GLCapabilities(glp);
Assert.assertNotNull(caps);
@@ -294,15 +287,13 @@ public class TestGLWindows01NEWT extends UITestCase {
final Screen screen1 = NewtFactory.createScreen(display1, 0); // screen 0
Assert.assertNotNull(screen1);
final GLWindow window1 = createWindow(screen1, caps, width, height,
- true /* onscreen */, false /* undecorated */,
- false /*addGLEventListenerAfterVisible*/);
+ true /* onscreen */, false /*addGLEventListenerAfterVisible*/);
Assert.assertNotNull(window1);
final Screen screen2 = NewtFactory.createScreen(display2, 0); // screen 0
Assert.assertNotNull(screen2);
final GLWindow window2 = createWindow(screen2, caps, width, height,
- true /* onscreen */, false /* undecorated */,
- false /*addGLEventListenerAfterVisible*/);
+ true /* onscreen */, false /*addGLEventListenerAfterVisible*/);
Assert.assertNotNull(window2);
Assert.assertEquals(2,Display.getActiveDisplayNumber());
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestWindowAndPointerIconNEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestWindowAndPointerIconNEWT.java
index 0ef554ec2..d613f7d94 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestWindowAndPointerIconNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestWindowAndPointerIconNEWT.java
@@ -94,7 +94,7 @@ public class TestWindowAndPointerIconNEWT extends SingletonJunitCase {
final int idx = 0;
{
PointerIcon _pointerIcon = null;
- final IOUtil.ClassResources res = new IOUtil.ClassResources(glWindow.getClass(), new String[] { "arrow-red-alpha-64x64.png" } );
+ final IOUtil.ClassResources res = new IOUtil.ClassResources(new String[] { "arrow-red-alpha-64x64.png" }, glWindow.getClass().getClassLoader(), null);
try {
_pointerIcon = disp.createPointerIcon(res, 0, 0);
System.err.printf("Create PointerIcon #%02d: %s%n", idx, _pointerIcon.toString());
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestWindows02NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestWindows02NEWT.java
new file mode 100644
index 000000000..5cdb7e118
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestWindows02NEWT.java
@@ -0,0 +1,158 @@
+/**
+ * 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.newt;
+
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.FixMethodOrder;
+import org.junit.runners.MethodSorters;
+
+import com.jogamp.nativewindow.*;
+
+import com.jogamp.newt.*;
+import java.io.IOException;
+
+import com.jogamp.opengl.test.junit.util.MiscUtils;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class TestWindows02NEWT extends UITestCase {
+ static int width, height;
+ static long durationPerTest = 100; // ms
+
+ @BeforeClass
+ public static void initClass() {
+ NativeWindowFactory.initSingleton();
+ width = 800;
+ height = 600;
+ }
+
+ static Window createWindow(final Capabilities caps, final int x, final int y, final int width, final int height, final boolean onscreen, final boolean undecorated) throws InterruptedException {
+ final boolean userPos = x>=0 && y>=0 ; // user has specified a position
+
+ Assert.assertNotNull(caps);
+ caps.setOnscreen(onscreen);
+ // System.out.println("Requested: "+caps);
+
+ //
+ // Create native windowing resources .. X11/Win/OSX
+ //
+ final Window window = NewtFactory.createWindow(caps);
+ Assert.assertNotNull(window);
+ final Screen screen = window.getScreen();
+ final Display display = screen.getDisplay();
+ window.setUndecorated(onscreen && undecorated);
+ if(userPos) {
+ window.setPosition(x, y);
+ }
+ window.setSize(width, height);
+ Assert.assertEquals(false,window.isNativeValid());
+ Assert.assertEquals(false,window.isVisible());
+ window.setVisible(true);
+ // System.err.println("************* Created: "+window);
+
+ Assert.assertEquals(true,display.isNativeValid());
+ Assert.assertEquals(true,screen.isNativeValid());
+ Assert.assertEquals(true,window.isVisible());
+ Assert.assertEquals(true,window.isNativeValid());
+ Assert.assertEquals(width, window.getWidth());
+ Assert.assertEquals(height, window.getHeight());
+
+ final CapabilitiesImmutable chosenCapabilities = window.getGraphicsConfiguration().getChosenCapabilities();
+ Assert.assertNotNull(chosenCapabilities);
+ Assert.assertTrue(chosenCapabilities.getGreenBits()>=5);
+ Assert.assertTrue(chosenCapabilities.getBlueBits()>=5);
+ Assert.assertTrue(chosenCapabilities.getRedBits()>=5);
+ Assert.assertEquals(chosenCapabilities.isOnscreen(),onscreen);
+
+ return window;
+ }
+
+ static void destroyWindow(final Window window, final boolean last) {
+ if(null==window) {
+ return;
+ }
+ final Screen screen = window.getScreen();
+ final Display display = screen.getDisplay();
+ window.destroy();
+ // System.err.println("************* Destroyed: "+window);
+ if(last) {
+ Assert.assertEquals(false,screen.isNativeValid());
+ Assert.assertEquals(false,display.isNativeValid());
+ } else {
+ Assert.assertEquals(true,screen.isNativeValid());
+ Assert.assertEquals(true,display.isNativeValid());
+ }
+ Assert.assertEquals(false,window.isNativeValid());
+ Assert.assertEquals(false,window.isVisible());
+ }
+
+
+ @Test
+ public void test01WindowDefault() throws InterruptedException {
+ final Capabilities caps = new Capabilities();
+ Assert.assertNotNull(caps);
+
+ final Window window = createWindow(caps, -1, -1, width, height, true /* onscreen */, false /* undecorated */);
+ final CapabilitiesImmutable chosenCapabilities = window.getGraphicsConfiguration().getChosenCapabilities();
+ System.err.println("XXX: "+chosenCapabilities);
+ for(int state=0; state*100<durationPerTest; state++) {
+ Thread.sleep(100);
+ }
+ destroyWindow(window, true);
+ }
+
+ @Test
+ public void test02WindowDefault() throws InterruptedException {
+ final Capabilities caps = new Capabilities();
+ Assert.assertNotNull(caps);
+ caps.setBackgroundOpaque(false);
+
+ final Window window = createWindow(caps, -1, -1, width, height, true /* onscreen */, false /* undecorated */);
+ final CapabilitiesImmutable chosenCapabilities = window.getGraphicsConfiguration().getChosenCapabilities();
+ System.err.println("XXX: "+chosenCapabilities);
+ for(int state=0; state*100<durationPerTest; state++) {
+ Thread.sleep(100);
+ }
+ destroyWindow(window, true);
+ }
+
+ public static void main(final String args[]) throws IOException {
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-time")) {
+ durationPerTest = MiscUtils.atol(args[++i], durationPerTest);
+ }
+ }
+ System.out.println("durationPerTest: "+durationPerTest);
+ final String tstname = TestWindows02NEWT.class.getName();
+ org.junit.runner.JUnitCore.main(tstname);
+ }
+
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/event/BaseNewtEventModifiers.java b/src/test/com/jogamp/opengl/test/junit/newt/event/BaseNewtEventModifiers.java
index 39c6c9f4d..5f88d1c6f 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/event/BaseNewtEventModifiers.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/event/BaseNewtEventModifiers.java
@@ -40,6 +40,7 @@ import org.junit.FixMethodOrder;
import org.junit.Test ;
import org.junit.runners.MethodSorters;
+import com.jogamp.common.util.InterruptSource;
import com.jogamp.common.util.RunnableTask;
import com.jogamp.newt.event.MouseEvent;
import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
@@ -344,20 +345,17 @@ public abstract class BaseNewtEventModifiers extends UITestCase {
}
_testMouseListener.setModifierCheckEnabled( true ) ;
- Throwable throwable = null;
// final Object sync = new Object();
final RunnableTask rt = new RunnableTask( testAction, null, true, System.err );
try {
// synchronized(sync) {
- new Thread(rt, "Test-Thread").start();
+ new InterruptSource.Thread(null, rt, "Test-Thread").start();
int i=0;
- while( !rt.isExecuted() && null == throwable ) {
+ while( rt.isInQueue() ) {
System.err.println("WAIT-till-done: eventDispatch() #"+i++);
eventDispatch();
}
- if(null==throwable) {
- throwable = rt.getThrowable();
- }
+ final Throwable throwable = rt.getThrowable();
if(null!=throwable) {
throw new RuntimeException(throwable);
}
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/event/TestParentingFocus03KeyTraversalAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/event/TestParentingFocus03KeyTraversalAWT.java
index cade05478..283fc262a 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/event/TestParentingFocus03KeyTraversalAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/event/TestParentingFocus03KeyTraversalAWT.java
@@ -53,6 +53,7 @@ import com.jogamp.opengl.*;
import com.jogamp.opengl.util.Animator;
import com.jogamp.newt.*;
import com.jogamp.newt.opengl.*;
+import com.jogamp.newt.opengl.util.NEWTDemoListener;
import com.jogamp.newt.awt.NewtCanvasAWT;
import com.jogamp.newt.event.KeyAdapter;
import com.jogamp.newt.event.KeyEvent;
@@ -64,12 +65,19 @@ import jogamp.newt.driver.DriverClearFocus;
import com.jogamp.opengl.test.junit.util.*;
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.newt.parenting.NewtReparentingKeyAdapter;
/**
* Testing focus <i>key</i> traversal of an AWT component tree with {@link NewtCanvasAWT} attached.
* <p>
* {@link Frame} [ Button*, {@link NewtCanvasAWT} . {@link GLWindow} ]
* </p>
+ * <p>
+ * The demo code uses {@link NewtReparentingKeyAdapter} including {@link NEWTDemoListener} functionality.
+ * </p>
+ * <p>
+ * Manual invocation via main allows setting each tests's duration in milliseconds, e.g.{@code -duration 10000}, and many more, see {@link #main(String[])}
+ * </p>
*/
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class TestParentingFocus03KeyTraversalAWT extends UITestCase {
@@ -154,7 +162,7 @@ public class TestParentingFocus03KeyTraversalAWT extends UITestCase {
final GLEventListener demo1 = new GearsES2(1);
setDemoFields(demo1, glWindow1, false);
glWindow1.addGLEventListener(demo1);
- glWindow1.addKeyListener(new NewtAWTReparentingKeyAdapter(frame1, newtCanvasAWT1, glWindow1, null));
+ glWindow1.addKeyListener(new NewtAWTReparentingKeyAdapter(frame1, newtCanvasAWT1, glWindow1));
glWindow1.addKeyListener(new KeyAdapter() {
public void keyReleased(final KeyEvent e) {
if( !e.isPrintableKey() || e.isAutoRepeat() ) {
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 ae873eaf0..7e92c8438 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
@@ -1,5 +1,5 @@
/**
- * Copyright 2011 JogAmp Community. All rights reserved.
+ * Copyright 2011, 2019 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:
@@ -30,94 +30,37 @@ package com.jogamp.opengl.test.junit.newt.parenting;
import java.awt.Frame;
import com.jogamp.nativewindow.CapabilitiesImmutable;
+import com.jogamp.nativewindow.NativeWindow;
+import com.jogamp.nativewindow.NativeWindowHolder;
import com.jogamp.nativewindow.util.InsetsImmutable;
import com.jogamp.newt.Window;
-import com.jogamp.newt.awt.NewtCanvasAWT;
import com.jogamp.newt.event.KeyEvent;
import com.jogamp.newt.opengl.GLWindow;
-import com.jogamp.opengl.test.junit.util.NEWTDemoListener;
-import com.jogamp.opengl.test.junit.util.QuitAdapter;
+import com.jogamp.newt.opengl.util.NEWTDemoListener;
-public class NewtAWTReparentingKeyAdapter extends NEWTDemoListener {
+/**
+ * AWT specializing demo functionality of {@link NewtReparentingKeyAdapter}, includes {@link NEWTDemoListener}.
+ */
+public class NewtAWTReparentingKeyAdapter extends NewtReparentingKeyAdapter {
final Frame frame;
- final NewtCanvasAWT newtCanvasAWT;
- public NewtAWTReparentingKeyAdapter(final Frame frame, final NewtCanvasAWT newtCanvasAWT, final GLWindow glWindow, final QuitAdapter quitAdapter) {
- super(glWindow, quitAdapter, null);
+ public NewtAWTReparentingKeyAdapter(final Frame frame, final NativeWindowHolder winHolder, final GLWindow glWindow) {
+ super(winHolder, glWindow);
this.frame = frame;
- this.newtCanvasAWT = newtCanvasAWT;
- }
-
- public void keyPressed(final KeyEvent e) {
- if( e.isAutoRepeat() || e.isConsumed() ) {
- return;
- }
- if( 0 == e.getModifiers() ) { // all modifiers go to super class ..
- final int keySymbol = e.getKeySymbol();
- switch (keySymbol) {
- case KeyEvent.VK_L:
- e.setConsumed(true);
- final com.jogamp.nativewindow.util.Point p0 = newtCanvasAWT.getNativeWindow().getLocationOnScreen(null);
- final com.jogamp.nativewindow.util.Point p1 = glWindow.getLocationOnScreen(null);
- printlnState("[location]", "AWT "+p0+", NEWT "+p1);
- break;
- case KeyEvent.VK_R:
- e.setConsumed(true);
- quitAdapterOff();
- new Thread() {
- public void run() {
- final Thread t = glWindow.setExclusiveContextThread(null);
- if(glWindow.getParent()==null) {
- printlnState("[reparent pre - glWin to HOME]");
- glWindow.reparentWindow(newtCanvasAWT.getNativeWindow(), -1, -1, 0 /* hints */);
- } else {
- if( null != frame ) {
- final InsetsImmutable nInsets = glWindow.getInsets();
- final java.awt.Insets aInsets = frame.getInsets();
- int dx, dy;
- if( nInsets.getTotalHeight()==0 ) {
- dx = aInsets.left;
- dy = aInsets.top;
- } else {
- dx = nInsets.getLeftWidth();
- dy = nInsets.getTopHeight();
- }
- final int topLevelX = frame.getX()+frame.getWidth()+dx;
- final int topLevelY = frame.getY()+dy;
- printlnState("[reparent pre - glWin to TOP.1]", topLevelX+"/"+topLevelY+" - insets " + nInsets + ", " + aInsets);
- glWindow.reparentWindow(null, topLevelX, topLevelY, 0 /* hint */);
- } else {
- printlnState("[reparent pre - glWin to TOP.0]");
- glWindow.reparentWindow(null, -1, -1, 0 /* hints */);
- }
- }
- printlnState("[reparent post]");
- glWindow.requestFocus();
- glWindow.setExclusiveContextThread(t);
- quitAdapterOn();
- } }.start();
- break;
- }
- }
- super.keyPressed(e);
}
@Override
public void setTitle() {
- setTitle(frame, newtCanvasAWT, glWindow);
+ setTitle(frame, winHolder.getNativeWindow(), glWindow);
}
- public static void setTitle(final Frame frame, final NewtCanvasAWT glc, final Window win) {
+ public void setTitle(final Frame frame, final NativeWindow nw, final Window win) {
final CapabilitiesImmutable chosenCaps = win.getChosenCapabilities();
final CapabilitiesImmutable reqCaps = win.getRequestedCapabilities();
final CapabilitiesImmutable caps = null != chosenCaps ? chosenCaps : reqCaps;
final String capsA = caps.isBackgroundOpaque() ? "opaque" : "transl";
{
- final java.awt.Rectangle b = glc.getBounds();
- frame.setTitle("NewtCanvasAWT["+capsA+"], win: ["+b.x+"/"+b.y+" "+b.width+"x"+b.height+"], pix: "+glc.getNativeWindow().getSurfaceWidth()+"x"+glc.getNativeWindow().getSurfaceHeight());
+ frame.setTitle("Frame["+capsA+"], win: "+getNativeWinTitle(nw));
}
- final float[] sDPI = win.getPixelsPerMM(new float[2]);
- sDPI[0] *= 25.4f;
- sDPI[1] *= 25.4f;
- win.setTitle("GLWindow["+capsA+"], win: "+win.getBounds()+", pix: "+win.getSurfaceWidth()+"x"+win.getSurfaceHeight()+", sDPI "+sDPI[0]+" x "+sDPI[1]);
+ super.setTitle(nw, win);
}
}
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtJFXReparentingKeyAdapter.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtJFXReparentingKeyAdapter.java
new file mode 100644
index 000000000..3ed847ae3
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtJFXReparentingKeyAdapter.java
@@ -0,0 +1,102 @@
+/**
+ * Copyright 2019 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.parenting;
+
+import com.jogamp.nativewindow.CapabilitiesImmutable;
+import com.jogamp.nativewindow.NativeWindow;
+import com.jogamp.nativewindow.NativeWindowHolder;
+import com.jogamp.nativewindow.util.Insets;
+import com.jogamp.nativewindow.util.InsetsImmutable;
+import com.jogamp.newt.Window;
+import com.jogamp.newt.event.KeyEvent;
+import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.newt.opengl.util.NEWTDemoListener;
+
+import javafx.geometry.Bounds;
+
+/**
+ * JavaFX specializing demo functionality of {@link NewtReparentingKeyAdapter}, includes {@link NEWTDemoListener}.
+ */
+public class NewtJFXReparentingKeyAdapter extends NewtReparentingKeyAdapter {
+ final javafx.stage.Stage frame;
+
+ public NewtJFXReparentingKeyAdapter(final javafx.stage.Stage frame, final NativeWindowHolder winHolder, final GLWindow glWindow) {
+ super(winHolder, glWindow);
+ this.frame = frame;
+ }
+
+ @Override
+ public void keyPressed(final KeyEvent e) {
+ if( e.isAutoRepeat() || e.isConsumed() ) {
+ return;
+ }
+ if( 0 == e.getModifiers() ) { // all modifiers go to super class ..
+ final int keySymbol = e.getKeySymbol();
+ switch (keySymbol) {
+ case KeyEvent.VK_R:
+ e.setConsumed(true);
+ quitAdapterOff();
+ glWindow.invokeOnNewThread(null, false, new Runnable() {
+ public void run() {
+ final java.lang.Thread t = glWindow.setExclusiveContextThread(null);
+ if(glWindow.getParent()==null) {
+ printlnState("[reparent pre - glWin to HOME: child pos "+winHolder.getNativeWindow().getX()+"/"+winHolder.getNativeWindow().getY()+"]");
+ glWindow.reparentWindow(winHolder.getNativeWindow(), winHolder.getNativeWindow().getX(), winHolder.getNativeWindow().getY(), 0 /* hints */);
+ glWindow.setPosition(winHolder.getNativeWindow().getX(), winHolder.getNativeWindow().getY());
+ } else {
+ final com.jogamp.nativewindow.util.Point p0 = winHolder.getNativeWindow().getLocationOnScreen(null);
+ final com.jogamp.nativewindow.util.Point p1 = glWindow.getLocationOnScreen(null);
+ printlnState("[reparent pre - glWin to TOP.1] frame ", p0+", glWindow "+p1);
+ glWindow.reparentWindow(null, p1.getX(), p1.getY(), 0 /* hint */);
+ }
+ printlnState("[reparent post]");
+ glWindow.requestFocus();
+ glWindow.setExclusiveContextThread(t);
+ quitAdapterOn();
+ } } );
+ break;
+ }
+ }
+ super.keyPressed(e);
+ }
+
+ @Override
+ public void setTitle() {
+ setTitle(frame, winHolder.getNativeWindow(), glWindow);
+ }
+ public void setTitle(final javafx.stage.Stage frame, final NativeWindow nw, final Window win) {
+ final CapabilitiesImmutable chosenCaps = win.getChosenCapabilities();
+ final CapabilitiesImmutable reqCaps = win.getRequestedCapabilities();
+ final CapabilitiesImmutable caps = null != chosenCaps ? chosenCaps : reqCaps;
+ final String capsA = caps.isBackgroundOpaque() ? "opaque" : "transl";
+ {
+ frame.setTitle("Frame["+capsA+"], win: "+getNativeWinTitle(nw));
+ }
+ super.setTitle(nw, win);
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtReparentingKeyAdapter.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtReparentingKeyAdapter.java
new file mode 100644
index 000000000..339230d48
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtReparentingKeyAdapter.java
@@ -0,0 +1,111 @@
+/**
+ * Copyright 2011, 2019 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.parenting;
+
+import com.jogamp.nativewindow.CapabilitiesImmutable;
+import com.jogamp.nativewindow.NativeWindow;
+import com.jogamp.nativewindow.NativeWindowHolder;
+import com.jogamp.newt.Window;
+import com.jogamp.newt.event.KeyEvent;
+import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.newt.opengl.util.NEWTDemoListener;
+import com.jogamp.opengl.GLAnimatorControl;
+
+/**
+ * Extending demo functionality of {@link NEWTDemoListener}
+ * <ul>
+ * <li>L: Print parent and (child) {@link GLWindow} location</li>
+ * <li>R: Toggel parenting (top-level/child)</li>
+ * </ul>
+ */
+public class NewtReparentingKeyAdapter extends NEWTDemoListener {
+ final NativeWindowHolder winHolder;
+
+ public NewtReparentingKeyAdapter(final NativeWindowHolder winHolder, final GLWindow glWindow) {
+ super(glWindow, null);
+ this.winHolder = winHolder;
+ }
+
+ @Override
+ public void keyPressed(final KeyEvent e) {
+ if( e.isAutoRepeat() || e.isConsumed() ) {
+ return;
+ }
+ if( 0 == e.getModifiers() ) { // all modifiers go to super class ..
+ final int keySymbol = e.getKeySymbol();
+ switch (keySymbol) {
+ case KeyEvent.VK_L:
+ e.setConsumed(true);
+ final com.jogamp.nativewindow.util.Point p0 = winHolder.getNativeWindow().getLocationOnScreen(null);
+ final com.jogamp.nativewindow.util.Point p1 = glWindow.getLocationOnScreen(null);
+ printlnState("[location]", "Parent "+p0+", NEWT "+p1);
+ break;
+ case KeyEvent.VK_R:
+ e.setConsumed(true);
+ quitAdapterOff();
+ glWindow.invokeOnNewThread(null, false, new Runnable() {
+ public void run() {
+ final java.lang.Thread t = glWindow.setExclusiveContextThread(null);
+ if(glWindow.getParent()==null) {
+ printlnState("[reparent pre - glWin to HOME: child pos "+winHolder.getNativeWindow().getX()+"/"+winHolder.getNativeWindow().getY()+"]");
+ glWindow.reparentWindow(winHolder.getNativeWindow(), -1, -1, 0 /* hints */);
+ } else {
+ final com.jogamp.nativewindow.util.Point p0 = winHolder.getNativeWindow().getLocationOnScreen(null);
+ final com.jogamp.nativewindow.util.Point p1 = glWindow.getLocationOnScreen(null);
+ printlnState("[reparent pre - glWin to TOP.1] frame ", p0+", glWindow "+p1);
+ glWindow.reparentWindow(null, p1.getX(), p1.getY(), 0 /* hint */);
+ }
+ printlnState("[reparent post]");
+ glWindow.requestFocus();
+ glWindow.setExclusiveContextThread(t);
+ quitAdapterOn();
+ } } );
+ break;
+ }
+ }
+ super.keyPressed(e);
+ }
+
+ @Override
+ public void setTitle() {
+ setTitle(winHolder.getNativeWindow(), glWindow);
+ }
+ String getNativeWinTitle(final NativeWindow nw) {
+ return "["+nw.getX()+"/"+nw.getY()+" "+nw.getWidth()+"x"+nw.getHeight()+"], pix: "+nw.getSurfaceWidth()+"x"+nw.getSurfaceHeight();
+ }
+ public void setTitle(final NativeWindow nw, final Window win) {
+ final CapabilitiesImmutable chosenCaps = win.getChosenCapabilities();
+ final CapabilitiesImmutable reqCaps = win.getRequestedCapabilities();
+ final CapabilitiesImmutable caps = null != chosenCaps ? chosenCaps : reqCaps;
+ final String capsA = caps.isBackgroundOpaque() ? "opaque" : "transl";
+ final float[] sDPI = win.getPixelsPerMM(new float[2]);
+ sDPI[0] *= 25.4f;
+ sDPI[1] *= 25.4f;
+ win.setTitle("GLWindow["+capsA+"], win: "+win.getBounds()+", pix: "+win.getSurfaceWidth()+"x"+win.getSurfaceHeight()+", sDPI "+sDPI[0]+" x "+sDPI[1]);
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01NEWT.java
index 591ce5f4e..6e3c7c3e7 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01NEWT.java
@@ -51,7 +51,8 @@ import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
public class TestParenting01NEWT extends UITestCase {
static int width, height;
static long durationPerTest = 600;
- static long waitAbout10FramesAt30fps = 10*34; // 10 frames @ 30fps
+ static boolean manual = false;
+ static int loopVisibleToggle = 10;
static GLCapabilities glCaps;
@BeforeClass
@@ -61,6 +62,37 @@ public class TestParenting01NEWT extends UITestCase {
glCaps = new GLCapabilities(null);
}
+ private static void waitForFrames(final String waitFor, final int prefixIdx,
+ final GLWindow glWindow1, final GLWindow glWindow2,
+ final long TO, final boolean doAssert) {
+ final long t0 = System.currentTimeMillis();
+ int a, b;
+ long t1;
+ do {
+ try { Thread.sleep(16); } catch (final InterruptedException e) { }
+ if( null != glWindow1 ) {
+ a = glWindow1.getTotalFPSFrames();
+ } else {
+ a = -1;
+ }
+ if( null != glWindow2 ) {
+ b = glWindow2.getTotalFPSFrames();
+ } else {
+ b = -1;
+ }
+ t1 = System.currentTimeMillis();
+ } while ( ( 0 == a || 0 == b ) && TO > ( t1 - t0 ) );
+ System.err.println("Frames for "+waitFor+": A"+prefixIdx+": "+a+", B"+prefixIdx+": "+b);
+ if( doAssert ) {
+ if( null != glWindow1 ) {
+ Assert.assertTrue("No frames."+prefixIdx+" displayed on window1 during "+TO+"ms", 0 < a);
+ }
+ if( null != glWindow2 ) {
+ Assert.assertTrue("No frames."+prefixIdx+" displayed on window2 during "+TO+"ms", 0 < b);
+ }
+ }
+ }
+
@Test
public void test01CreateVisibleDestroy() throws InterruptedException {
Assert.assertEquals(0,Display.getActiveDisplayNumber());
@@ -109,44 +141,43 @@ public class TestParenting01NEWT extends UITestCase {
Assert.assertEquals(0,Display.getActiveDisplayNumber());
// visible test
+ for(int i=1; i<=loopVisibleToggle; i++) {
+ Assert.assertEquals(0, glWindow1.getTotalFPSFrames());
+ Assert.assertEquals(0, glWindow2.getTotalFPSFrames());
+ System.err.println("XXX VISIBLE."+i+" -> TRUE");
+ glWindow1.setVisible(true);
+ Assert.assertEquals(true, glWindow1.isVisible());
+ Assert.assertEquals(true, glWindow1.isNativeValid());
+ Assert.assertEquals(true, glWindow2.isVisible());
+ Assert.assertEquals(true, glWindow2.isNativeValid());
+ Assert.assertEquals(1,display.getReferenceCount());
+ Assert.assertEquals(true,display.isNativeValid());
+ Assert.assertNotNull(display.getEDTUtil());
+ Assert.assertEquals(true,display.getEDTUtil().isRunning());
+ Assert.assertEquals(2,screen.getReferenceCount());
+ Assert.assertEquals(true,screen.isNativeValid());
+ Assert.assertEquals(1,Display.getActiveDisplayNumber());
+ waitForFrames("window1.setVisible(true)", 1, glWindow1, glWindow2, 2000, true);
+
+ System.err.println("XXX VISIBLE."+i+" -> FALSE");
+ glWindow1.setVisible(false);
+ Assert.assertEquals(false, glWindow1.isVisible());
+ Assert.assertEquals(true, glWindow1.isNativeValid());
+ Assert.assertEquals(false, glWindow2.isVisible());
+ Assert.assertEquals(true, glWindow2.isNativeValid());
+
+ glWindow1.resetFPSCounter();
+ glWindow2.resetFPSCounter();
+ }
Assert.assertEquals(0, glWindow1.getTotalFPSFrames());
Assert.assertEquals(0, glWindow2.getTotalFPSFrames());
+ System.err.println("XXX VISIBLE.3 -> TRUE");
glWindow1.setVisible(true);
- System.err.println("Frames for setVisible(true): A1: "+glWindow1.getTotalFPSFrames()+", B1: "+glWindow2.getTotalFPSFrames());
- Assert.assertTrue(0 < glWindow1.getTotalFPSFrames());
- Assert.assertTrue(0 < glWindow2.getTotalFPSFrames());
-
- Assert.assertEquals(true, glWindow1.isVisible());
- Assert.assertEquals(true, glWindow1.isNativeValid());
- Assert.assertEquals(true, glWindow2.isVisible());
- Assert.assertEquals(true, glWindow2.isNativeValid());
- Assert.assertEquals(1,display.getReferenceCount());
- Assert.assertEquals(true,display.isNativeValid());
- Assert.assertNotNull(display.getEDTUtil());
- Assert.assertEquals(true,display.getEDTUtil().isRunning());
- Assert.assertEquals(2,screen.getReferenceCount());
- Assert.assertEquals(true,screen.isNativeValid());
- Assert.assertEquals(1,Display.getActiveDisplayNumber());
-
- glWindow1.setVisible(false);
- Assert.assertEquals(false, glWindow1.isVisible());
- Assert.assertEquals(true, glWindow1.isNativeValid());
- Assert.assertEquals(false, glWindow2.isVisible());
- Assert.assertEquals(true, glWindow2.isNativeValid());
-
- glWindow1.resetFPSCounter();
- glWindow2.resetFPSCounter();
- Assert.assertEquals(0, glWindow1.getTotalFPSFrames());
- Assert.assertEquals(0, glWindow2.getTotalFPSFrames());
- glWindow1.setVisible(true);
- System.err.println("Frames for setVisible(true): A2: "+glWindow1.getTotalFPSFrames()+", B2: "+glWindow2.getTotalFPSFrames());
- Assert.assertTrue(0 < glWindow1.getTotalFPSFrames());
- Assert.assertTrue(0 < glWindow2.getTotalFPSFrames());
-
Assert.assertEquals(true, glWindow1.isVisible());
Assert.assertEquals(true, glWindow1.isNativeValid());
Assert.assertEquals(true, glWindow2.isVisible());
Assert.assertEquals(true, glWindow2.isNativeValid());
+ waitForFrames("window1.setVisible(true)", 2, glWindow1, glWindow2, 2000, true);
glWindow1.resetFPSCounter();
glWindow2.resetFPSCounter();
@@ -165,9 +196,7 @@ public class TestParenting01NEWT extends UITestCase {
while(animator1.isAnimating() && animator1.getTotalFPSDuration()<durationPerTest) {
Thread.sleep(100);
}
- System.err.println("Frames for setVisible(true): A3: "+glWindow1.getTotalFPSFrames()+", B3: "+glWindow2.getTotalFPSFrames());
- Assert.assertTrue(0 < glWindow1.getTotalFPSFrames());
- Assert.assertTrue(0 < glWindow2.getTotalFPSFrames());
+ waitForFrames("animator.start()", 3, glWindow1, glWindow2, 2000, true);
Assert.assertEquals(true, animator1.pause());
Assert.assertEquals(false, animator1.isAnimating());
@@ -188,10 +217,7 @@ public class TestParenting01NEWT extends UITestCase {
Assert.assertEquals(true, animator2.isAnimating());
Assert.assertEquals(false, animator2.isPaused());
Assert.assertNotNull(animator2.getThread());
- Thread.sleep(waitAbout10FramesAt30fps);
- System.err.println("Frames for setVisible(true): A4: "+glWindow1.getTotalFPSFrames()+", B4: "+glWindow2.getTotalFPSFrames());
- Assert.assertTrue(0 < glWindow1.getTotalFPSFrames());
- Assert.assertTrue(0 < glWindow2.getTotalFPSFrames());
+ waitForFrames("animator.resume()", 4, glWindow1, glWindow2, 2000, true);
animator1.stop();
Assert.assertEquals(false, animator1.isAnimating());
@@ -243,15 +269,13 @@ public class TestParenting01NEWT extends UITestCase {
glWindow2.resetFPSCounter();
Assert.assertEquals(0, glWindow1.getTotalFPSFrames());
Assert.assertEquals(0, glWindow2.getTotalFPSFrames());
+ System.err.println("XXX VISIBLE.4 -> TRUE");
glWindow1.setVisible(true);
Assert.assertEquals(true, glWindow1.isVisible());
Assert.assertEquals(true, glWindow1.isNativeValid());
Assert.assertEquals(true, glWindow2.isVisible());
Assert.assertEquals(true, glWindow2.isNativeValid());
-
- System.err.println("Frames for setVisible(true): A3: "+glWindow1.getTotalFPSFrames()+", B3: "+glWindow2.getTotalFPSFrames());
- Assert.assertTrue(0 < glWindow1.getTotalFPSFrames());
- Assert.assertTrue(0 < glWindow2.getTotalFPSFrames());
+ waitForFrames("window1.setVisible(true) recreate", 5, glWindow1, glWindow2, 2000, true);
Assert.assertEquals(1,display.getReferenceCount());
Assert.assertEquals(true,display.isNativeValid());
@@ -287,11 +311,17 @@ public class TestParenting01NEWT extends UITestCase {
@Test
public void test02aReparentTop2WinReparentRecreate() throws InterruptedException {
+ if( manual ) {
+ return;
+ }
test02ReparentTop2WinImpl(true);
}
@Test
public void test02bReparentTop2WinReparentNative() throws InterruptedException {
+ if( manual ) {
+ return;
+ }
test02ReparentTop2WinImpl(false);
}
@@ -348,12 +378,10 @@ public class TestParenting01NEWT extends UITestCase {
Assert.assertEquals(true,screen1.isNativeValid());
Assert.assertEquals(1,Display.getActiveDisplayNumber());
Assert.assertEquals(true, glWindow1.isVisible());
- System.err.println("Frames for setVisible(true) A1: "+glWindow1.getTotalFPSFrames());
- Assert.assertTrue(0 < glWindow1.getTotalFPSFrames());
-
+ waitForFrames("window1.setVisible(true)", 1, glWindow1, null, 2000, true);
Assert.assertEquals(0, glWindow2.getTotalFPSFrames());
- glWindow2.setVisible(true);
+ glWindow2.setVisible(true);
Assert.assertEquals(1,display1.getReferenceCount());
Assert.assertEquals(true,display1.isNativeValid());
Assert.assertNotNull(display1.getEDTUtil());
@@ -362,8 +390,7 @@ public class TestParenting01NEWT extends UITestCase {
Assert.assertEquals(true,screen1.isNativeValid());
Assert.assertEquals(1,Display.getActiveDisplayNumber());
Assert.assertEquals(true, glWindow2.isVisible());
- System.err.println("Frames for setVisible(true) B1: "+glWindow2.getTotalFPSFrames());
- Assert.assertTrue(0 < glWindow1.getTotalFPSFrames());
+ waitForFrames("window2.setVisible(true)", 2, glWindow1, glWindow2, 2000, true);
final Animator animator1 = new Animator(glWindow1);
animator1.setUpdateFPSFrames(1, null);
@@ -405,9 +432,7 @@ public class TestParenting01NEWT extends UITestCase {
Assert.assertEquals(true, glWindow2.isVisible());
Assert.assertEquals(true, glWindow2.isNativeValid());
Assert.assertSame(glWindow1,glWindow2.getParent());
- Thread.sleep(20*16); // Wait for a few frames since counter could be reset - 20 frames at 60Hz
- System.err.println("Frames for reparentWindow(parent, "+reparentRecreate+"): "+reparentAction+", B2: "+glWindow2.getTotalFPSFrames());
- Assert.assertTrue(0 < glWindow2.getTotalFPSFrames());
+ waitForFrames("reparentWindow.child(parent, "+reparentRecreate+"), "+reparentAction, 10, glWindow1, glWindow2, 2000, true);
Assert.assertEquals(1,display1.getReferenceCount());
Assert.assertEquals(true,display1.isNativeValid());
@@ -448,9 +473,7 @@ public class TestParenting01NEWT extends UITestCase {
Assert.assertEquals(true, glWindow2.isVisible());
Assert.assertEquals(true, glWindow2.isNativeValid());
Assert.assertNull(glWindow2.getParent());
- Thread.sleep(20*16); // Wait for a few frames since counter could be reset - 20 frames at 60Hz
- System.err.println("Frames for reparentWindow(parent, "+reparentRecreate+"): "+reparentAction+", B3: "+glWindow2.getTotalFPSFrames());
- Assert.assertTrue(0 < glWindow2.getTotalFPSFrames());
+ waitForFrames("reparentWindow.top(parent, "+reparentRecreate+"), "+reparentAction, 11, glWindow1, glWindow2, 2000, true);
Assert.assertEquals(1,display1.getReferenceCount());
Assert.assertEquals(true,display1.isNativeValid());
@@ -523,11 +546,17 @@ public class TestParenting01NEWT extends UITestCase {
@Test
public void test03aReparentWin2TopReparentRecreate() throws InterruptedException {
+ if( manual ) {
+ return;
+ }
test03ReparentWin2TopImpl(true);
}
@Test
public void test03bReparentWin2TopReparentNative() throws InterruptedException {
+ if( manual ) {
+ return;
+ }
test03ReparentWin2TopImpl(false);
}
@@ -579,10 +608,6 @@ public class TestParenting01NEWT extends UITestCase {
Assert.assertEquals(0, glWindow1.getTotalFPSFrames());
Assert.assertEquals(0, glWindow2.getTotalFPSFrames());
glWindow1.setVisible(true);
- System.err.println("Frames for setVisible(): A1: "+glWindow1.getTotalFPSFrames()+", B1: "+glWindow2.getTotalFPSFrames());
- Assert.assertTrue(0 < glWindow2.getTotalFPSFrames());
- Assert.assertTrue(0 < glWindow1.getTotalFPSFrames());
-
Assert.assertEquals(1,display1.getReferenceCount());
Assert.assertEquals(true,display1.isNativeValid());
Assert.assertNotNull(display1.getEDTUtil());
@@ -592,6 +617,7 @@ public class TestParenting01NEWT extends UITestCase {
Assert.assertSame(glWindow1,glWindow2.getParent());
Assert.assertSame(screen1,glWindow2.getScreen());
Assert.assertEquals(1,Display.getActiveDisplayNumber());
+ waitForFrames("window1.setVisible(true)", 1, glWindow1, glWindow2, 2000, true);
final Animator animator1 = new Animator(glWindow1);
animator1.setUpdateFPSFrames(1, null);
@@ -630,9 +656,7 @@ public class TestParenting01NEWT extends UITestCase {
Assert.assertTrue(Window.ReparentOperation.ACTION_INVALID != reparentAction);
Assert.assertEquals(true, glWindow2.isVisible());
Assert.assertEquals(true, glWindow2.isNativeValid());
- Thread.sleep(20*16); // Wait for a few frames since counter could be reset - 20 frames at 60Hz
- System.err.println("Frames for reparentWindow(parent, "+reparentRecreate+"): "+reparentAction+", B2: "+glWindow2.getTotalFPSFrames());
- Assert.assertTrue(0 < glWindow2.getTotalFPSFrames());
+ waitForFrames("reparentWindow.top(parent, "+reparentRecreate+"), "+reparentAction, 10, glWindow1, glWindow2, 2000, true);
Assert.assertNull(glWindow2.getParent());
Assert.assertSame(screen1,glWindow2.getScreen());
@@ -665,9 +689,7 @@ public class TestParenting01NEWT extends UITestCase {
Assert.assertTrue(Window.ReparentOperation.ACTION_INVALID != reparentAction);
Assert.assertEquals(true, glWindow2.isVisible());
Assert.assertEquals(true, glWindow2.isNativeValid());
- Thread.sleep(20*16); // Wait for a few frames since counter could be reset - 20 frames at 60Hz
- System.err.println("Frames for reparentWindow(parent, "+reparentRecreate+"): "+reparentAction+", B3 "+glWindow2.getTotalFPSFrames());
- Assert.assertTrue(0 < glWindow2.getTotalFPSFrames());
+ waitForFrames("reparentWindow.child(parent, "+reparentRecreate+"), "+reparentAction, 11, glWindow1, glWindow2, 2000, true);
Assert.assertSame(glWindow1,glWindow2.getParent());
Assert.assertSame(screen1,glWindow2.getScreen());
@@ -759,6 +781,10 @@ public class TestParenting01NEWT extends UITestCase {
for(int i=0; i<args.length; i++) {
if(args[i].equals("-time")) {
durationPerTest = atoi(args[++i]);
+ } else if(args[i].equals("-loopvt")) {
+ loopVisibleToggle = atoi(args[++i]);
+ } else if(args[i].equals("-manual")) {
+ manual = true;
} else if(args[i].equals("-asMain")) {
asMain = true;
}
@@ -768,8 +794,8 @@ public class TestParenting01NEWT extends UITestCase {
try {
TestParenting01NEWT.initClass();
final TestParenting01NEWT m = new TestParenting01NEWT();
- m.test02aReparentTop2WinReparentRecreate();
m.test01CreateVisibleDestroy();
+ m.test02aReparentTop2WinReparentRecreate();
} catch (final Throwable t ) {
t.printStackTrace();
}
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01cSwingAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01cSwingAWT.java
index b53da38d7..4af752eb4 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01cSwingAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01cSwingAWT.java
@@ -47,6 +47,7 @@ import javax.swing.WindowConstants;
import com.jogamp.opengl.*;
import com.jogamp.opengl.util.Animator;
+import com.jogamp.common.util.InterruptSource;
import com.jogamp.newt.*;
import com.jogamp.newt.opengl.*;
import com.jogamp.newt.awt.NewtCanvasAWT;
@@ -140,7 +141,7 @@ public class TestParenting01cSwingAWT extends UITestCase {
animator1.start();
final GLDisturbanceAction disturbanceAction = new GLDisturbanceAction(glWindow1);
- new Thread(disturbanceAction).start();
+ new InterruptSource.Thread(null, disturbanceAction).start();
disturbanceAction.waitUntilRunning();
final NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow1);
@@ -274,7 +275,7 @@ public class TestParenting01cSwingAWT extends UITestCase {
animator1.start();
final GLDisturbanceAction disturbanceAction = new GLDisturbanceAction(glWindow1);
- new Thread(disturbanceAction).start();
+ new InterruptSource.Thread(null, disturbanceAction).start();
disturbanceAction.waitUntilRunning();
final NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow1);
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting02NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting02NEWT.java
index 6a7066820..b56010bc4 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting02NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting02NEWT.java
@@ -37,7 +37,8 @@ import org.junit.runners.MethodSorters;
import com.jogamp.opengl.*;
import com.jogamp.nativewindow.*;
-
+import com.jogamp.nativewindow.util.Point;
+import com.jogamp.nativewindow.util.PointImmutable;
import com.jogamp.newt.*;
import com.jogamp.newt.event.*;
import com.jogamp.newt.opengl.*;
@@ -150,6 +151,7 @@ public class TestParenting02NEWT extends UITestCase {
glWindow1.addGLEventListener(demo1);
glWindow2.addGLEventListener(demo2);
+ glWindow2.addWindowListener(windowMoveDetection);
boolean shouldQuit = false;
long duration = durationPerTest;
@@ -163,8 +165,19 @@ public class TestParenting02NEWT extends UITestCase {
x += 1;
y += 1;
// glWindow1.setPosition(x,y);
- glWindow2.setPosition(glWindow1.getWidth()/2,glWindow1.getHeight()/2-y);
- Thread.sleep(step);
+ final PointImmutable expPos = new Point(glWindow1.getWidth()/2, glWindow1.getHeight()/2-y);
+ glWindow2.setPosition(expPos.getX(), expPos.getY());
+ {
+ int waitCount=0;
+ do {
+ Thread.sleep(step);
+ waitCount++;
+ } while( !windowMoved && waitCount < 10);
+ final boolean didWindowMove = windowMoved;
+ windowMoved = false;
+ final PointImmutable hasPos = new Point(glWindow2.getX(), glWindow2.getY());
+ System.err.println("Moved: exp "+expPos+", has "+hasPos+", equals "+expPos.equals(hasPos)+", didWindowMove "+didWindowMove+", waitCount "+waitCount);
+ }
while( null != ( event = eventFifo.get() ) ) {
final Window source = (Window) event.getSource();
@@ -186,6 +199,13 @@ public class TestParenting02NEWT extends UITestCase {
destroyWindow(null, null, window2, glWindow2);
destroyWindow(display, screen, window1, glWindow1);
}
+ volatile boolean windowMoved = false;
+ final WindowListener windowMoveDetection = new WindowAdapter() {
+ @Override
+ public void windowMoved(final WindowEvent e) {
+ windowMoved = true;
+ }
+ };
public static void setDemoFields(final GLEventListener demo, final Window window, final GLWindow glWindow, final boolean debug) {
Assert.assertNotNull(demo);
@@ -214,17 +234,7 @@ public class TestParenting02NEWT extends UITestCase {
}
}
final String tstname = TestParenting02NEWT.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" } );
+ org.junit.runner.JUnitCore.main(tstname);
}
}
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting03AWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting03AWT.java
index 723b84081..005839cec 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting03AWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting03AWT.java
@@ -47,6 +47,7 @@ import com.jogamp.opengl.*;
import com.jogamp.opengl.util.Animator;
import com.jogamp.newt.*;
import com.jogamp.newt.opengl.*;
+import com.jogamp.newt.opengl.util.NEWTDemoListener;
import com.jogamp.newt.awt.NewtCanvasAWT;
import java.io.IOException;
@@ -54,6 +55,14 @@ import java.io.IOException;
import com.jogamp.opengl.test.junit.util.*;
import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+/**
+ * <p>
+ * The demo code uses {@link NewtReparentingKeyAdapter} including {@link NEWTDemoListener} functionality.
+ * </p>
+ * <p>
+ * Manual invocation via main allows setting each tests's duration in milliseconds, e.g.{@code -duration 10000}, and many more, see {@link #main(String[])}
+ * </p>
+ */
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class TestParenting03AWT extends UITestCase {
static Dimension glSize, fSize;
@@ -88,7 +97,7 @@ public class TestParenting03AWT extends UITestCase {
final GLEventListener demo1 = new GearsES2(1);
setDemoFields(demo1, glWindow1, false);
glWindow1.addGLEventListener(demo1);
- glWindow1.addKeyListener(new NewtAWTReparentingKeyAdapter(frame1, newtCanvasAWT1, glWindow1, null));
+ glWindow1.addKeyListener(new NewtAWTReparentingKeyAdapter(frame1, newtCanvasAWT1, glWindow1));
final GLAnimatorControl animator1 = new Animator(glWindow1);
animator1.start();
@@ -104,7 +113,7 @@ public class TestParenting03AWT extends UITestCase {
final GLEventListener demo2 = new GearsES2(1);
setDemoFields(demo2, glWindow2, false);
glWindow2.addGLEventListener(demo2);
- glWindow2.addKeyListener(new NewtAWTReparentingKeyAdapter(frame1, newtCanvasAWT2, glWindow2, null));
+ glWindow2.addKeyListener(new NewtAWTReparentingKeyAdapter(frame1, newtCanvasAWT2, glWindow2));
animator2 = new Animator(glWindow2);
animator2.start();
}
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 60f2f962c..bf656bb4d 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/MiscUtils.java
+++ b/src/test/com/jogamp/opengl/test/junit/util/MiscUtils.java
@@ -42,6 +42,7 @@ import java.util.List;
import com.jogamp.opengl.GLContext;
import com.jogamp.common.os.Platform;
+import com.jogamp.common.util.InterruptSource;
public class MiscUtils {
public static boolean atob(final String str, final boolean def) {
@@ -160,7 +161,7 @@ public class MiscUtils {
return false;
}
- public static class StreamDump extends Thread {
+ public static class StreamDump extends InterruptSource.Thread {
final InputStream is;
final StringBuilder outString;
final OutputStream outStream;