aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/jogl/classes/com/jogamp/opengl/FBObject.java12
-rw-r--r--src/jogl/classes/jogamp/opengl/GLBufferStateTracker.java2
-rw-r--r--src/jogl/classes/jogamp/opengl/GLContextImpl.java32
-rw-r--r--src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java33
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java54
-rw-r--r--src/newt/classes/com/jogamp/newt/opengl/GLWindow.java14
-rw-r--r--src/newt/classes/jogamp/newt/WindowImpl.java10
-rw-r--r--src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java46
-rw-r--r--src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java194
-rw-r--r--src/test-native/displayMultiple02_mch.c130
-rw-r--r--src/test-native/displayMultiple02_new_mch.c199
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestBug692GL3VAO.java352
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java2
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/newt/TestGearsNewtAWTWrapper.java68
14 files changed, 982 insertions, 166 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/FBObject.java b/src/jogl/classes/com/jogamp/opengl/FBObject.java
index 7d0fcfa38..6f2ac3e35 100644
--- a/src/jogl/classes/com/jogamp/opengl/FBObject.java
+++ b/src/jogl/classes/com/jogamp/opengl/FBObject.java
@@ -835,6 +835,8 @@ public class FBObject {
checkPreGLError(gl);
+ if( 0 >= width ) { width = 1; }
+ if( 0 >= height ) { height = 1; }
this.width = width;
this.height = height;
this.samples = samples <= maxSamples ? samples : maxSamples;
@@ -941,7 +943,7 @@ public class FBObject {
* @throws GLException in case of an error, i.e. size too big, etc ..
*/
public final void reset(GL gl, int newWidth, int newHeight, int newSamples, boolean resetSamplingSink) {
- if(!initialized) {
+ if( !initialized ) {
init(gl, newWidth, newHeight, newSamples);
return;
}
@@ -949,10 +951,10 @@ public class FBObject {
newSamples = newSamples <= maxSamples ? newSamples : maxSamples; // clamp
if( newWidth != width || newHeight != height || newSamples != samples ) {
- if(0>=newWidth) { newWidth = 1; }
- if(0>=newHeight) { newHeight = 1; }
- if(newWidth > 2 + maxTextureSize || newHeight> 2 + maxTextureSize ||
- newWidth > maxRenderbufferSize || newHeight> maxRenderbufferSize ) {
+ if( 0 >= newWidth ) { newWidth = 1; }
+ if( 0 >= newHeight ) { newHeight = 1; }
+ if( newWidth > 2 + maxTextureSize || newHeight > 2 + maxTextureSize ||
+ newWidth > maxRenderbufferSize || newHeight > maxRenderbufferSize ) {
throw new GLException("size "+width+"x"+height+" exceeds on of the maxima [texture "+maxTextureSize+", renderbuffer "+maxRenderbufferSize+"]");
}
diff --git a/src/jogl/classes/jogamp/opengl/GLBufferStateTracker.java b/src/jogl/classes/jogamp/opengl/GLBufferStateTracker.java
index 4a1a81bcb..7f5316fbd 100644
--- a/src/jogl/classes/jogamp/opengl/GLBufferStateTracker.java
+++ b/src/jogl/classes/jogamp/opengl/GLBufferStateTracker.java
@@ -91,6 +91,7 @@ public class GLBufferStateTracker {
bindingMap.setKeyNotFoundValue(0xFFFFFFFF);
// Start with known unbound targets for known keys
+ // setBoundBufferObject(GL2GL3.GL_VERTEX_ARRAY_BINDING, 0); // not using default VAO (removed in GL3 core) - only explicit
setBoundBufferObject(GL.GL_ARRAY_BUFFER, 0);
setBoundBufferObject(GL.GL_ELEMENT_ARRAY_BUFFER, 0);
setBoundBufferObject(GL2.GL_PIXEL_PACK_BUFFER, 0);
@@ -120,6 +121,7 @@ public class GLBufferStateTracker {
boolean gotQueryTarget = true;
int queryTarget = 0;
switch (target) {
+ case GL2GL3.GL_VERTEX_ARRAY_BINDING: queryTarget = GL2GL3.GL_VERTEX_ARRAY_BINDING; break;
case GL.GL_ARRAY_BUFFER: queryTarget = GL.GL_ARRAY_BUFFER_BINDING; break;
case GL.GL_ELEMENT_ARRAY_BUFFER: queryTarget = GL.GL_ELEMENT_ARRAY_BUFFER_BINDING; break;
case GL2.GL_PIXEL_PACK_BUFFER: queryTarget = GL2.GL_PIXEL_PACK_BUFFER_BINDING; break;
diff --git a/src/jogl/classes/jogamp/opengl/GLContextImpl.java b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
index 0d8b193af..9f7c9cf57 100644
--- a/src/jogl/classes/jogamp/opengl/GLContextImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
@@ -342,23 +342,24 @@ public abstract class GLContextImpl extends GLContext {
@Override
public final void destroy() {
- if ( null == drawable ) {
- throw new GLException("Drawable is null: "+toString());
- }
if ( DEBUG_TRACE_SWITCH ) {
+ final long drawH = null != drawable ? drawable.getHandle() : 0;
System.err.println(getThreadName() + ": GLContextImpl.destroy.0: obj " + toHexString(hashCode()) + ", ctx " + toHexString(contextHandle) +
- ", surf "+toHexString(drawable.getHandle())+", isShared "+GLContextShareSet.isShared(this)+" - "+lock);
+ ", surf "+toHexString(drawH)+", isShared "+GLContextShareSet.isShared(this)+" - "+lock);
}
- if ( 0 != contextHandle ) {
+ if ( 0 != contextHandle ) { // isCreated() ?
+ if ( null == drawable ) {
+ throw new GLException("GLContext created but drawable is null: "+toString());
+ }
final int lockRes = drawable.lockSurface();
if ( NativeSurface.LOCK_SURFACE_NOT_READY >= lockRes ) {
// this would be odd ..
throw new GLException("Surface not ready to lock: "+drawable);
}
- Throwable drawableContextRealizedException = null;
+ Throwable associateDrawableException = null;
try {
if ( !drawable.isRealized() ) {
- throw new GLException("Drawable not realized: "+toString());
+ throw new GLException("GLContext created but drawable not realized: "+toString());
}
// Must hold the lock around the destroy operation to make sure we
// don't destroy the context while another thread renders to it.
@@ -380,7 +381,7 @@ public abstract class GLContextImpl extends GLContext {
try {
associateDrawable(false);
} catch (Throwable t) {
- drawableContextRealizedException = t;
+ associateDrawableException = t;
}
if ( 0 != defaultVAO ) {
int[] tmp = new int[] { defaultVAO };
@@ -410,8 +411,8 @@ public abstract class GLContextImpl extends GLContext {
} finally {
drawable.unlockSurface();
}
- if(null != drawableContextRealizedException) {
- throw new GLException("GLContext.destroy() during GLDrawableImpl.contextRealized(this, false)", drawableContextRealizedException);
+ if( null != associateDrawableException ) {
+ throw new GLException("GLContext.destroy() during associateDrawable(false)", associateDrawableException);
}
}
resetStates();
@@ -601,6 +602,13 @@ public abstract class GLContextImpl extends GLContext {
private final int makeCurrentWithinLock(int surfaceLockRes) throws GLException {
if (!isCreated()) {
+ if( 0 >= drawable.getWidth() || 0 >= drawable.getHeight() ) {
+ if ( DEBUG_TRACE_SWITCH ) {
+ System.err.println(getThreadName() + ": Create GL context REJECTED (zero surface size) obj " + toHexString(hashCode()) + ", surf "+toHexString(drawable.getHandle())+" for " + getClass().getName());
+ System.err.println(drawable.toString());
+ }
+ return CONTEXT_NOT_CURRENT;
+ }
if(DEBUG_GL) {
// only impacts w/ createContextARB(..)
additionalCtxCreationFlags |= GLContext.CTX_OPTION_DEBUG ;
@@ -1782,6 +1790,10 @@ public abstract class GLContextImpl extends GLContext {
public final GLStateTracker getGLStateTracker() {
return glStateTracker;
}
+
+ public final boolean isDefaultVAO(int vao) {
+ return defaultVAO == vao;
+ }
//---------------------------------------------------------------------------
// Helpers for context optimization where the last context is left
diff --git a/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java b/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java
index ac10e2728..85f63b52c 100644
--- a/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java
@@ -335,16 +335,17 @@ public class GLFBODrawableImpl extends GLDrawableImpl implements GLFBODrawable {
protected final void contextMadeCurrent(GLContext glc, boolean current) {
final GL gl = glc.getGL();
if(current) {
+ if( !initialized ) {
+ throw new GLException("Not initialized: "+this);
+ }
fbos[fboIBack].bind(gl);
fboBound = true;
- } else {
- if(fboBound) {
- swapFBOImpl(glc);
- swapFBOImplPost(glc);
- fboBound=false;
- if(DEBUG_SWAP) {
- System.err.println("Post FBO swap(@release): done");
- }
+ } else if( fboBound ) {
+ swapFBOImpl(glc);
+ swapFBOImplPost(glc);
+ fboBound=false;
+ if(DEBUG_SWAP) {
+ System.err.println("Post FBO swap(@release): done");
}
}
}
@@ -353,17 +354,15 @@ public class GLFBODrawableImpl extends GLDrawableImpl implements GLFBODrawable {
protected void swapBuffersImpl(boolean doubleBuffered) {
final GLContext ctx = GLContext.getCurrent();
boolean doPostSwap = false;
- if(null!=ctx && ctx.getGLDrawable()==this) {
- if(fboBound) {
- swapFBOImpl(ctx);
- doPostSwap = true;
- fboBound=false;
- if(DEBUG_SWAP) {
- System.err.println("Post FBO swap(@swap): done");
- }
+ if( null != ctx && ctx.getGLDrawable() == this && fboBound ) {
+ swapFBOImpl(ctx);
+ doPostSwap = true;
+ fboBound=false;
+ if(DEBUG_SWAP) {
+ System.err.println("Post FBO swap(@swap): done");
}
}
- if(null != swapBufferContext) {
+ if( null != swapBufferContext ) {
swapBufferContext.swapBuffers(doubleBuffered);
}
if(doPostSwap) {
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
index a197bd51f..6cab369cf 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
@@ -622,7 +622,7 @@ public abstract class MacOSXCGLContext extends GLContextImpl
* Hence this method blocks the main-thread only for a short period of time.
* </p>
*/
- class AttachNSOpenGLLayer implements Runnable {
+ class AttachGLLayerCmd implements Runnable {
final OffscreenLayerSurface ols;
final long ctx;
final int shaderProgram;
@@ -637,7 +637,7 @@ public abstract class MacOSXCGLContext extends GLContextImpl
/** Synchronized by instance's monitor */
boolean valid;
- AttachNSOpenGLLayer(OffscreenLayerSurface ols, long ctx, int shaderProgram, long pfmt, long pbuffer, int texID, boolean isOpaque, int width, int height) {
+ AttachGLLayerCmd(OffscreenLayerSurface ols, long ctx, int shaderProgram, long pfmt, long pbuffer, int texID, boolean isOpaque, int width, int height) {
this.ols = ols;
this.ctx = ctx;
this.shaderProgram = shaderProgram;
@@ -651,6 +651,15 @@ public abstract class MacOSXCGLContext extends GLContextImpl
this.nsOpenGLLayer = 0;
}
+ public final String contentToString() {
+ return "valid "+valid+", size "+width+"x"+height+", ctx "+toHexString(ctx)+", opaque "+isOpaque+", texID "+texID+", pbuffer "+toHexString(pbuffer)+", nsOpenGLLayer "+toHexString(nsOpenGLLayer);
+ }
+
+ @Override
+ public final String toString() {
+ return "AttachGLLayerCmd["+contentToString()+"]";
+ }
+
@Override
public void run() {
synchronized(this) {
@@ -693,14 +702,20 @@ public abstract class MacOSXCGLContext extends GLContextImpl
}
}
}
- AttachNSOpenGLLayer attachCALayerCmd = null;
+ AttachGLLayerCmd attachGLLayerCmd = null;
- class DetachNSOpenGLLayer implements Runnable {
- final AttachNSOpenGLLayer cmd;
+ class DetachGLLayerCmd implements Runnable {
+ final AttachGLLayerCmd cmd;
- DetachNSOpenGLLayer(AttachNSOpenGLLayer cmd) {
+ DetachGLLayerCmd(AttachGLLayerCmd cmd) {
this.cmd = cmd;
}
+
+ @Override
+ public final String toString() {
+ return "DetachGLLayerCmd["+cmd.contentToString()+"]";
+ }
+
@Override
public void run() {
synchronized( cmd ) {
@@ -734,7 +749,8 @@ public abstract class MacOSXCGLContext extends GLContextImpl
backingLayerHost = NativeWindowFactory.getOffscreenLayerSurface(drawable.getNativeSurface(), true);
if(DEBUG) {
- System.err.println("MaxOSXCGLContext.NSOpenGLImpl.associateDrawable: "+bound+", ctx "+toHexString(contextHandle)+", hasBackingLayerHost "+(null!=backingLayerHost));
+ System.err.println("MaxOSXCGLContext.NSOpenGLImpl.associateDrawable: "+bound+", ctx "+toHexString(contextHandle)+
+ ", hasBackingLayerHost "+(null!=backingLayerHost)+", attachGLLayerCmd "+attachGLLayerCmd);
// Thread.dumpStack();
}
@@ -785,10 +801,13 @@ public abstract class MacOSXCGLContext extends GLContextImpl
}
// All CALayer lifecycle ops are deferred on main-thread
- attachCALayerCmd = new AttachNSOpenGLLayer(
+ attachGLLayerCmd = new AttachGLLayerCmd(
backingLayerHost, ctx, gl3ShaderProgramName, pixelFormat, pbufferHandle, texID,
chosenCaps.isBackgroundOpaque(), lastWidth, lastHeight );
- OSXUtil.RunOnMainThread(false, attachCALayerCmd);
+ if(DEBUG) {
+ System.err.println("MaxOSXCGLContext.NSOpenGLImpl.associateDrawable(true): "+attachGLLayerCmd);
+ }
+ OSXUtil.RunOnMainThread(false, attachGLLayerCmd);
} else { // -> null == backingLayerHost
lastWidth = drawable.getWidth();
lastHeight = drawable.getHeight();
@@ -798,8 +817,11 @@ public abstract class MacOSXCGLContext extends GLContextImpl
}
} else { // -> !bound
if( null != backingLayerHost ) {
- final AttachNSOpenGLLayer cmd = attachCALayerCmd;
- attachCALayerCmd = null;
+ final AttachGLLayerCmd cmd = attachGLLayerCmd;
+ attachGLLayerCmd = null;
+ if( null == cmd ) {
+ throw new GLException("Null attachGLLayerCmd: "+drawable);
+ }
if( 0 != cmd.pbuffer ) {
CGL.setContextPBuffer(contextHandle, 0);
}
@@ -808,7 +830,11 @@ public abstract class MacOSXCGLContext extends GLContextImpl
cmd.valid = true; // skip pending creation
} else {
// All CALayer lifecycle ops are deferred on main-thread
- OSXUtil.RunOnMainThread(false, new DetachNSOpenGLLayer(cmd));
+ final DetachGLLayerCmd dCmd = new DetachGLLayerCmd(cmd);
+ if(DEBUG) {
+ System.err.println("MaxOSXCGLContext.NSOpenGLImpl.associateDrawable(false): "+dCmd);
+ }
+ OSXUtil.RunOnMainThread(false, dCmd);
if( null != gl3ShaderProgram ) {
gl3ShaderProgram.destroy(MacOSXCGLContext.this.gl.getGL3());
gl3ShaderProgram = null;
@@ -903,7 +929,7 @@ public abstract class MacOSXCGLContext extends GLContextImpl
@Override
public boolean setSwapInterval(int interval) {
- final AttachNSOpenGLLayer cmd = attachCALayerCmd;
+ final AttachGLLayerCmd cmd = attachGLLayerCmd;
if(null != cmd) {
synchronized(cmd) {
if( cmd.valid && 0 != cmd.nsOpenGLLayer) {
@@ -932,7 +958,7 @@ public abstract class MacOSXCGLContext extends GLContextImpl
@Override
public boolean swapBuffers() {
- final AttachNSOpenGLLayer cmd = attachCALayerCmd;
+ final AttachGLLayerCmd cmd = attachGLLayerCmd;
if(null != cmd) {
synchronized(cmd) {
if( cmd.valid && 0 != cmd.nsOpenGLLayer) {
diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
index a6c655915..de62747be 100644
--- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
+++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
@@ -40,7 +40,6 @@ import javax.media.nativewindow.CapabilitiesImmutable;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.NativeWindow;
import javax.media.nativewindow.NativeWindowException;
-import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.SurfaceUpdatedListener;
import javax.media.nativewindow.util.InsetsImmutable;
import javax.media.nativewindow.util.Point;
@@ -472,17 +471,16 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind
if( ( null != context ) ) {
throw new InternalError("GLWindow.LifecycleHook.setVisiblePost: "+WindowImpl.getThreadName()+" - Null drawable, but valid context - "+GLWindow.this);
}
- final NativeWindow nw;
- if (window.getWrappedWindow() != null) {
- nw = NativeWindowFactory.getNativeWindow(window.getWrappedWindow(), window.getPrivateGraphicsConfiguration());
- } else {
- nw = window;
+ final NativeSurface ns;
+ {
+ final NativeSurface wrapped_ns = window.getWrappedSurface();
+ ns = null != wrapped_ns ? wrapped_ns : window;
}
- final GLCapabilitiesImmutable glCaps = (GLCapabilitiesImmutable) nw.getGraphicsConfiguration().getChosenCapabilities();
+ final GLCapabilitiesImmutable glCaps = (GLCapabilitiesImmutable) ns.getGraphicsConfiguration().getChosenCapabilities();
if(null==factory) {
factory = GLDrawableFactory.getFactory(glCaps.getGLProfile());
}
- drawable = (GLDrawableImpl) factory.createGLDrawable(nw);
+ drawable = (GLDrawableImpl) factory.createGLDrawable(ns);
drawable.setRealized(true);
if( !GLWindow.this.pushGLEventListenerState() ) {
diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java
index 01a58a305..bfb450f68 100644
--- a/src/newt/classes/jogamp/newt/WindowImpl.java
+++ b/src/newt/classes/jogamp/newt/WindowImpl.java
@@ -1562,9 +1562,11 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
return old;
}
- /** If this Window actually wraps one from another toolkit such as
- the AWT, this will return a non-null value. */
- public Object getWrappedWindow() {
+ /**
+ * If this Window actually wraps a {@link NativeSurface} from another instance or toolkit,
+ * it will return such reference. Otherwise returns null.
+ */
+ public NativeSurface getWrappedSurface() {
return null;
}
@@ -1598,7 +1600,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
"\n, Visible "+isVisible()+", focus "+hasFocus()+
"\n, Undecorated "+undecorated+" ("+isUndecorated()+")"+
"\n, AlwaysOnTop "+alwaysOnTop+", Fullscreen "+fullscreen+
- "\n, WrappedWindow "+getWrappedWindow()+
+ "\n, WrappedSurface "+getWrappedSurface()+
"\n, ChildWindows "+childWindows.size());
sb.append(", SurfaceUpdatedListeners num "+surfaceUpdatedHelper.size()+" [");
diff --git a/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java b/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java
index 17eb6a2fb..9a1632130 100644
--- a/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java
+++ b/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java
@@ -47,13 +47,15 @@ import javax.media.nativewindow.AbstractGraphicsScreen;
import javax.media.nativewindow.CapabilitiesChooser;
import javax.media.nativewindow.CapabilitiesImmutable;
import javax.media.nativewindow.GraphicsConfigurationFactory;
+import javax.media.nativewindow.NativeWindow;
import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.VisualIDHolder;
-
import com.jogamp.nativewindow.awt.AWTGraphicsConfiguration;
import com.jogamp.nativewindow.awt.AWTGraphicsDevice;
import com.jogamp.nativewindow.awt.AWTGraphicsScreen;
+import com.jogamp.nativewindow.awt.JAWTWindow;
import com.jogamp.newt.Window;
@SuppressWarnings("serial")
@@ -61,17 +63,15 @@ public class AWTCanvas extends Canvas {
private GraphicsDevice device;
private GraphicsConfiguration chosen;
private AWTGraphicsConfiguration awtConfig;
-
- private WindowDriver newtWindowImpl;
+ private volatile JAWTWindow jawtWindow=null; // the JAWTWindow presentation of this AWT Canvas, bound to the 'drawable' lifecycle
private CapabilitiesChooser chooser=null;
private CapabilitiesImmutable capabilities;
private boolean displayConfigChanged=false;
- public AWTCanvas(WindowDriver newtWindowImpl, CapabilitiesImmutable capabilities, CapabilitiesChooser chooser) {
+ public AWTCanvas(CapabilitiesImmutable capabilities, CapabilitiesChooser chooser) {
super();
- this.newtWindowImpl = newtWindowImpl;
if(null==capabilities) {
throw new NativeWindowException("Capabilities null");
}
@@ -89,7 +89,7 @@ public class AWTCanvas extends Canvas {
*/
@Override
public void update(Graphics g) {
- paint(g);
+ // paint(g);
}
/** Overridden to cause OpenGL rendering to be performed during
@@ -99,7 +99,6 @@ public class AWTCanvas extends Canvas {
*/
@Override
public void paint(Graphics g) {
- newtWindowImpl.windowRepaint(0, 0, getWidth(), getHeight());
}
public boolean hasDeviceChanged() {
@@ -120,8 +119,7 @@ public class AWTCanvas extends Canvas {
*/
awtConfig = chooseGraphicsConfiguration(capabilities, capabilities, chooser, device);
if(Window.DEBUG_IMPLEMENTATION) {
- Exception e = new Exception("Info: Created Config: "+awtConfig);
- e.printStackTrace();
+ System.err.println(getThreadName()+": AWTCanvas.addNotify.0: Created Config: "+awtConfig);
}
if(null==awtConfig) {
throw new NativeWindowException("Error: NULL AWTGraphicsConfiguration");
@@ -137,12 +135,31 @@ public class AWTCanvas extends Canvas {
// after native peer is valid: Windows
disableBackgroundErase();
+ {
+ jawtWindow = (JAWTWindow) NativeWindowFactory.getNativeWindow(this, awtConfig);
+ // trigger initialization cycle
+ jawtWindow.lockSurface();
+ jawtWindow.unlockSurface();
+ }
+
GraphicsConfiguration gc = super.getGraphicsConfiguration();
if(null!=gc) {
device = gc.getDevice();
}
+ if(Window.DEBUG_IMPLEMENTATION) {
+ System.err.println(getThreadName()+": AWTCanvas.addNotify.X");
+ }
}
+ public NativeWindow getNativeWindow() {
+ final JAWTWindow _jawtWindow = jawtWindow;
+ return (null != _jawtWindow) ? _jawtWindow : null;
+ }
+
+ public boolean isOffscreenLayerSurfaceEnabled() {
+ return null != jawtWindow ? jawtWindow.isOffscreenLayerSurfaceEnabled() : false;
+ }
+
public void removeNotify() {
try {
dispose();
@@ -152,6 +169,13 @@ public class AWTCanvas extends Canvas {
}
private void dispose() {
+ if( null != jawtWindow ) {
+ jawtWindow.destroy();
+ if(Window.DEBUG_IMPLEMENTATION) {
+ System.err.println(getThreadName()+": AWTCanvas.disposeJAWTWindowAndAWTDeviceOnEDT(): post JAWTWindow: "+jawtWindow);
+ }
+ jawtWindow=null;
+ }
if(null != awtConfig) {
AbstractGraphicsDevice adevice = awtConfig.getNativeGraphicsConfiguration().getScreen().getDevice();
String adeviceMsg=null;
@@ -160,10 +184,12 @@ public class AWTCanvas extends Canvas {
}
boolean closed = adevice.close();
if(Window.DEBUG_IMPLEMENTATION) {
- System.err.println("AWTCanvas.dispose(): closed GraphicsDevice: "+adeviceMsg+", result: "+closed);
+ System.err.println(getThreadName()+": AWTCanvas.dispose(): closed GraphicsDevice: "+adeviceMsg+", result: "+closed);
}
}
}
+
+ private String getThreadName() { return Thread.currentThread().getName(); }
/**
* Overridden to choose a GraphicsConfiguration on a parent container's
diff --git a/src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java
index 0172309fb..c45a5ae3b 100644
--- a/src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java
@@ -40,11 +40,15 @@ import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Insets;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindow;
import javax.media.nativewindow.NativeWindowException;
import javax.media.nativewindow.util.Point;
+import jogamp.nativewindow.awt.AWTMisc;
import jogamp.newt.WindowImpl;
+import com.jogamp.common.os.Platform;
import com.jogamp.nativewindow.awt.AWTGraphicsConfiguration;
import com.jogamp.nativewindow.awt.AWTGraphicsDevice;
import com.jogamp.nativewindow.awt.AWTGraphicsScreen;
@@ -70,25 +74,26 @@ public class WindowDriver extends WindowImpl {
public WindowDriver(Container container) {
super();
- this.container = container;
+ this.awtContainer = container;
if(container instanceof Frame) {
- frame = (Frame) container;
+ awtFrame = (Frame) container;
}
}
private boolean owningFrame;
- private Container container = null;
- private Frame frame = null; // same instance as container, just for impl. convenience
- private AWTCanvas canvas;
+ private Container awtContainer = null;
+ /** same instance as container, just for impl. convenience */
+ private Frame awtFrame = null;
+ private AWTCanvas awtCanvas;
protected void requestFocusImpl(boolean reparented) {
- container.requestFocus();
+ awtContainer.requestFocus();
}
@Override
protected void setTitleImpl(final String title) {
- if (frame != null) {
- frame.setTitle(title);
+ if (awtFrame != null) {
+ awtFrame.setTitle(title);
}
}
@@ -97,58 +102,66 @@ public class WindowDriver extends WindowImpl {
throw new RuntimeException("Window parenting not supported in AWT, use AWTWindow(Frame) cstr for wrapping instead");
}
- if(null==container) {
- frame = new Frame();
- container = frame;
+ if(null==awtContainer) {
+ awtFrame = new Frame();
+ awtContainer = awtFrame;
owningFrame=true;
} else {
owningFrame=false;
- defineSize(container.getWidth(), container.getHeight());
- definePosition(container.getX(), container.getY());
+ defineSize(awtContainer.getWidth(), awtContainer.getHeight());
+ definePosition(awtContainer.getX(), awtContainer.getY());
}
- if(null!=frame) {
- frame.setTitle(getTitle());
+ if(null!=awtFrame) {
+ awtFrame.setTitle(getTitle());
}
- container.setLayout(new BorderLayout());
+ awtContainer.setLayout(new BorderLayout());
- canvas = new AWTCanvas(this, capsRequested, WindowDriver.this.capabilitiesChooser);
+ if( null == awtCanvas ) {
+ awtCanvas = new AWTCanvas(capsRequested, WindowDriver.this.capabilitiesChooser);
- // canvas.addComponentListener(listener);
- container.add(canvas, BorderLayout.CENTER);
+ // canvas.addComponentListener(listener);
+ awtContainer.add(awtCanvas, BorderLayout.CENTER);
- // via EDT ..
- new AWTMouseAdapter(this).addTo(canvas); // fwd all AWT Mouse events to here
- new AWTKeyAdapter(this).addTo(canvas); // fwd all AWT Key events to here
+ // 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(canvas); // fwd all AWT Window events to here
+ // direct w/o EDT
+ new AWTWindowAdapter(new LocalWindowListener(), this).addTo(awtCanvas); // fwd all AWT Window events to here
+ }
reconfigureWindowImpl(getX(), getY(), getWidth(), getHeight(), getReconfigureFlags(FLAG_CHANGE_VISIBILITY | FLAG_CHANGE_DECORATION, true));
// throws exception if failed ..
- setWindowHandle(1); // just a marker ..
+ final NativeWindow nw = awtCanvas.getNativeWindow();
+ if( null != nw ) {
+ setGraphicsConfiguration( awtCanvas.getAWTGraphicsConfiguration() );
+ setWindowHandle( nw.getWindowHandle() );
+ }
}
protected void closeNativeImpl() {
- setWindowHandle(0); // just a marker ..
- if(null!=container) {
- container.setVisible(false);
- container.remove(canvas);
- container.setEnabled(false);
- canvas.setEnabled(false);
+ setWindowHandle(0);
+ if(null!=awtContainer) {
+ awtContainer.setVisible(false);
+ awtContainer.remove(awtCanvas);
+ awtContainer.setEnabled(false);
+ awtCanvas.setEnabled(false);
}
- if(owningFrame && null!=frame) {
- frame.dispose();
+ if(owningFrame && null!=awtFrame) {
+ awtFrame.dispose();
owningFrame=false;
- frame = null;
}
+ awtCanvas = null;
+ awtFrame = null;
+ awtContainer = null;
}
@Override
public boolean hasDeviceChanged() {
- boolean res = canvas.hasDeviceChanged();
+ boolean res = awtCanvas.hasDeviceChanged();
if(res) {
- final AWTGraphicsConfiguration cfg = canvas.getAWTGraphicsConfiguration();
+ final AWTGraphicsConfiguration cfg = awtCanvas.getAWTGraphicsConfiguration();
if (null == cfg) {
throw new NativeWindowException("Error Device change null GraphicsConfiguration: "+this);
}
@@ -164,17 +177,54 @@ public class WindowDriver extends WindowImpl {
}
protected void updateInsetsImpl(javax.media.nativewindow.util.Insets insets) {
- Insets contInsets = container.getInsets();
+ Insets contInsets = awtContainer.getInsets();
insets.setLeftWidth(contInsets.left);
insets.setRightWidth(contInsets.right);
insets.setTopHeight(contInsets.top);
insets.setBottomHeight(contInsets.bottom);
}
+ private void setCanvasSizeImpl(int width, int height) {
+ final Dimension szClient = new Dimension(width, height);
+ final java.awt.Window awtWindow = AWTMisc.getWindow(awtCanvas);
+ final Container c= null != awtWindow ? awtWindow : awtContainer;
+ awtCanvas.setMinimumSize(szClient);
+ awtCanvas.setPreferredSize(szClient);
+ if(DEBUG_IMPLEMENTATION) {
+ final Insets insets = c.getInsets();
+ final Dimension szContainer = new Dimension(width + insets.left + insets.right,
+ height + insets.top + insets.bottom);
+ System.err.println(getThreadName()+": AWTWindow setCanvasSize: szClient "+szClient+", szCont "+szContainer+", insets "+insets);
+ }
+ awtCanvas.setSize(szClient);
+ awtCanvas.invalidate();
+ if(null != awtWindow) {
+ awtWindow.pack();
+ } else {
+ awtContainer.validate();
+ }
+ }
+ private void setFrameSizeImpl(int width, int height) {
+ final Insets insets = awtContainer.getInsets();
+ final Dimension szContainer = new Dimension(width + insets.left + insets.right,
+ height + insets.top + insets.bottom);
+ if(DEBUG_IMPLEMENTATION) {
+ final Dimension szClient = new Dimension(width, height);
+ System.err.println(getThreadName()+": AWTWindow setFrameSize: szClient "+szClient+", szCont "+szContainer+", insets "+insets);
+ }
+ awtContainer.setSize(szContainer);
+ awtCanvas.invalidate();
+ awtContainer.validate();
+ }
+
protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) {
- if(0 != ( FLAG_CHANGE_DECORATION & flags) && null!=frame) {
- if(!container.isDisplayable()) {
- frame.setUndecorated(isUndecorated());
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("AWTWindow reconfig: "+x+"/"+y+" "+width+"x"+height+", "+
+ getReconfigureFlagsAsString(null, flags));
+ }
+ if(0 != ( FLAG_CHANGE_DECORATION & flags) && null!=awtFrame) {
+ if(!awtContainer.isDisplayable()) {
+ awtFrame.setUndecorated(isUndecorated());
} else {
if(DEBUG_IMPLEMENTATION) {
System.err.println(getThreadName()+": AWTWindow can't undecorate already created frame");
@@ -182,32 +232,31 @@ public class WindowDriver extends WindowImpl {
}
}
- final Dimension szClient = new Dimension(width, height);
- canvas.setMinimumSize(szClient);
- canvas.setPreferredSize(szClient);
- canvas.setSize(szClient);
- if(DEBUG_IMPLEMENTATION) {
- final Insets insets = container.getInsets();
- final Dimension szContainer = new Dimension(width + insets.left + insets.right,
- height + insets.top + insets.bottom);
- System.err.println(getThreadName()+": AWTWindow new size: szClient "+szClient+", szCont "+szContainer+", insets "+insets);
- }
-
if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) {
- if(null != frame) {
- frame.pack();
+ if( 0 != ( FLAG_IS_VISIBLE & flags) ) {
+ setCanvasSizeImpl(width, height);
+ awtContainer.setVisible( true );
+ } else {
+ awtContainer.setVisible( false );
+ }
+ } else if( awtCanvas.getWidth() != width || awtCanvas.getHeight() != height ) {
+ if( Platform.OSType.MACOS == Platform.getOSType() && awtCanvas.isOffscreenLayerSurfaceEnabled() ) {
+ setFrameSizeImpl(width, height);
+ } else {
+ setCanvasSizeImpl(width, height);
}
- container.validate();
- container.setVisible(0 != ( FLAG_IS_VISIBLE & flags));
}
+ defineSize(width, height); // we are on AWT-EDT .. change values immediately
- container.setLocation(x, y);
+ if( awtContainer.getX() != x || awtContainer.getY() != y ) {
+ awtContainer.setLocation(x, y);
+ }
if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) {
if( 0 != ( FLAG_IS_VISIBLE & flags ) ) {
if( !hasDeviceChanged() ) {
// oops ??
- final AWTGraphicsConfiguration cfg = canvas.getAWTGraphicsConfiguration();
+ final AWTGraphicsConfiguration cfg = awtCanvas.getAWTGraphicsConfiguration();
if(null == cfg) {
throw new NativeWindowException("Error: !hasDeviceChanged && null == GraphicsConfiguration: "+this);
}
@@ -215,39 +264,37 @@ public class WindowDriver extends WindowImpl {
}
}
visibleChanged(false, 0 != ( FLAG_IS_VISIBLE & flags));
- } else {
- container.invalidate();
- if(null != frame) {
- frame.pack();
- }
- container.validate();
}
return true;
}
protected Point getLocationOnScreenImpl(int x, int y) {
- java.awt.Point ap = canvas.getLocationOnScreen();
+ java.awt.Point ap = awtCanvas.getLocationOnScreen();
ap.translate(x, y);
return new Point((int)(ap.getX()+0.5),(int)(ap.getY()+0.5));
}
@Override
- public Object getWrappedWindow() {
- return canvas;
+ public NativeSurface getWrappedSurface() {
+ return ( null != awtCanvas ) ? awtCanvas.getNativeWindow() : null;
}
class LocalWindowListener implements com.jogamp.newt.event.WindowListener {
@Override
public void windowMoved(com.jogamp.newt.event.WindowEvent e) {
- if(null!=container) {
- WindowDriver.this.positionChanged(false, container.getX(), container.getY());
+ if(null!=awtContainer) {
+ WindowDriver.this.positionChanged(false, awtContainer.getX(), awtContainer.getY());
}
}
@Override
public void windowResized(com.jogamp.newt.event.WindowEvent e) {
- if(null!=canvas) {
- WindowDriver.this.sizeChanged(false, canvas.getWidth(), canvas.getHeight(), false);
+ if(null!=awtCanvas) {
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window Resized: "+awtCanvas);
+ }
+ WindowDriver.this.sizeChanged(false, awtCanvas.getWidth(), awtCanvas.getHeight(), true);
+ WindowDriver.this.windowRepaint(false, 0, 0, getWidth(), getHeight());
}
}
@Override
@@ -268,7 +315,12 @@ public class WindowDriver extends WindowImpl {
}
@Override
public void windowRepaint(WindowUpdateEvent e) {
- WindowDriver.this.windowRepaint(false, 0, 0, getWidth(), getHeight());
+ if(null!=awtCanvas) {
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window Repaint: "+awtCanvas);
+ }
+ WindowDriver.this.windowRepaint(false, 0, 0, getWidth(), getHeight());
+ }
}
}
}
diff --git a/src/test-native/displayMultiple02_mch.c b/src/test-native/displayMultiple02_mch.c
new file mode 100644
index 000000000..c2ab25fbb
--- /dev/null
+++ b/src/test-native/displayMultiple02_mch.c
@@ -0,0 +1,130 @@
+/**
+ * compile with: gcc -o displayMultiple02 displayMultiple02.c -lX11 -lGL
+ */
+
+#include <stdio.h>
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <GL/glx.h>
+#include <GL/gl.h>
+
+static void testOrder(int reverseDestroyOrder, const char * msg);
+
+static int useXLockDisplay = 0;
+
+int main(int nargs, char **vargs) {
+ int arg=1;
+ while(arg<nargs) {
+ if(0 == strcmp(vargs[arg], "-xlock")) {
+ useXLockDisplay = 1;
+ }
+ arg++;
+ }
+ fprintf(stderr, "-xlock (XLockDisplay): %d\n", useXLockDisplay);
+
+ if( useXLockDisplay ) {
+ XInitThreads();
+ }
+ testOrder(0, "Normal order");
+ testOrder(1, "Reverse order");
+ return 0;
+}
+
+static void createGLWin(Display *dpy, int width, int height, Window *rWin, GLXContext *rCtx);
+static void useGL(Display *dpy, Window win, GLXContext ctx, int width, int height);
+
+static void XLOCKDISPLAY(Display *dpy) {
+ if( useXLockDisplay ) {
+ XLockDisplay(dpy);
+ }
+}
+static void XUNLOCKDISPLAY(Display *dpy) {
+ if( useXLockDisplay ) {
+ XUnlockDisplay(dpy);
+ }
+}
+
+void testOrder(int reverseDestroyOrder, const char * msg) {
+ int major, minor;
+ Display *disp1;
+ Window win1;
+ GLXContext ctx1;
+
+ fprintf(stderr, "%s: Create #1\n", msg);
+ disp1 = XOpenDisplay(NULL);
+ XLOCKDISPLAY(disp1);
+ createGLWin(disp1, 200, 200, &win1, &ctx1);
+ useGL(disp1, win1, ctx1, 200, 200);
+ XUNLOCKDISPLAY(disp1);
+
+ if(reverseDestroyOrder) {
+ fprintf(stderr, "%s: Destroy #1.0\n", msg);
+ XLOCKDISPLAY(disp1);
+ fprintf(stderr, "%s: Destroy #1.1\n", msg);
+ glXMakeCurrent(disp1, 0, 0);
+ fprintf(stderr, "%s: Destroy #1.2\n", msg);
+ glXDestroyContext(disp1, ctx1);
+ fprintf(stderr, "%s: Destroy #1.3\n", msg);
+ XUNLOCKDISPLAY(disp1);
+ fprintf(stderr, "%s: Destroy #1.4\n", msg);
+ XCloseDisplay(disp1);
+ fprintf(stderr, "%s: Destroy #1.X\n", msg);
+ } else {
+ fprintf(stderr, "%s: Destroy #1.0\n", msg);
+ XLOCKDISPLAY(disp1);
+ glXMakeCurrent(disp1, 0, 0);
+ glXDestroyContext(disp1, ctx1);
+ XUNLOCKDISPLAY(disp1);
+ XCloseDisplay(disp1);
+ fprintf(stderr, "%s: Destroy #1.X\n", msg);
+ }
+
+ fprintf(stderr, "%s: Success - no bug\n", msg);
+}
+
+/* attributes for a double buffered visual in RGBA format with at least
+ * 4 bits per color and a 16 bit depth buffer */
+static int attrListDbl[] = { GLX_RGBA, GLX_DOUBLEBUFFER,
+ GLX_RED_SIZE, 4,
+ GLX_GREEN_SIZE, 4,
+ GLX_BLUE_SIZE, 4,
+ GLX_DEPTH_SIZE, 16,
+ None };
+
+void createGLWin(Display *dpy, int width, int height, Window *rWin, GLXContext *rCtx)
+{
+ int screen = DefaultScreen(dpy);
+ XVisualInfo *vi = glXChooseVisual(dpy, screen, attrListDbl);
+ Colormap cmap;
+ XSetWindowAttributes attr;
+
+ /* create a GLX context */
+ *rCtx = glXCreateContext(dpy, vi, 0, GL_TRUE);
+ /* create a color map */
+ cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual, AllocNone);
+ attr.colormap = cmap;
+ attr.border_pixel = 0;
+
+ /* create a window in window mode*/
+ attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask |
+ StructureNotifyMask;
+ *rWin = XCreateWindow(dpy, RootWindow(dpy, vi->screen),
+ 0, 0, width, height, 0, vi->depth, InputOutput, vi->visual,
+ CWBorderPixel | CWColormap | CWEventMask, &attr);
+
+ XMapRaised(dpy, *rWin);
+}
+
+void useGL(Display *dpy, Window win, GLXContext ctx, int width, int height)
+{
+ glXMakeCurrent(dpy, win, ctx);
+ glShadeModel(GL_SMOOTH);
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ glClearDepth(1.0f);
+ glViewport(0, 0, width, height);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glXSwapBuffers(dpy, win);
+ glXMakeCurrent(dpy, 0, 0);
+}
+
diff --git a/src/test-native/displayMultiple02_new_mch.c b/src/test-native/displayMultiple02_new_mch.c
new file mode 100644
index 000000000..f64d41472
--- /dev/null
+++ b/src/test-native/displayMultiple02_new_mch.c
@@ -0,0 +1,199 @@
+/**
+ * compile with: gcc -o displayMultiple02 displayMultiple02.c -lX11 -lGL
+ */
+
+#include <stdio.h>
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <GL/glx.h>
+#include <GL/gl.h>
+
+static void testOrder(int reverseDestroyOrder, const char * msg);
+
+static int useXLockDisplay = 0;
+
+int main(int nargs, char **vargs) {
+ int arg=1;
+ while(arg<nargs) {
+ if(0 == strcmp(vargs[arg], "-xlock")) {
+ useXLockDisplay = 1;
+ }
+ arg++;
+ }
+ fprintf(stderr, "-xlock (XLockDisplay): %d\n", useXLockDisplay);
+
+ if( useXLockDisplay ) {
+ XInitThreads();
+ }
+ testOrder(0, "Normal order");
+ testOrder(1, "Reverse order");
+ return 0;
+}
+
+static void createGLWin(Display *dpy, int width, int height, Window *rWin, GLXContext *rCtx);
+static void createGLWinNew(Display *dpy, int width, int height, Window *rWin, GLXContext *rCtx);
+static void useGL(Display *dpy, Window win, GLXContext ctx, int width, int height);
+
+static void XLOCKDISPLAY(Display *dpy) {
+ if( useXLockDisplay ) {
+ XLockDisplay(dpy);
+ }
+}
+static void XUNLOCKDISPLAY(Display *dpy) {
+ if( useXLockDisplay ) {
+ XUnlockDisplay(dpy);
+ }
+}
+
+void testOrder(int reverseDestroyOrder, const char * msg) {
+ int major, minor;
+ Display *disp1;
+ Window win1;
+ GLXContext ctx1;
+
+ Display *disp2;
+ Window win2;
+ GLXContext ctx2;
+
+ fprintf(stderr, "%s: Create #1\n", msg);
+ disp1 = XOpenDisplay(NULL);
+ XLOCKDISPLAY(disp1);
+ createGLWinNew(disp1, 200, 200, &win1, &ctx1);
+ useGL(disp1, win1, ctx1, 200, 200);
+ XUNLOCKDISPLAY(disp1);
+
+ fprintf(stderr, "%s: Create #2\n", msg);
+ disp2 = XOpenDisplay(NULL);
+ XLOCKDISPLAY(disp2);
+ createGLWinNew(disp2, 300, 300, &win2, &ctx2);
+ useGL(disp2, win2, ctx2, 300, 300);
+ XUNLOCKDISPLAY(disp2);
+
+ if(reverseDestroyOrder) {
+ fprintf(stderr, "%s: Destroy #2.0\n", msg);
+ XLOCKDISPLAY(disp2);
+ glXMakeCurrent(disp2, 0, 0);
+ glXDestroyContext(disp2, ctx2);
+ XUNLOCKDISPLAY(disp2);
+ XCloseDisplay(disp2);
+ fprintf(stderr, "%s: Destroy #2.X\n", msg);
+
+ fprintf(stderr, "%s: Destroy #1.0\n", msg);
+ XLOCKDISPLAY(disp1);
+ fprintf(stderr, "%s: Destroy #1.1\n", msg);
+ glXMakeCurrent(disp1, 0, 0);
+ fprintf(stderr, "%s: Destroy #1.2\n", msg);
+ glXDestroyContext(disp1, ctx1);
+ fprintf(stderr, "%s: Destroy #1.3\n", msg);
+ XUNLOCKDISPLAY(disp1);
+ fprintf(stderr, "%s: Destroy #1.4\n", msg);
+ XCloseDisplay(disp1);
+ fprintf(stderr, "%s: Destroy #1.X\n", msg);
+ } else {
+ fprintf(stderr, "%s: Destroy #1.0\n", msg);
+ XLOCKDISPLAY(disp1);
+ glXMakeCurrent(disp1, 0, 0);
+ glXDestroyContext(disp1, ctx1);
+ XUNLOCKDISPLAY(disp1);
+ XCloseDisplay(disp1);
+ fprintf(stderr, "%s: Destroy #1.X\n", msg);
+
+ fprintf(stderr, "%s: Destroy #2.0\n", msg);
+ XLOCKDISPLAY(disp2);
+ fprintf(stderr, "%s: Destroy #2.1\n", msg);
+ glXMakeCurrent(disp2, 0, 0);
+ fprintf(stderr, "%s: Destroy #2.2\n", msg);
+ glXDestroyContext(disp2, ctx2);
+ fprintf(stderr, "%s: Destroy #2.3\n", msg);
+ XUNLOCKDISPLAY(disp2);
+ fprintf(stderr, "%s: Destroy #2.4\n", msg);
+ XCloseDisplay(disp2);
+ fprintf(stderr, "%s: Destroy #2.X\n", msg);
+ }
+
+ fprintf(stderr, "%s: Success - no bug\n", msg);
+}
+
+/* attributes for a double buffered visual in RGBA format with at least
+ * 4 bits per color and a 16 bit depth buffer */
+static int attrListDbl[] = { GLX_RGBA, GLX_DOUBLEBUFFER,
+ GLX_RED_SIZE, 4,
+ GLX_GREEN_SIZE, 4,
+ GLX_BLUE_SIZE, 4,
+ GLX_DEPTH_SIZE, 16,
+ None };
+static int attrListDblNew[] = { GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
+ GLX_RENDER_TYPE, GLX_RGBA_BIT,
+ GLX_DOUBLEBUFFER, True,
+ GLX_BUFFER_SIZE, 24,
+ GLX_DEPTH_SIZE, 24,
+ None };
+
+void createGLWin(Display *dpy, int width, int height, Window *rWin, GLXContext *rCtx)
+{
+ int screen = DefaultScreen(dpy);
+ XVisualInfo *vi = glXChooseVisual(dpy, screen, attrListDbl);
+ Colormap cmap;
+ XSetWindowAttributes attr;
+
+ /* create a GLX context */
+ *rCtx = glXCreateContext(dpy, vi, 0, GL_TRUE);
+ /* create a color map */
+ cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual, AllocNone);
+ attr.colormap = cmap;
+ attr.border_pixel = 0;
+
+ /* create a window in window mode*/
+ attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask |
+ StructureNotifyMask;
+ *rWin = XCreateWindow(dpy, RootWindow(dpy, vi->screen),
+ 0, 0, width, height, 0, vi->depth, InputOutput, vi->visual,
+ CWBorderPixel | CWColormap | CWEventMask, &attr);
+
+ XMapRaised(dpy, *rWin);
+}
+
+void createGLWinNew(Display *dpy, int width, int height, Window *rWin, GLXContext *rCtx)
+{
+ int screen = DefaultScreen(dpy);
+ Colormap cmap;
+ XSetWindowAttributes attr;
+
+ // create configs
+ int nelements;
+ GLXFBConfig *fbconfigs = glXChooseFBConfig(dpy,screen,attrListDblNew,&nelements );
+
+ // get visual
+ XVisualInfo *vi = glXGetVisualFromFBConfig(dpy,*fbconfigs);
+
+ /* create a GLX context */
+ *rCtx = glXCreateNewContext(dpy, *fbconfigs, GLX_RGBA_TYPE, 0, GL_TRUE);
+
+ /* create a color map */
+ cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual, AllocNone);
+ attr.colormap = cmap;
+ attr.border_pixel = 0;
+
+ /* create a window in window mode*/
+ attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask |
+ StructureNotifyMask;
+ *rWin = XCreateWindow(dpy, RootWindow(dpy, vi->screen),
+ 0, 0, width, height, 0, vi->depth, InputOutput, vi->visual,
+ CWBorderPixel | CWColormap | CWEventMask, &attr);
+
+ XMapRaised(dpy, *rWin);
+}
+
+void useGL(Display *dpy, Window win, GLXContext ctx, int width, int height)
+{
+ glXMakeCurrent(dpy, win, ctx);
+ glShadeModel(GL_SMOOTH);
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ glClearDepth(1.0f);
+ glViewport(0, 0, width, height);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glXSwapBuffers(dpy, win);
+ glXMakeCurrent(dpy, 0, 0);
+}
+
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestBug692GL3VAO.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestBug692GL3VAO.java
new file mode 100644
index 000000000..95944cd98
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestBug692GL3VAO.java
@@ -0,0 +1,352 @@
+/**
+ * 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.acore;
+
+import java.io.IOException;
+import java.nio.FloatBuffer;
+import java.nio.ShortBuffer;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.media.opengl.DebugGL3;
+import javax.media.opengl.GL3;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLProfile;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+
+import com.jogamp.common.nio.Buffers;
+import com.jogamp.newt.opengl.GLWindow;
+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.GLBuffers;
+
+/**
+ * Test Vertex Array Object (VAO) Usage.
+ * <p>
+ * testGL3() tests VAO alone, i.e. w/o VBO enable/disabling.
+ * </p>
+ * <p>
+ * testGL3bc() tests VAO and VBO while alternating between both methods.
+ * </p>
+ */
+public class TestBug692GL3VAO extends UITestCase {
+ static long duration = 500; // ms
+
+ static class GL3VAODemo implements GLEventListener {
+ /** Different modes of displaying the geometry */
+ public enum Mode {
+ /** Traditional one without using VAO */
+ NON_VAO {
+ @Override
+ void display(GL3VAODemo t, GL3 gl) {
+ t.displayNonVAO(gl);
+ }
+ },
+
+ /** Using VAOs throws [incorrectly as of JOGL 2.0rc11] a GLException */
+ VAO_NORMAL {
+ @Override
+ void display(GL3VAODemo t, GL3 gl) {
+ t.displayVAONormal(gl);
+ }
+ };
+
+ abstract void display(GL3VAODemo t, GL3 gl);
+ }
+
+ private final Mode[] allModes;
+ private Mode currentMode;
+ private int currentModeIdx;
+
+ public GL3VAODemo(Mode[] modes) {
+ allModes = modes;
+ currentMode = allModes[0];
+ currentModeIdx = 0;
+ }
+
+ private final static float[] vertexData = new float[]{
+ 0.0f, 0.75f, 0.0f, 1,0,0,
+ -0.5f, -0.75f, 0.0f, 0,1,0,
+ 0.9f, -0.75f, 0.0f, 0,0,1
+ };
+
+ private int ibo = -1;
+ private int vbo = -1;
+ private int vertID = -1;
+ private int fragID = -1;
+ private int progID = -1;
+
+ private int vaoNormal = -1;
+
+ private static int createShader(final GL3 gl, int type,
+ final String[] srcLines){
+ int shaderID = gl.glCreateShader(type);
+ assert shaderID > 0;
+ int[] lengths = new int[srcLines.length];
+ for (int i = 0; i < srcLines.length; i++) {
+ lengths[i] = srcLines[i].length();
+ }
+ gl.glShaderSource(shaderID, srcLines.length, srcLines, lengths, 0);
+ gl.glCompileShader(shaderID);
+ return shaderID;
+ }
+
+ private void initBuffers(GL3 gl) {
+ // IDs for 2 buffers
+ int[] buffArray = new int[2];
+ gl.glGenBuffers(buffArray.length, buffArray, 0);
+ vbo = buffArray[0];
+ assert vbo > 0;
+
+ // Bind buffer and upload data
+ gl.glBindBuffer(GL3.GL_ARRAY_BUFFER, vbo);
+ FloatBuffer buffer = GLBuffers.newDirectFloatBuffer(vertexData);
+ assert buffer.remaining() == vertexData.length;
+ gl.glBufferData(GL3.GL_ARRAY_BUFFER, vertexData.length * Buffers.SIZEOF_FLOAT,
+ buffer, GL3.GL_STATIC_DRAW);
+ gl.glBindBuffer(GL3.GL_ARRAY_BUFFER, 0);
+
+ // Buffer with the 3 indices required for one triangle
+ ibo = buffArray[1];
+ assert ibo > 0;
+ final short[] indices = new short[]{0, 1, 2};
+ ShortBuffer shortBuffer = GLBuffers.newDirectShortBuffer(indices);
+ assert shortBuffer.remaining() == indices.length;
+ gl.glBindBuffer(GL3.GL_ELEMENT_ARRAY_BUFFER, ibo);
+ gl.glBufferData(GL3.GL_ELEMENT_ARRAY_BUFFER,indices.length*Buffers.SIZEOF_SHORT,
+ shortBuffer, GL3.GL_STATIC_DRAW);
+ gl.glBindBuffer(GL3.GL_ELEMENT_ARRAY_BUFFER, 0);
+ }
+ private void initShaders(GL3 gl) {
+ final String[] vertSrc = new String[]{
+ "#version 150 core\n",
+ "in vec4 vPosition;\n",
+ "in vec4 vColor;\n",
+ "out vec4 pColor;\n",
+ "void main() {\n",
+ " pColor = vColor;\n",
+ " gl_Position = vPosition;\n",
+ "}\n"
+ };
+ vertID = createShader(gl, GL3.GL_VERTEX_SHADER, vertSrc);
+
+ final String[] fragSrc = new String[]{
+ "#version 150 core\n",
+ "in vec4 pColor;\n",
+ "void main() {\n",
+ " gl_FragColor = pColor;\n",
+ "}\n"
+ };
+ fragID = createShader(gl, GL3.GL_FRAGMENT_SHADER, fragSrc);
+
+ // We're done with the compiler
+ gl.glReleaseShaderCompiler();
+
+ progID = gl.glCreateProgram();
+ assert progID > 0;
+ gl.glAttachShader(progID, vertID);
+ gl.glAttachShader(progID, fragID);
+ gl.glLinkProgram(progID);
+ gl.glValidateProgram(progID);
+ }
+
+ private int initVAO(GL3 gl) {
+ int[] buff = new int[1];
+ gl.glGenVertexArrays(1, buff, 0);
+ int vao = buff[0];
+ Assert.assertTrue("Invalid VAO: "+vao, vao > 0);
+
+
+ gl.glUseProgram(progID);
+ final int posLoc = gl.glGetAttribLocation(progID, "vPosition");
+ final int colorLoc = gl.glGetAttribLocation(progID, "vColor");
+ gl.glUseProgram(0);
+
+ gl.glBindVertexArray(vao);
+ gl.glBindBuffer(GL3.GL_ARRAY_BUFFER, vbo);
+ gl.glBindBuffer(GL3.GL_ELEMENT_ARRAY_BUFFER, ibo);
+
+ gl.glEnableVertexAttribArray(posLoc);
+ gl.glEnableVertexAttribArray(colorLoc);
+
+ final int stride = 6 * Buffers.SIZEOF_FLOAT;
+ final int cOff = 3 * Buffers.SIZEOF_FLOAT;
+ gl.glVertexAttribPointer(posLoc, 3, GL3.GL_FLOAT, false, stride, 0L);
+ gl.glVertexAttribPointer(colorLoc,3, GL3.GL_FLOAT, false, stride, cOff);
+
+ gl.glBindVertexArray(0);
+ return vao;
+ }
+
+ @Override
+ public void init(GLAutoDrawable drawable) {
+ drawable.setGL(new DebugGL3(drawable.getGL().getGL3()));
+
+ final GL3 gl = drawable.getGL().getGL3();
+ gl.glEnable(GL3.GL_DEPTH_TEST);
+ gl.glDisable(GL3.GL_CULL_FACE);
+ initBuffers(gl);
+ initShaders(gl);
+
+ vaoNormal = initVAO(gl);
+
+ gl.setSwapInterval(1);
+ }
+
+ @Override
+ public void dispose(GLAutoDrawable drawable) {
+ final GL3 gl = drawable.getGL().getGL3();
+ gl.glDeleteBuffers(2, new int[]{vbo, ibo}, 0);
+ gl.glDetachShader(progID, fragID);
+ gl.glDetachShader(progID, vertID);
+ gl.glDeleteProgram(progID);
+ gl.glDeleteShader(fragID);
+ gl.glDeleteShader(vertID);
+ }
+
+ private void displayNonVAO(final GL3 gl) {
+ final int posLoc = gl.glGetAttribLocation(progID, "vPosition");
+ final int colorLoc = gl.glGetAttribLocation(progID, "vColor");
+ gl.glEnableVertexAttribArray(posLoc);
+ gl.glEnableVertexAttribArray(colorLoc);
+
+ gl.glBindBuffer(GL3.GL_ARRAY_BUFFER, vbo);
+ final int stride = 6 * Buffers.SIZEOF_FLOAT;
+ final int cOff = 3 * Buffers.SIZEOF_FLOAT;
+ gl.glVertexAttribPointer(posLoc, 3, GL3.GL_FLOAT, false, stride, 0L);
+ gl.glVertexAttribPointer(colorLoc,3, GL3.GL_FLOAT, false, stride, cOff);
+ gl.glBindBuffer(GL3.GL_ELEMENT_ARRAY_BUFFER, ibo);
+ gl.glDrawElements(GL3.GL_TRIANGLES, 3, GL3.GL_UNSIGNED_SHORT, 0L);
+
+ gl.glDisableVertexAttribArray(posLoc);
+ gl.glDisableVertexAttribArray(colorLoc);
+ gl.glBindBuffer(GL3.GL_ARRAY_BUFFER, 0);
+ gl.glBindBuffer(GL3.GL_ELEMENT_ARRAY_BUFFER, 0);
+ }
+
+ private void displayVAONormal(final GL3 gl) {
+ try {
+ gl.glBindVertexArray(vaoNormal);
+ gl.glDrawElements(GL3.GL_TRIANGLES, 3, GL3.GL_UNSIGNED_SHORT, 0L);
+ gl.glBindVertexArray(0);
+ } catch (GLException ex) {
+ Logger.getLogger(TestBug692GL3VAO.class.getName()).log(Level.SEVERE,null,ex);
+ }
+ }
+
+ @Override
+ public void display(GLAutoDrawable drawable) {
+ final GL3 gl = drawable.getGL().getGL3();
+ float color = ((float) currentMode.ordinal() + 1) / (Mode.values().length + 2);
+ gl.glClearColor(color, color, color, 0);
+ gl.glClear(GL3.GL_COLOR_BUFFER_BIT | GL3.GL_DEPTH_BUFFER_BIT);
+ gl.glUseProgram(progID);
+ final Mode newMode;
+ {
+ currentModeIdx = ( currentModeIdx + 1 ) % allModes.length;
+ newMode = allModes[ currentModeIdx ];
+ }
+ if (newMode != currentMode) {
+ currentMode = newMode;
+ System.out.println("Display mode: " + currentMode);
+ }
+ currentMode.display(this, gl);
+ gl.glUseProgram(0);
+ }
+
+ @Override
+ public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h) {
+ }
+ }
+
+ private void testImpl(GLProfile profile, GL3VAODemo.Mode[] modes) throws InterruptedException {
+ final GLCapabilities capabilities = new GLCapabilities(profile);
+ final GLWindow glWindow = GLWindow.create(capabilities);
+ glWindow.setSize(512, 512);
+
+ Animator anim = new Animator(glWindow);
+
+ QuitAdapter quitAdapter = new QuitAdapter();
+ glWindow.addKeyListener(quitAdapter);
+ glWindow.addWindowListener(quitAdapter);
+
+ final GL3VAODemo vaoTest = new GL3VAODemo(modes);
+ glWindow.addGLEventListener(vaoTest);
+ glWindow.setVisible(true);
+ anim.start();
+
+ final long t0 = System.currentTimeMillis();
+ long t1 = t0;
+ while(!quitAdapter.shouldQuit() && t1-t0<duration) {
+ Thread.sleep(100);
+ t1 = System.currentTimeMillis();
+ }
+
+ anim.stop();
+ glWindow.destroy();
+ }
+
+ //@Test
+ public void testGL3() throws GLException, InterruptedException {
+ if( ! GLProfile.isAvailable(GLProfile.GL3) ) {
+ System.err.println("GL3 n/a");
+ return;
+ }
+ GL3VAODemo.Mode[] modes = new GL3VAODemo.Mode[] { GL3VAODemo.Mode.VAO_NORMAL };
+ testImpl(GLProfile.get(GLProfile.GL3), modes);
+ }
+
+ @Test
+ public void testGL3bc() throws GLException, InterruptedException {
+ if( ! GLProfile.isAvailable(GLProfile.GL3bc) ) {
+ System.err.println("GL3bc n/a");
+ return;
+ }
+ GL3VAODemo.Mode[] modes = new GL3VAODemo.Mode[] { GL3VAODemo.Mode.VAO_NORMAL, GL3VAODemo.Mode.NON_VAO };
+ testImpl(GLProfile.get(GLProfile.GL3bc), modes);
+ }
+
+ public static void main(String args[]) throws IOException {
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-time")) {
+ duration = MiscUtils.atoi(args[++i], (int)duration);
+ }
+ }
+ String tstname = TestBug692GL3VAO.class.getName();
+ org.junit.runner.JUnitCore.main(tstname);
+ }
+
+}
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 5e523c780..9bbbbce05 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
@@ -270,7 +270,7 @@ public class GearsES2 implements GLEventListener {
public void display(GLAutoDrawable drawable) {
GLAnimatorControl anim = drawable.getAnimator();
if( verbose && ( null == anim || !anim.isAnimating() ) ) {
- System.err.println(Thread.currentThread()+" GearsES2.display"+drawable.getWidth()+"x"+drawable.getHeight()+", swapInterval "+swapInterval+", drawable 0x"+Long.toHexString(drawable.getHandle()));
+ System.err.println(Thread.currentThread()+" GearsES2.display "+drawable.getWidth()+"x"+drawable.getHeight()+", swapInterval "+swapInterval+", drawable 0x"+Long.toHexString(drawable.getHandle()));
}
// Turn the gears' teeth
if(doRotate) {
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/newt/TestGearsNewtAWTWrapper.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/newt/TestGearsNewtAWTWrapper.java
index cc20cc27e..0b907d5ee 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/newt/TestGearsNewtAWTWrapper.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/newt/TestGearsNewtAWTWrapper.java
@@ -34,6 +34,7 @@ import javax.media.opengl.*;
import com.jogamp.opengl.util.Animator;
import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
+import com.jogamp.opengl.test.junit.util.MiscUtils;
import com.jogamp.opengl.test.junit.util.UITestCase;
import com.jogamp.opengl.test.junit.util.QuitAdapter;
import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
@@ -49,6 +50,9 @@ import org.junit.Test;
public class TestGearsNewtAWTWrapper extends UITestCase {
static GLProfile glp;
static int width, height;
+ static boolean useAnimator = true;
+ static boolean doResizeTest = true;
+ static long duration = 500; // ms
@BeforeClass
public static void initClass() {
@@ -73,39 +77,50 @@ public class TestGearsNewtAWTWrapper extends UITestCase {
glWindow.addGLEventListener(new GearsES2(1));
- Animator animator = new Animator(glWindow);
+ Animator animator = useAnimator ? new Animator(glWindow) : null;
QuitAdapter quitAdapter = new QuitAdapter();
glWindow.addKeyListener(new TraceKeyAdapter(quitAdapter));
glWindow.addWindowListener(new TraceWindowAdapter(quitAdapter));
+ if( useAnimator ) {
+ animator.start();
+ }
+
int div = 3;
glWindow.setSize(width/div, height/div);
glWindow.setVisible(true);
- glWindow.display();
- Assert.assertTrue("Size not reached: Expected "+(width/div)+"x"+(height/div)+", Is "+glWindow.getWidth()+"x"+glWindow.getHeight(),
- AWTRobotUtil.waitForSize(glWindow, width/div, height/div));
-
- div = 2;
- glWindow.setSize(width/div, height/div);
- glWindow.display();
- Assert.assertTrue("Size not reached: Expected "+(width/div)+"x"+(height/div)+", Is "+glWindow.getWidth()+"x"+glWindow.getHeight(),
- AWTRobotUtil.waitForSize(glWindow, width/div, height/div));
-
- div = 1;
- glWindow.setSize(width/div, height/div);
- glWindow.display();
- Assert.assertTrue("Size not reached: Expected "+(width/div)+"x"+(height/div)+", Is "+glWindow.getWidth()+"x"+glWindow.getHeight(),
- AWTRobotUtil.waitForSize(glWindow, width/div, height/div));
-
- animator.setUpdateFPSFrames(1, null);
- animator.start();
+ if( doResizeTest ) {
+ glWindow.display();
+ Assert.assertTrue("Size not reached: Expected "+(width/div)+"x"+(height/div)+", Is "+glWindow.getWidth()+"x"+glWindow.getHeight(),
+ AWTRobotUtil.waitForSize(glWindow, width/div, height/div));
+ Thread.sleep(600);
+
+ div = 2;
+ glWindow.setSize(width/div, height/div);
+ glWindow.display();
+ Assert.assertTrue("Size not reached: Expected "+(width/div)+"x"+(height/div)+", Is "+glWindow.getWidth()+"x"+glWindow.getHeight(),
+ AWTRobotUtil.waitForSize(glWindow, width/div, height/div));
+ Thread.sleep(600);
+
+ div = 1;
+ glWindow.setSize(width/div, height/div);
+ glWindow.display();
+ Assert.assertTrue("Size not reached: Expected "+(width/div)+"x"+(height/div)+", Is "+glWindow.getWidth()+"x"+glWindow.getHeight(),
+ AWTRobotUtil.waitForSize(glWindow, width/div, height/div));
+ Thread.sleep(600);
+ }
- while(!quitAdapter.shouldQuit() && animator.isAnimating() && animator.getTotalFPSDuration()<duration) {
+ final long t0 = System.currentTimeMillis();
+ long t1 = t0;
+ while(!quitAdapter.shouldQuit() && t1-t0<duration) {
Thread.sleep(100);
+ t1 = System.currentTimeMillis();
}
- animator.stop();
+ if( useAnimator ) {
+ animator.stop();
+ }
glWindow.destroy();
}
@@ -115,17 +130,18 @@ public class TestGearsNewtAWTWrapper extends UITestCase {
runTestGL(caps);
}
- static long duration = 500; // ms
-
public static void main(String args[]) {
for(int i=0; i<args.length; i++) {
if(args[i].equals("-time")) {
i++;
- try {
- duration = Integer.parseInt(args[i]);
- } catch (Exception ex) { ex.printStackTrace(); }
+ duration = MiscUtils.atol(args[i], duration);
+ } else if(args[i].equals("-noanim")) {
+ useAnimator = false;
+ } else if(args[i].equals("-noresize")) {
+ doResizeTest = false;
}
}
+ System.err.println("useAnimator "+useAnimator);
org.junit.runner.JUnitCore.main(TestGearsNewtAWTWrapper.class.getName());
}
}