diff options
Diffstat (limited to 'src')
22 files changed, 667 insertions, 287 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/util/Animator.java b/src/jogl/classes/com/jogamp/opengl/util/Animator.java index fed55aeef..4fbd0e478 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/Animator.java +++ b/src/jogl/classes/com/jogamp/opengl/util/Animator.java @@ -41,7 +41,6 @@ package com.jogamp.opengl.util; import javax.media.opengl.GLAutoDrawable; -import javax.media.opengl.GLException; /** <P> An Animator can be attached to one or more {@link @@ -125,11 +124,15 @@ public class Animator extends AnimatorBase { } class MainLoop implements Runnable { + public String toString() { + return "[started "+isStartedImpl()+", animating "+isAnimatingImpl()+", paused "+isPausedImpl()+", frames "+getTotalFrames()+", drawable "+drawables.size()+"]"; + } + public void run() { try { synchronized (Animator.this) { if(DEBUG) { - System.err.println("Animator started: "+Thread.currentThread()); + System.err.println("Animator start:" + Thread.currentThread() + ": " + toString()); } startTime = System.currentTimeMillis(); @@ -147,7 +150,7 @@ public class Animator extends AnimatorBase { while (!stopIssued && (pauseIssued || drawablesEmpty)) { boolean wasPaused = pauseIssued; if (DEBUG) { - System.err.println("Animator paused: " + Thread.currentThread()); + System.err.println("Animator pause:" + Thread.currentThread() + ": " + toString()); } setIsAnimatingSynced(false); // barrier Animator.this.notifyAll(); @@ -162,7 +165,7 @@ public class Animator extends AnimatorBase { curTime = startTime; totalFrames = 0; if (DEBUG) { - System.err.println("Animator resume: " + Thread.currentThread()); + System.err.println("Animator resume:" + Thread.currentThread() + ": " + toString()); } } } @@ -184,7 +187,7 @@ public class Animator extends AnimatorBase { } finally { synchronized (Animator.this) { if(DEBUG) { - System.err.println("Animator stopped: "+Thread.currentThread()); + System.err.println("Animator stop " + Thread.currentThread() + ": " + toString()); } stopIssued = false; pauseIssued = false; diff --git a/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java b/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java index 4a8579767..01c2ea664 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java +++ b/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java @@ -111,7 +111,7 @@ public abstract class AnimatorBase implements GLAnimatorControl { public synchronized void remove(GLAutoDrawable drawable) { if(DEBUG) { - System.err.println("Animator remove: "+drawable.hashCode()+" - "+Thread.currentThread()); + System.err.println("Animator remove: "+drawable.hashCode()+" - "+Thread.currentThread() + ": "+toString()); } boolean paused = pause(); diff --git a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java index 395ee3704..c433e8b68 100644 --- a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java +++ b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java @@ -52,6 +52,7 @@ import com.jogamp.common.util.ReflectionUtil; import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.NativeSurface; import javax.media.nativewindow.NativeWindowFactory; +import javax.media.nativewindow.ProxySurface; /** <P> Provides a virtual machine- and operating system-independent mechanism for creating {@link GLDrawable}s. </P> @@ -425,6 +426,23 @@ public abstract class GLDrawableFactory { int width, int height); /** + * Highly experimental API entry, allowing developer of new windowing system bindings + * to leverage the native window handle to produce a NativeSurface implementation (ProxySurface), having the required GLCapabilities.<br> + * Such surface can be used to instantiate a GLDrawable and hence test your new binding w/o the + * costs of providing a full set of abstraction like the AWT GLCanvas or even the native NEWT bindings. + * + * @param device the platform's target device, shall not be <code>null</code> + * @param windowHandle the native window handle + * @param caps the requested GLCapabilties + * @param chooser the custom chooser, may be null for default + * @return The proxy surface wrapping the windowHandle on the device + */ + public abstract ProxySurface createProxySurface(AbstractGraphicsDevice device, + long windowHandle, + GLCapabilitiesImmutable caps, + GLCapabilitiesChooser chooser); + + /** * Returns true if it is possible to create a GLPbuffer. Some older * graphics cards do not have this capability. * diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java b/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java index 585590170..e04ced6fa 100644 --- a/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java +++ b/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java @@ -232,6 +232,21 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { GLCapabilitiesChooser chooser, int width, int height); + public ProxySurface createProxySurface(AbstractGraphicsDevice device, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser) { + if(null == device) { + throw new GLException("No shared device for requested: "+device); + } + + device.lock(); + try { + return createProxySurfaceImpl(device, windowHandle, capsRequested, chooser); + } finally { + device.unlock(); + } + } + + protected abstract ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice device, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser); + //--------------------------------------------------------------------------- // // External GLDrawable construction diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java index f81e5a70e..b6599de1b 100644 --- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java +++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java @@ -225,6 +225,11 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { return ns; } + protected ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice device, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser) { + WrappedSurface ns = new WrappedSurface(EGLGraphicsConfigurationFactory.createOffscreenGraphicsConfiguration(device, capsRequested, capsRequested, chooser), windowHandle); + return ns; + } + protected GLContext createExternalGLContextImpl() { AbstractGraphicsScreen absScreen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_EGL); return new EGLExternalContext(absScreen); diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java index fa0a0b6ed..6ce793490 100644 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java +++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java @@ -173,6 +173,12 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl { return ns; } + protected ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice device, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser) { + AbstractGraphicsScreen screen = new DefaultGraphicsScreen(device, 0); + WrappedSurface ns = new WrappedSurface(MacOSXCGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsRequested, capsRequested, chooser, screen, true), windowHandle); + return ns; + } + protected GLContext createExternalGLContextImpl() { return MacOSXExternalCGLContext.create(this, null); } diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLContext.java index c839c87f1..55d3a0853 100644 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLContext.java +++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLContext.java @@ -39,11 +39,8 @@ package jogamp.opengl.macosx.cgl; -import java.util.*; -import javax.media.nativewindow.*; import javax.media.opengl.*; -import jogamp.opengl.*; public class MacOSXOnscreenCGLContext extends MacOSXCGLContext { @@ -52,21 +49,25 @@ public class MacOSXOnscreenCGLContext extends MacOSXCGLContext { super(drawable, shareWith); } + @Override protected void makeCurrentImpl(boolean newCreated) throws GLException { super.makeCurrentImpl(newCreated); CGL.updateContext(contextHandle); } + @Override protected void releaseImpl() throws GLException { super.releaseImpl(); } + @Override protected void swapBuffers() { if (!CGL.flushBuffer(contextHandle)) { throw new GLException("Error swapping buffers"); } } + @Override protected void update() throws GLException { if (contextHandle == 0) { throw new GLException("Context not created"); diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLDrawable.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLDrawable.java index bd311217d..513dc3a04 100644 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLDrawable.java +++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLDrawable.java @@ -41,12 +41,10 @@ package jogamp.opengl.macosx.cgl; import java.lang.ref.WeakReference; -import java.security.*; import java.util.*; import javax.media.nativewindow.*; import javax.media.opengl.*; -import jogamp.opengl.*; public class MacOSXOnscreenCGLDrawable extends MacOSXCGLDrawable { private List/*<WeakReference<GLContext>>*/ createdContexts = diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java index 5afbb9218..3cbef2569 100644 --- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java +++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java @@ -65,6 +65,7 @@ import javax.media.opengl.GLProfile; import com.jogamp.common.JogampRuntimeException; import com.jogamp.common.nio.PointerBuffer; import com.jogamp.common.util.ReflectionUtil; +import javax.media.opengl.GLCapabilities; import jogamp.nativewindow.WrappedSurface; import jogamp.nativewindow.windows.GDI; import jogamp.nativewindow.windows.GDISurface; @@ -445,6 +446,15 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { return ns; } + protected final ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice adevice, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser) { + // FIXME device/windowHandle -> screen ?! + WindowsGraphicsDevice device = (WindowsGraphicsDevice) adevice; + AbstractGraphicsScreen screen = new DefaultGraphicsScreen(device, 0); + WindowsWGLGraphicsConfiguration cfg = WindowsWGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsRequested, capsRequested, chooser, screen); + GDISurface ns = new GDISurface(cfg, windowHandle); + return ns; + } + protected final GLContext createExternalGLContextImpl() { return WindowsExternalWGLContext.create(this, null); } diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java index 755c078b9..8203a440c 100644 --- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java +++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java @@ -177,6 +177,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { try { String glXVendorName = GLXUtil.getVendorName(sharedDevice.getHandle()); X11GraphicsScreen sharedScreen = new X11GraphicsScreen(sharedDevice, 0); + if (null == sharedScreen) { throw new GLException("Couldn't create shared screen for device: "+sharedDevice+", idx 0"); } @@ -407,6 +408,15 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { return ns; } + protected final ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice adevice, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser) { + // FIXME device/windowHandle -> screen ?! + X11GraphicsDevice device = (X11GraphicsDevice) adevice; + X11GraphicsScreen screen = new X11GraphicsScreen(device, 0); + X11GLXGraphicsConfiguration cfg = X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsRequested, capsRequested, chooser, screen); + WrappedSurface ns = new WrappedSurface(cfg, windowHandle); + return ns; + } + protected final GLContext createExternalGLContextImpl() { return X11ExternalGLXContext.create(this, null); } diff --git a/src/nativewindow/classes/jogamp/nativewindow/swt/SWTAccessor.java b/src/nativewindow/classes/jogamp/nativewindow/swt/SWTAccessor.java index 7f8bccd56..d1f5efc88 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/swt/SWTAccessor.java +++ b/src/nativewindow/classes/jogamp/nativewindow/swt/SWTAccessor.java @@ -27,6 +27,7 @@ */ package jogamp.nativewindow.swt; +import com.jogamp.common.os.Platform; import java.lang.reflect.Field; import java.lang.reflect.Method; @@ -34,19 +35,65 @@ import org.eclipse.swt.graphics.GCData; import org.eclipse.swt.widgets.Control; import javax.media.nativewindow.NativeWindowException; +import javax.media.nativewindow.AbstractGraphicsDevice; +import javax.media.nativewindow.NativeWindowFactory; +import javax.media.nativewindow.windows.WindowsGraphicsDevice; +import javax.media.nativewindow.x11.X11GraphicsDevice; import com.jogamp.common.util.ReflectionUtil; +import javax.media.nativewindow.macosx.MacOSXGraphicsDevice; public class SWTAccessor { + static final Field swt_control_handle; + static final boolean swt_uses_long_handles; + + // X11/GTK, Windows/GDI, .. + static final String str_handle = "handle"; + + // OSX/Cocoa + static final String str_view = "view"; // OSX + static final String str_id = "id"; // OSX + // static final String str_NSView = "org.eclipse.swt.internal.cocoa.NSView"; + static final Method swt_control_internal_new_GC; static final Method swt_control_internal_dispose_GC; - static final boolean swt_uses_long_handles; - static final Field swt_control_handle; - static final String str_internal_new_GC = "internal_new_GC"; static final String str_internal_dispose_GC = "internal_dispose_GC"; - static final String str_handle = "handle"; + static final String str_OS_gtk_class = "org.eclipse.swt.internal.gtk.OS"; + static final Class OS_gtk_class; + static final Method OS_gtk_widget_realize; + static final Method OS_gtk_widget_unrealize; + static final Method OS_GTK_WIDGET_WINDOW; + static final Method OS_gdk_x11_drawable_get_xdisplay; + static final Method OS_gdk_x11_drawable_get_xid; + static final String str_gtk_widget_realize = "gtk_widget_realize"; + static final String str_gtk_widget_unrealize = "gtk_widget_unrealize"; + static final String str_GTK_WIDGET_WINDOW = "GTK_WIDGET_WINDOW"; + static final String str_gdk_x11_drawable_get_xdisplay = "gdk_x11_drawable_get_xdisplay"; + static final String str_gdk_x11_drawable_get_xid = "gdk_x11_drawable_get_xid"; + static { + Field f = null; + + if(NativeWindowFactory.TYPE_MACOSX != NativeWindowFactory.getNativeWindowType(false) ) { + try { + f = Control.class.getField(str_handle); + } catch (Exception ex) { + throw new NativeWindowException(ex); + } + } + swt_control_handle = f; // maybe null ! + + boolean ulh; + if (null != swt_control_handle) { + ulh = swt_control_handle.getGenericType().toString().equals(long.class.toString()); + } else { + ulh = Platform.is64Bit(); + } + swt_uses_long_handles = ulh; + // System.err.println("SWT long handles: " + swt_uses_long_handles); + // System.err.println("Platform 64bit: "+Platform.is64Bit()); + Method m=null; try { m = ReflectionUtil.getMethod(Control.class, str_internal_new_GC, new Class[] { GCData.class }); @@ -54,37 +101,76 @@ public class SWTAccessor { throw new NativeWindowException(ex); } swt_control_internal_new_GC = m; - - boolean swt_uses_long_tmp = false; + try { - m = Control.class.getDeclaredMethod(str_internal_dispose_GC, new Class[] { int.class, GCData.class }); - swt_uses_long_tmp = false; - } catch (NoSuchMethodException ex1) { - try { - m = Control.class.getDeclaredMethod(str_internal_dispose_GC, new Class[] { long.class, GCData.class }); - swt_uses_long_tmp = true; - } catch (NoSuchMethodException ex2) { - throw new NativeWindowException("Neither 'int' nor 'long' variant of '"+str_internal_dispose_GC+"' exist", ex2); + if(swt_uses_long_handles) { + m = Control.class.getDeclaredMethod(str_internal_dispose_GC, new Class[] { long.class, GCData.class }); + } else { + m = Control.class.getDeclaredMethod(str_internal_dispose_GC, new Class[] { int.class, GCData.class }); } + } catch (NoSuchMethodException ex) { + throw new NativeWindowException(ex); } - swt_uses_long_handles = swt_uses_long_tmp; swt_control_internal_dispose_GC = m; - Field f = null; - try { - f = Control.class.getField(str_handle); - } catch (Exception ex) { - throw new NativeWindowException(ex); + Class c=null; + Method m1=null, m2=null, m3=null, m4=null, m5=null; + Class handleType = swt_uses_long_handles ? long.class : int.class ; + if( NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(false) ) { + try { + c = ReflectionUtil.getClass(str_OS_gtk_class, false, SWTAccessor.class.getClassLoader()); + m1 = c.getDeclaredMethod(str_gtk_widget_realize, handleType); + m2 = c.getDeclaredMethod(str_gtk_widget_unrealize, handleType); + m3 = c.getDeclaredMethod(str_GTK_WIDGET_WINDOW, handleType); + m4 = c.getDeclaredMethod(str_gdk_x11_drawable_get_xdisplay, handleType); + m5 = c.getDeclaredMethod(str_gdk_x11_drawable_get_xid, handleType); + } catch (Exception ex) { throw new NativeWindowException(ex); } } - swt_control_handle = f; + OS_gtk_class = c; + OS_gtk_widget_realize = m1; + OS_gtk_widget_unrealize = m2; + OS_GTK_WIDGET_WINDOW = m3; + OS_gdk_x11_drawable_get_xdisplay = m4; + OS_gdk_x11_drawable_get_xid = m5; } + static Object getIntOrLong(long arg) { + if(swt_uses_long_handles) { + return new Long(arg); + } + return new Integer((int) arg); + } + + static void callStaticMethodL2V(Method m, long arg) { + ReflectionUtil.callMethod(null, m, new Object[] { getIntOrLong(arg) }); + } + + static long callStaticMethodL2L(Method m, long arg) { + Object o = ReflectionUtil.callMethod(null, m, new Object[] { getIntOrLong(arg) }); + if(o instanceof Number) { + return ((Number)o).longValue(); + } else { + throw new InternalError("SWT method "+m.getName()+" didn't return int or long but "+o.getClass()); + } + } + public static boolean isUsingLongHandles() { return swt_uses_long_handles; } - + public static long getHandle(Control swtControl) { long h = 0; + if(NativeWindowFactory.TYPE_MACOSX == NativeWindowFactory.getNativeWindowType(false) ) { + try { + Field fView = Control.class.getField(str_view); + Object view = fView.get(swtControl); + Field fId = view.getClass().getField(str_id); + return fId.getLong(view); + } catch (Exception ex) { + throw new NativeWindowException(ex); + } + } + try { h = swt_control_handle.getLong(swtControl); } catch (Exception ex) { @@ -92,6 +178,47 @@ public class SWTAccessor { } return h; } + + public static void setRealized(Control swtControl, boolean realize) { + long handle = getHandle(swtControl); + + if(null != OS_gtk_class) { + if(realize) { + callStaticMethodL2V(OS_gtk_widget_realize, handle); + } else { + callStaticMethodL2V(OS_gtk_widget_unrealize, handle); + } + } + } + + public static AbstractGraphicsDevice getDevice(Control swtControl) { + long handle = getHandle(swtControl); + if( null != OS_gtk_class ) { + long widgedHandle = callStaticMethodL2L(OS_GTK_WIDGET_WINDOW, handle); + long displayHandle = callStaticMethodL2L(OS_gdk_x11_drawable_get_xdisplay, widgedHandle); + return new X11GraphicsDevice(displayHandle, AbstractGraphicsDevice.DEFAULT_UNIT); + } + if( NativeWindowFactory.TYPE_WINDOWS == NativeWindowFactory.getNativeWindowType(false) ) { + return new WindowsGraphicsDevice(AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT); + } + if( NativeWindowFactory.TYPE_MACOSX == NativeWindowFactory.getNativeWindowType(false) ) { + return new MacOSXGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT); + } + throw new UnsupportedOperationException("n/a for this windowing system: "+NativeWindowFactory.getNativeWindowType(false)); + } + + public static long getWindowHandle(Control swtControl) { + long handle = getHandle(swtControl); + if( null != OS_gtk_class ) { + long widgedHandle = callStaticMethodL2L(OS_GTK_WIDGET_WINDOW, handle); + return callStaticMethodL2L(OS_gdk_x11_drawable_get_xid, widgedHandle); + } + if( NativeWindowFactory.TYPE_WINDOWS == NativeWindowFactory.getNativeWindowType(false) || + NativeWindowFactory.TYPE_MACOSX == NativeWindowFactory.getNativeWindowType(false) ) { + return handle; + } + throw new UnsupportedOperationException("n/a for this windowing system: "+NativeWindowFactory.getNativeWindowType(false)); + } public static long newGC(Control swtControl, GCData gcData) { Object o = ReflectionUtil.callMethod(swtControl, swt_control_internal_new_GC, new Object[] { gcData }); @@ -109,4 +236,5 @@ public class SWTAccessor { ReflectionUtil.callMethod(swtControl, swt_control_internal_dispose_GC, new Object[] { new Integer((int)gc), gcData }); } } + } diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java index 052a9934e..26da46319 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java +++ b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java @@ -361,11 +361,11 @@ public class X11Util { * @return If name is null, it returns the previous queried NULL display name, * otherwise the name. */ public static String validateDisplayName(String name) { - return ( null == name ) ? getNullDisplayName() : name ; + return ( null == name || AbstractGraphicsDevice.DEFAULT_CONNECTION.equals(name) ) ? getNullDisplayName() : name ; } public static String validateDisplayName(String name, long handle) { - if(null==name && 0!=handle) { + if( ( null==name || AbstractGraphicsDevice.DEFAULT_CONNECTION.equals(name) ) && 0!=handle) { name = XDisplayString(handle); } return validateDisplayName(name); diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java index 5eec746a8..efbd9594b 100644 --- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java +++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java @@ -304,8 +304,8 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer { // Hide methods here .. protected class GLLifecycleHook implements WindowImpl.LifecycleHook { - class DisposeAction implements Runnable { - public void run() { + private class DisposeAction implements Runnable { + public final void run() { // Lock: Covered by DestroyAction .. helper.dispose(GLWindow.this); } @@ -579,8 +579,8 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer { } } - class InitAction implements Runnable { - public void run() { + private class InitAction implements Runnable { + public final void run() { // Lock: Locked Surface/Window by MakeCurrent/Release helper.init(GLWindow.this); resetCounter(); @@ -588,8 +588,8 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer { } private InitAction initAction = new InitAction(); - class DisplayAction implements Runnable { - public void run() { + private class DisplayAction implements Runnable { + public final void run() { // Lock: Locked Surface/Window by display _and_ MakeCurrent/Release if (sendReshape) { helper.reshape(GLWindow.this, 0, 0, getWidth(), getHeight()); @@ -659,8 +659,8 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer { totalFrames = 0; lastFrames = 0; } - class SwapBuffersAction implements Runnable { - public void run() { + private class SwapBuffersAction implements Runnable { + public final void run() { drawable.swapBuffers(); } } diff --git a/src/newt/classes/jogamp/newt/DisplayImpl.java b/src/newt/classes/jogamp/newt/DisplayImpl.java index 83f4ca47c..299f4fb54 100644 --- a/src/newt/classes/jogamp/newt/DisplayImpl.java +++ b/src/newt/classes/jogamp/newt/DisplayImpl.java @@ -195,7 +195,7 @@ public abstract class DisplayImpl extends Display { } public void runOnEDTIfAvail(boolean wait, final Runnable task) { - if( shallRunOnEDT() && null!=edtUtil ) { + if( shallRunOnEDT() && null!=edtUtil && !edtUtil.isCurrentThreadEDT()) { edtUtil.invoke(wait, task); } else { task.run(); @@ -353,6 +353,7 @@ public abstract class DisplayImpl extends Display { private Object eventsLock = new Object(); private ArrayList/*<NEWTEvent>*/ events = new ArrayList(); + private volatile boolean haveEvents = false; class DispatchMessagesRunnable implements Runnable { public void run() { @@ -361,6 +362,21 @@ public abstract class DisplayImpl extends Display { } DispatchMessagesRunnable dispatchMessagesRunnable = new DispatchMessagesRunnable(); + final void dispatchMessage(final NEWTEventTask eventTask) { + NEWTEvent event = eventTask.get(); + Object source = event.getSource(); + if(source instanceof NEWTEventConsumer) { + NEWTEventConsumer consumer = (NEWTEventConsumer) source ; + if(!consumer.consumeEvent(event)) { + // enqueue for later execution + enqueueEvent(false, event); + } + } else { + throw new RuntimeException("Event source not NEWT: "+source.getClass().getName()+", "+source); + } + eventTask.notifyIssuer(); + } + public void dispatchMessages() { // System.err.println("Display.dispatchMessages() 0 "+this+" "+getThreadName()); if(0==refCount) return; // no screens @@ -368,29 +384,19 @@ public abstract class DisplayImpl extends Display { ArrayList/*<NEWTEvent>*/ _events = null; - if(events.size()>0) { - // swap events list to free ASAP + if(haveEvents) { // volatile: ok synchronized(eventsLock) { - if(events.size()>0) { + if(haveEvents) { + // swap events list to free ASAP _events = events; events = new ArrayList(); + haveEvents = false; } eventsLock.notifyAll(); } if( null != _events ) { for (int i=0; i < _events.size(); i++) { - NEWTEventTask eventTask = (NEWTEventTask) _events.get(i); - NEWTEvent event = eventTask.get(); - Object source = event.getSource(); - if(source instanceof NEWTEventConsumer) { - NEWTEventConsumer consumer = (NEWTEventConsumer) source ; - if(!consumer.consumeEvent(event)) { - enqueueEvent(false, event); - } - } else { - throw new RuntimeException("Event source not NEWT: "+source.getClass().getName()+", "+source); - } - eventTask.notifyIssuer(); + dispatchMessage((NEWTEventTask) _events.get(i)); } } } @@ -408,11 +414,19 @@ public abstract class DisplayImpl extends Display { } return; } + + // can't wait if we are on EDT -> consume right away + if(wait && edtUtil.isCurrentThreadEDT()) { + dispatchMessage(new NEWTEventTask(e, null)); + return; + } + Object lock = new Object(); NEWTEventTask eTask = new NEWTEventTask(e, wait?lock:null); synchronized(lock) { synchronized(eventsLock) { events.add(eTask); + haveEvents = true; eventsLock.notifyAll(); } if( wait ) { diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java index 391f918cf..cb1c0eda2 100644 --- a/src/newt/classes/jogamp/newt/WindowImpl.java +++ b/src/newt/classes/jogamp/newt/WindowImpl.java @@ -612,75 +612,74 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer return screen; } - class VisibleAction implements Runnable { - boolean visible; - boolean nativeWindowCreated; - boolean madeVisible; - - public VisibleAction (boolean visible) { - this.visible = visible; - this.nativeWindowCreated = false; - this.madeVisible = false; - } - - public final boolean getNativeWindowCreated() { return nativeWindowCreated; } - public final boolean getBecameVisible() { return madeVisible; } - public final boolean getChanged() { return nativeWindowCreated || madeVisible; } - - public void run() { - windowLock.lock(); - try { - if(null!=lifecycleHook) { - lifecycleHook.resetCounter(); - } + final void setVisibleActionImpl(boolean visible) { + boolean nativeWindowCreated = false; + boolean madeVisible = false; + + windowLock.lock(); + try { + if(null!=lifecycleHook) { + lifecycleHook.resetCounter(); + } - if(!visible && null!=childWindows && childWindows.size()>0) { - synchronized(childWindowsLock) { - for(int i = 0; i < childWindows.size(); i++ ) { - NativeWindow nw = (NativeWindow) childWindows.get(i); - if(nw instanceof WindowImpl) { - ((WindowImpl)nw).setVisible(false); - } + if(!visible && null!=childWindows && childWindows.size()>0) { + synchronized(childWindowsLock) { + for(int i = 0; i < childWindows.size(); i++ ) { + NativeWindow nw = (NativeWindow) childWindows.get(i); + if(nw instanceof WindowImpl) { + ((WindowImpl)nw).setVisible(false); } - } } - if(0==windowHandle && visible) { - if( 0<width*height ) { - nativeWindowCreated = createNative(); - WindowImpl.this.waitForVisible(visible, true); - madeVisible = visible; - } - } else if(WindowImpl.this.visible != visible) { - if(0 != windowHandle) { - setVisibleImpl(visible, x, y, width, height); - WindowImpl.this.waitForVisible(visible, true); - madeVisible = visible; - } + } + } + if(0==windowHandle && visible) { + if( 0<width*height ) { + nativeWindowCreated = createNative(); + WindowImpl.this.waitForVisible(visible, true); + madeVisible = visible; } - - if(null!=lifecycleHook) { - lifecycleHook.setVisibleActionPost(visible, nativeWindowCreated); + } else if(WindowImpl.this.visible != visible) { + if(0 != windowHandle) { + setVisibleImpl(visible, x, y, width, height); + WindowImpl.this.waitForVisible(visible, true); + madeVisible = visible; } + } - if(0!=windowHandle && visible && null!=childWindows && childWindows.size()>0) { - synchronized(childWindowsLock) { - for(int i = 0; i < childWindows.size(); i++ ) { - NativeWindow nw = (NativeWindow) childWindows.get(i); - if(nw instanceof WindowImpl) { - ((WindowImpl)nw).setVisible(true); - } + if(null!=lifecycleHook) { + lifecycleHook.setVisibleActionPost(visible, nativeWindowCreated); + } + + if(0!=windowHandle && visible && null!=childWindows && childWindows.size()>0) { + synchronized(childWindowsLock) { + for(int i = 0; i < childWindows.size(); i++ ) { + NativeWindow nw = (NativeWindow) childWindows.get(i); + if(nw instanceof WindowImpl) { + ((WindowImpl)nw).setVisible(true); } - } } - if(DEBUG_IMPLEMENTATION) { - System.err.println("Window setVisible: END ("+getThreadName()+") "+x+"/"+y+" "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible: "+WindowImpl.this.visible+", nativeWindowCreated: "+nativeWindowCreated+", madeVisible: "+madeVisible); - } - } finally { - windowLock.unlock(); + } } - if( getChanged() ) { - sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener + if(DEBUG_IMPLEMENTATION) { + System.err.println("Window setVisible: END ("+getThreadName()+") "+x+"/"+y+" "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible: "+WindowImpl.this.visible+", nativeWindowCreated: "+nativeWindowCreated+", madeVisible: "+madeVisible); } + } finally { + windowLock.unlock(); + } + if( nativeWindowCreated || madeVisible ) { + sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener + } + } + + private class VisibleAction implements Runnable { + boolean visible; + + private VisibleAction (boolean visible) { + this.visible = visible; + } + + public final void run() { + setVisibleActionImpl(visible); } } @@ -696,25 +695,21 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer System.err.println(msg); Thread.dumpStack(); } - VisibleAction visibleAction = new VisibleAction(visible); - runOnEDTIfAvail(true, visibleAction); + runOnEDTIfAvail(true, new VisibleAction(visible)); } } - class SetSizeActionImpl implements Runnable { - int visibleAction = 0; // 1 invisible, 2 visible (create) + private class SetSizeActionImpl implements Runnable { int width, height; - public int getVisibleAction() { - return visibleAction; - } - public SetSizeActionImpl(int w, int h) { + private SetSizeActionImpl(int w, int h) { width = w; height = h; } - public void run() { + public final void run() { windowLock.lock(); try { + int visibleAction = 0; // 1 invisible, 2 visible (create) if ( !fullscreen && ( width != WindowImpl.this.width || WindowImpl.this.height != height ) ) { if(DEBUG_IMPLEMENTATION) { String msg = "Window setSize: START "+WindowImpl.this.width+"x"+WindowImpl.this.height+" -> "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible "+visible; @@ -737,6 +732,10 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } if(DEBUG_IMPLEMENTATION) { System.err.println("Window setSize: END "+WindowImpl.this.width+"x"+WindowImpl.this.height+", visibleAction "+visibleAction); + } + switch(visibleAction) { + case 1: setVisibleActionImpl(false); break; + case 2: setVisibleActionImpl(true); break; } } } finally { @@ -747,17 +746,19 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer public void setSize(int width, int height) { if(isValid()) { - SetSizeActionImpl setSizeAction = new SetSizeActionImpl(width, height); - runOnEDTIfAvail(true, setSizeAction); - switch(setSizeAction.getVisibleAction()) { - case 1: setVisible(false); break; - case 2: setVisible(true); break; - } + runOnEDTIfAvail(true, new SetSizeActionImpl(width, height)); } } - class DestroyAction implements Runnable { - public void run() { + private class DestroyAction implements Runnable { + public final void run() { + boolean animatorPaused = false; + if(null!=lifecycleHook) { + animatorPaused = lifecycleHook.pauseRenderingAction(); + } + if(null!=lifecycleHook) { + lifecycleHook.destroyActionPreLock(); + } windowLock.lock(); try { if( !isValid() ) { @@ -797,6 +798,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } finally { windowLock.unlock(); } + if(animatorPaused) { + lifecycleHook.resumeRenderingAction(); + } } } @@ -808,17 +812,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer //Exception ee = new Exception(msg); //ee.printStackTrace(); } - boolean animatorPaused = false; - if(null!=lifecycleHook) { - animatorPaused = lifecycleHook.pauseRenderingAction(); - } - if(null!=lifecycleHook) { - lifecycleHook.destroyActionPreLock(); - } runOnEDTIfAvail(true, destroyAction); - if(animatorPaused) { - lifecycleHook.resumeRenderingAction(); - } } } @@ -900,18 +894,18 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } } - class ReparentActionImpl implements Runnable, ReparentAction { + private class ReparentActionImpl implements Runnable, ReparentAction { NativeWindow newParentWindow; boolean forceDestroyCreate; int reparentAction; - public ReparentActionImpl(NativeWindow newParentWindow, boolean forceDestroyCreate) { + private ReparentActionImpl(NativeWindow newParentWindow, boolean forceDestroyCreate) { this.newParentWindow = newParentWindow; this.forceDestroyCreate = forceDestroyCreate; this.reparentAction = -1; // ensure it's set } - public final int getStrategy() { + private int getStrategy() { return reparentAction; } @@ -920,14 +914,24 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer screen = newScreen; } - public void run() { - boolean wasVisible; - + public final void run() { + boolean animatorPaused = false; + if(null!=lifecycleHook) { + animatorPaused = lifecycleHook.pauseRenderingAction(); + } + reparent(); + if(animatorPaused) { + lifecycleHook.resumeRenderingAction(); + } + } + + private void reparent() { // mirror pos/size so native change notification can get overwritten int x = WindowImpl.this.x; int y = WindowImpl.this.y; int width = WindowImpl.this.width; int height = WindowImpl.this.height; + boolean wasVisible; windowLock.lock(); try { @@ -1160,8 +1164,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer break; case ACTION_NATIVE_CREATION: - // This may run on the Display/Screen connection, - // hence a new EDT task + // This may run on the new Display/Screen connection, hence a new EDT task runOnEDTIfAvail(true, reparentActionRecreate); break; } @@ -1169,8 +1172,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } } - class ReparentActionRecreate implements Runnable { - public void run() { + private class ReparentActionRecreate implements Runnable { + public final void run() { windowLock.lock(); try { visible = true; @@ -1191,19 +1194,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer public int reparentWindow(NativeWindow newParent, boolean forceDestroyCreate) { int reparentActionStrategy = ReparentAction.ACTION_INVALID; if(isValid()) { - boolean animatorPaused = false; - if(null!=lifecycleHook) { - animatorPaused = lifecycleHook.pauseRenderingAction(); - } - try { - ReparentActionImpl reparentAction = new ReparentActionImpl(newParent, forceDestroyCreate); - runOnEDTIfAvail(true, reparentAction); - reparentActionStrategy = reparentAction.getStrategy(); - } finally { - if(animatorPaused) { - lifecycleHook.resumeRenderingAction(); - } - } + ReparentActionImpl reparentAction = new ReparentActionImpl(newParent, forceDestroyCreate); + runOnEDTIfAvail(true, reparentAction); + reparentActionStrategy = reparentAction.getStrategy(); } return reparentActionStrategy; } @@ -1236,14 +1229,14 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } } - class DecorationActionImpl implements Runnable { + private class DecorationActionImpl implements Runnable { boolean undecorated; - public DecorationActionImpl(boolean undecorated) { + private DecorationActionImpl(boolean undecorated) { this.undecorated = undecorated; } - public void run() { + public final void run() { windowLock.lock(); try { if(!fullscreen && isNativeValid() && WindowImpl.this.undecorated != undecorated) { @@ -1284,14 +1277,13 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } finally { windowLock.unlock(); } + sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener } } public void setUndecorated(boolean value) { if(isValid()) { - DecorationActionImpl decorationAction = new DecorationActionImpl(value); - runOnEDTIfAvail(true, decorationAction); - sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener + runOnEDTIfAvail(true, new DecorationActionImpl(value)); } } @@ -1431,8 +1423,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer d.runOnEDTIfAvail(wait, task); } - class RequestFocusAction implements Runnable { - public void run() { + private class RequestFocusAction implements Runnable { + public final void run() { if(DEBUG_IMPLEMENTATION) { System.err.println("Window.RequestFocusAction: ("+getThreadName()+"): "+hasFocus+" -> true - windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle)); } @@ -1468,14 +1460,14 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer return res; } - class SetPositionActionImpl implements Runnable { + private class SetPositionActionImpl implements Runnable { int x, y; - public SetPositionActionImpl(int x, int y) { + private SetPositionActionImpl(int x, int y) { this.x = x; this.y = y; } - public void run() { + public final void run() { windowLock.lock(); try { if(DEBUG_IMPLEMENTATION) { @@ -1500,19 +1492,18 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer public void setPosition(int x, int y) { if(isValid()) { - SetPositionActionImpl setPositionAction = new SetPositionActionImpl(x, y); - runOnEDTIfAvail(true, setPositionAction); + runOnEDTIfAvail(true, new SetPositionActionImpl(x, y)); } } - class FullScreenActionImpl implements Runnable { + private class FullScreenActionImpl implements Runnable { boolean fullscreen; - public FullScreenActionImpl (boolean fullscreen) { + private FullScreenActionImpl (boolean fullscreen) { this.fullscreen = fullscreen; } - public void run() { + public final void run() { windowLock.lock(); try { if(isNativeValid() && WindowImpl.this.fullscreen != fullscreen) { @@ -1578,19 +1569,18 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } finally { windowLock.unlock(); } + sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener } } public boolean setFullscreen(boolean fullscreen) { if(isValid()) { - FullScreenActionImpl fullScreenAction = new FullScreenActionImpl(fullscreen); - runOnEDTIfAvail(true, fullScreenAction); - sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener + runOnEDTIfAvail(true, new FullScreenActionImpl(fullscreen)); } return this.fullscreen; } - class ScreenModeListenerImpl implements ScreenModeListener { + private class ScreenModeListenerImpl implements ScreenModeListener { boolean animatorPaused = false; public void screenModeChangeNotify(ScreenMode sm) { diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListAWT.java index 63f54e267..bf4c493bc 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListAWT.java @@ -85,8 +85,12 @@ public class TestSharedContextListAWT extends UITestCase { protected GLCanvas runTestGL(final Frame frame, final Animator animator, final int x, final int y, final boolean useShared) throws InterruptedException { - final GLCanvas glCanvas = new GLCanvas(caps, useShared ? sharedDrawable.getContext() : null); + final GLCanvas glCanvas = new GLCanvas(caps, useShared ? sharedDrawable.getContext() : null); Assert.assertNotNull(glCanvas); + frame.add(glCanvas); + frame.setLocation(x, y); + frame.setSize(width, height); + Gears gears = new Gears(); if(useShared) { gears.setGears(sharedGears.getGear1(), sharedGears.getGear2(), sharedGears.getGear3()); @@ -95,14 +99,7 @@ public class TestSharedContextListAWT extends UITestCase { animator.add(glCanvas); - SwingUtilities.invokeLater(new Runnable() { - public void run() { - frame.add(glCanvas); - frame.setLocation(x, y); - frame.setSize(width, height); - frame.pack(); - frame.setVisible(true); - } }); + frame.setVisible(true); Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glCanvas, true)); return glCanvas; diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/gears/Gears.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/gears/Gears.java index dd28b4e40..0dcf6bec8 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/gears/Gears.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/gears/Gears.java @@ -107,14 +107,17 @@ public class Gears implements GLEventListener { gl.glEnable(GL2.GL_NORMALIZE); // MouseListener gearsMouse = new TraceMouseAdapter(new GearsMouseAdapter()); - MouseListener gearsMouse = new GearsMouseAdapter(); + MouseListener gearsMouse = new GearsMouseAdapter(); + KeyListener gearsKeys = new GearsKeyAdapter(); if (drawable instanceof Window) { Window window = (Window) drawable; window.addMouseListener(gearsMouse); + window.addKeyListener(gearsKeys); } else if (GLProfile.isAWTAvailable() && drawable instanceof java.awt.Component) { java.awt.Component comp = (java.awt.Component) drawable; new AWTMouseAdapter(gearsMouse).addTo(comp); + new AWTKeyAdapter(gearsKeys).addTo(comp); } } @@ -309,6 +312,21 @@ public class Gears implements GLEventListener { gl.glEnd(); } + class GearsKeyAdapter extends KeyAdapter { + public void keyPressed(KeyEvent e) { + int kc = e.getKeyCode(); + if(KeyEvent.VK_LEFT == kc) { + view_roty -= 1; + } else if(KeyEvent.VK_RIGHT == kc) { + view_roty += 1; + } else if(KeyEvent.VK_UP == kc) { + view_rotx -= 1; + } else if(KeyEvent.VK_DOWN == kc) { + view_rotx += 1; + } + } + } + class GearsMouseAdapter extends MouseAdapter { public void mousePressed(MouseEvent e) { prevMouseX = e.getX(); diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/gears/newt/TestGearsNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/gears/newt/TestGearsNEWT.java index 588fe725f..0f7d77f82 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/gears/newt/TestGearsNEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/gears/newt/TestGearsNEWT.java @@ -83,11 +83,15 @@ public class TestGearsNEWT extends UITestCase { glWindow.addKeyListener(new KeyAdapter() { public void keyTyped(KeyEvent e) { if(e.getKeyChar()=='f') { - f_glWindow.invoke(false, new GLRunnable() { - public void run(GLAutoDrawable drawable) { - GLWindow win = (GLWindow)drawable; - win.setFullscreen(!win.isFullscreen()); - } }); + 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(); } } }); diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWT01GLn.java b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWT01GLn.java index 96204d148..af125d4df 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWT01GLn.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWT01GLn.java @@ -54,14 +54,6 @@ import org.junit.After; import org.junit.Test;
import com.jogamp.opengl.test.junit.util.UITestCase;
-import javax.media.nativewindow.NativeSurface;
-import javax.media.nativewindow.ProxySurface;
-import javax.media.opengl.GLCapabilities;
-import javax.media.opengl.GLDrawable;
-import jogamp.nativewindow.swt.SWTAccessor;
-import jogamp.opengl.windows.wgl.WindowsWGLDrawableFactory;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.widgets.Canvas;
/**
* Tests that a basic SWT app can open without crashing under different GL profiles. Uses the SWT GL canvas.
@@ -173,73 +165,6 @@ public class TestSWT01GLn extends UITestCase { glcanvas.dispose();
}
- /**
- protected void runTestBGL( GLProfile glprofile ) throws InterruptedException {
- GLCapabilities caps = new GLCapabilities(glprofile);
- WindowsWGLDrawableFactory factory = (WindowsWGLDrawableFactory) GLDrawableFactory.getFactory(glprofile);
-
- GLData gldata = new GLData();
- gldata.doubleBuffer = true;
- // need SWT.NO_BACKGROUND to prevent SWT from clearing the window
- // at the wrong times (we use glClear for this instead)
- final Canvas canvas = new Canvas(composite, SWT.NO_BACKGROUND);
- Assert.assertNotNull( canvas );
- canvas.setSize(iwidth, iheight);
- long windowHandle = SWTAccessor.getHandle(canvas);
- Point sz = canvas.getSize();
- ProxySurface surface = factory.createProxySurfaceImpl(caps, caps, null, windowHandle, sz.x, sz.y);
- final GLDrawable glDrawable = factory.createGLDrawable(surface);
-
- glDrawable.setRealized(true);
- final GLContext glContext = glDrawable.createContext(null);
-
- // fix the viewport when the user resizes the window
- canvas.addListener( SWT.Resize, new Listener() {
- public void handleEvent( Event event ) {
- Rectangle rectangle = canvas.getClientArea();
- glContext.makeCurrent();
- GL2 gl = glContext.getGL().getGL2();
- OneTriangle.setup( gl, rectangle );
- glContext.release();
- System.err.println("resize");
- }
- });
-
- // draw the triangle when the OS tells us that any part of the window needs drawing
- canvas.addPaintListener( new PaintListener() {
- public void paintControl( PaintEvent paintevent ) {
- Rectangle rectangle = canvas.getClientArea();
- glContext.makeCurrent();
- GL2 gl = glContext.getGL().getGL2();
- OneTriangle.render( gl, rectangle );
- glDrawable.swapBuffers();
- glContext.release();
- System.err.println("paint");
- }
- });
-
- shell.setText( getClass().getName() );
- shell.setSize( iwidth, iheight );
- shell.open();
-
- long lStartTime = System.currentTimeMillis();
- long lEndTime = lStartTime + duration;
- try {
- while( (System.currentTimeMillis() < lEndTime) && !canvas.isDisposed() ) {
- if( !display.readAndDispatch() ) {
- // blocks on linux .. display.sleep();
- Thread.sleep(10);
- }
- }
- } catch( Throwable throwable ) {
- throwable.printStackTrace();
- Assume.assumeNoException( throwable );
- }
- glContext.destroy();
- glDrawable.setRealized(false);
- canvas.dispose();
- } */
-
@Test
public void testA01GLDefault() throws InterruptedException {
GLProfile glprofile = GLProfile.getDefault();
@@ -247,13 +172,6 @@ public class TestSWT01GLn extends UITestCase { runTestAGL( glprofile );
}
- /* @Test
- public void testB01GLDefault() throws InterruptedException {
- GLProfile glprofile = GLProfile.getDefault();
- System.out.println( "GLProfile Default: " + glprofile );
- runTestBGL( glprofile );
- } */
-
@Test
public void test02GL2() throws InterruptedException {
GLProfile glprofile = GLProfile.get(GLProfile.GL2);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWT02GLn.java b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWT02GLn.java new file mode 100644 index 000000000..b3d167b80 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWT02GLn.java @@ -0,0 +1,236 @@ +/** + * 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.swt; + +import javax.media.opengl.GL2; +import javax.media.opengl.GLContext; +import javax.media.opengl.GLDrawableFactory; +import javax.media.opengl.GLProfile; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; + +import org.junit.Assert; +import org.junit.Assume; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.After; +import org.junit.Test; + +import com.jogamp.opengl.test.junit.util.UITestCase; +import javax.media.nativewindow.AbstractGraphicsDevice; +import javax.media.nativewindow.ProxySurface; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLDrawable; +import jogamp.nativewindow.swt.SWTAccessor; +import org.eclipse.swt.widgets.Canvas; + +/** + * Tests that a basic SWT app can open without crashing under different GL profiles. Uses the SWT GL canvas. + * @author Wade Walker + */ +public class TestSWT02GLn extends UITestCase { + + static int duration = 250; + + static final int iwidth = 640; + static final int iheight = 480; + + Display display = null; + Shell shell = null; + Composite composite = null; + + @BeforeClass + public static void startup() { + GLProfile.initSingleton( true ); + System.out.println( "GLProfile " + GLProfile.glAvailabilityToString() ); + } + + @Before + public void init() { + display = new Display(); + Assert.assertNotNull( display ); + shell = new Shell( display ); + Assert.assertNotNull( shell ); + shell.setLayout( new FillLayout() ); + composite = new Composite( shell, SWT.NONE ); + composite.setLayout( new FillLayout() ); + Assert.assertNotNull( composite ); + } + + @After + public void release() { + Assert.assertNotNull( display ); + Assert.assertNotNull( shell ); + Assert.assertNotNull( composite ); + try { + composite.dispose(); + shell.dispose(); + display.dispose(); + } + catch( Throwable throwable ) { + throwable.printStackTrace(); + Assume.assumeNoException( throwable ); + } + display = null; + shell = null; + composite = null; + } + + protected void runTestAGL( GLProfile glprofile ) throws InterruptedException { + GLCapabilities caps = new GLCapabilities(glprofile); + GLDrawableFactory factory = GLDrawableFactory.getFactory(glprofile); + + // need SWT.NO_BACKGROUND to prevent SWT from clearing the window + // at the wrong times (we use glClear for this instead) + final Canvas canvas = new Canvas( composite, SWT.NO_BACKGROUND); + Assert.assertNotNull( canvas ); + + SWTAccessor.setRealized(canvas, true); + AbstractGraphicsDevice device = SWTAccessor.getDevice(canvas); + long nativeWindowHandle = SWTAccessor.getWindowHandle(canvas); + System.err.println("*** device: " + device); + System.err.println("*** window handle: 0x" + Long.toHexString(nativeWindowHandle)); + + ProxySurface proxySurface = factory.createProxySurface(device, nativeWindowHandle, caps, null); + Assert.assertNotNull( proxySurface ); + proxySurface.setSize( 640, 480 ); + System.err.println("*** ProxySurface: " + proxySurface); + final GLDrawable drawable = factory.createGLDrawable(proxySurface); + Assert.assertNotNull( drawable ); + drawable.setRealized(true); + System.err.println("*** Drawable: " + drawable); + Assert.assertTrue( drawable.isRealized() ); + final GLContext glcontext = drawable.createContext(null); + // trigger native creation .. + if( GLContext.CONTEXT_NOT_CURRENT < glcontext.makeCurrent() ) { + glcontext.release(); + } + + final boolean[] sizeMissing = new boolean[] { false }; + + // fix the viewport when the user resizes the window + canvas.addListener( SWT.Resize, new Listener() { + public void handleEvent( Event event ) { + Rectangle rectangle = canvas.getClientArea(); + boolean glok=false; + if( GLContext.CONTEXT_NOT_CURRENT < glcontext.makeCurrent() ) { + glok=true; + GL2 gl = glcontext.getGL().getGL2(); + OneTriangle.setup( gl, rectangle ); + glcontext.release(); + } else { + sizeMissing[0] = true; + } + System.err.println("resize: glok " + glok); + } + }); + + // draw the triangle when the OS tells us that any part of the window needs drawing + canvas.addPaintListener( new PaintListener() { + public void paintControl( PaintEvent paintevent ) { + Rectangle rectangle = canvas.getClientArea(); + boolean glok=false; + if( GLContext.CONTEXT_NOT_CURRENT < glcontext.makeCurrent() ) { + glok=true; + GL2 gl = glcontext.getGL().getGL2(); + if(sizeMissing[0]) { + OneTriangle.setup( gl, rectangle ); + sizeMissing[0] = false; + } + OneTriangle.render( gl, rectangle ); + drawable.swapBuffers(); + glcontext.release(); + } + System.err.println("paint: glok " + glok); + } + }); + + shell.setText( getClass().getName() ); + shell.setSize( 640, 480 ); + shell.open(); + + long lStartTime = System.currentTimeMillis(); + long lEndTime = lStartTime + duration; + try { + while( (System.currentTimeMillis() < lEndTime) && !canvas.isDisposed() ) { + if( !display.readAndDispatch() ) { + // blocks on linux .. display.sleep(); + Thread.sleep(10); + } + } + } catch( Throwable throwable ) { + throwable.printStackTrace(); + Assume.assumeNoException( throwable ); + } + glcontext.destroy(); + drawable.setRealized(false); + canvas.dispose(); + } + + @Test + public void testA01GLDefault() throws InterruptedException { + GLProfile glprofile = GLProfile.getDefault(); + System.out.println( "GLProfile Default: " + glprofile ); + runTestAGL( glprofile ); + } + + @Test + public void test02GL2() throws InterruptedException { + GLProfile glprofile = GLProfile.get(GLProfile.GL2); + System.out.println( "GLProfile GL2: " + glprofile ); + runTestAGL( glprofile ); + } + + static int atoi(String a) { + int i=0; + try { + i = Integer.parseInt(a); + } catch (Exception ex) { ex.printStackTrace(); } + return i; + } + + public static void main(String args[]) { + for(int i=0; i<args.length; i++) { + if(args[i].equals("-time")) { + duration = atoi(args[++i]); + } + } + System.out.println("durationPerTest: "+duration); + org.junit.runner.JUnitCore.main(TestSWT02GLn.class.getName()); + } +} diff --git a/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java b/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java index bbd53db9b..d0f9172bc 100644 --- a/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java +++ b/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java @@ -367,11 +367,15 @@ public class AWTRobotUtil { } if(wait>=POLL_DIVIDER) { // for some reason GLCanvas hasn't been painted yet, force it! - System.err.println("XXX: FORCE REPAINT - canvas: "+glcanvas); + System.err.println("XXX: FORCE REPAINT PRE - canvas: "+glcanvas); glcanvas.repaint(); for (wait=0; wait<POLL_DIVIDER && realized != glcanvas.isRealized(); wait++) { Thread.sleep(TIME_OUT/POLL_DIVIDER); } + System.err.println("XXX: FORCE REPAINT POST - canvas: "+glcanvas); + } + for (wait=0; wait<POLL_DIVIDER && realized != glcanvas.isRealized(); wait++) { + Thread.sleep(TIME_OUT/POLL_DIVIDER); } } } else if(obj instanceof com.jogamp.newt.Window) { diff --git a/src/test/jogamp/newt/WindowImplAccess.java b/src/test/jogamp/newt/WindowImplAccess.java index 848e58227..76d0dc050 100644 --- a/src/test/jogamp/newt/WindowImplAccess.java +++ b/src/test/jogamp/newt/WindowImplAccess.java @@ -45,7 +45,12 @@ public class WindowImplAccess { } else { throw new RuntimeException("Given Window not a GLWindow, not WindowImpl, but "+win.getClass()); } - winImpl.windowDestroyNotify(); + final WindowImpl winImplF = winImpl; + winImplF.runOnEDTIfAvail(true, new Runnable() { + public void run() { + winImplF.windowDestroyNotify(); + } + }); } } |