diff options
author | Sven Gothel <[email protected]> | 2010-11-27 07:55:31 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2010-11-27 07:55:31 +0100 |
commit | 86c164950b0a0d351fc8af3884187b10201b6237 (patch) | |
tree | 498535608116440d9122db89af33f7f8c998378f /src | |
parent | c6c30d46bc9c6ff472e35cf592713297b1ef7409 (diff) |
GLCanvas: Fix disableBackgroundErase/X11, make drawable creation more robust, doc Java2D/AWT properties.
On X11 disableBackgroundErase() must happen before native peer creation,
this patch issues it before and after super.addNotify().
Make drawable creation more robust, ie only create a drawable in case the size is > 0x0
and do this check/create at display/paint in case size it not yet determined.
Add documentation about Java2D/AWT properties impact on GLCanvas.
Make JUnit tests on AWT/GLProfile's more robust, while adding frame validate()
ensuring 1st paint will have a size, hence will create the drawable.
This is necessary for eg. AMD GPU's and GL context > 3.
Diffstat (limited to 'src')
4 files changed, 89 insertions, 19 deletions
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java index 711e33494..b230a2b6a 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java @@ -71,10 +71,38 @@ import java.security.*; // GLEventListeners /** A heavyweight AWT component which provides OpenGL rendering - support. This is the primary implementation of {@link GLDrawable}; + support. This is the primary implementation of an AWT {@link GLDrawable}; {@link GLJPanel} is provided for compatibility with Swing user interfaces when adding a heavyweight doesn't work either because - of Z-ordering or LayoutManager problems. */ + of Z-ordering or LayoutManager problems. + * + * <h5><A NAME="java2dgl">Java2D OpenGL Remarks</A></h5> + * + * To avoid any conflicts with a potential Java2D OpenGL context,<br> + * you shall consider setting the following JVM properties:<br> + * <ul> + * <li><pre>sun.java2d.opengl=false</pre></li> + * <li><pre>sun.java2d.noddraw=true</pre></li> + * </ul> + * This is especially true in case you want to utilize a GLProfile other than + * {@link GLProfile#GL2}, eg. using {@link GLProfile#getMaxFixedFunc()}.<br> + * On the other hand, if you like to experiment with GLJPanel's utilization + * of Java2D's OpenGL pipeline, you have to set them to + * <ul> + * <li><pre>sun.java2d.opengl=true</pre></li> + * <li><pre>sun.java2d.noddraw=true</pre></li> + * </ul> + * + * <h5><A NAME="backgrounderase">Disable Background Erase</A></h5> + * + * GLCanvas tries to disable background erase for the AWT Canvas + * before native peer creation (X11) and after it (Windows), <br> + * utilizing the optional {@link java.awt.Toolkit} method <code>disableBeackgroundErase(java.awt.Canvas)</code>.<br> + * However if this does not give you the desired results, you may want to disable AWT background erase in general: + * <ul> + * <li><pre>sun.awt.noerasebackground=true</pre></li> + * </ul> + */ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { @@ -313,7 +341,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { private Object closingListenerLock = new Object(); public void display() { - if(!drawable.isRealized()) { + if( !validateGLDrawable() ) { return; // not yet available .. } maybeDoSingleThreadedWorkaround(displayOnEventDispatchThreadAction, @@ -427,7 +455,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { <DL><DD><CODE>addNotify</CODE> in class <CODE>java.awt.Component</CODE></DD></DL> */ public void addNotify() { if(DEBUG) { - Exception ex1 = new Exception(Thread.currentThread().getName()+" - Info: addNotify - start"); + Exception ex1 = new Exception(Thread.currentThread().getName()+" - Info: addNotify - start, bounds: "+this.getBounds()); ex1.printStackTrace(); } @@ -452,23 +480,43 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { context.setSynchronized(true); } + // before native peer is valid: X11 + disableBackgroundErase(); + // issues getGraphicsConfiguration() and creates the native peer super.addNotify(); - if (!Beans.isDesignTime()) { - // no lock required, since this resource ain't available yet - disableBackgroundErase(); - drawable.setRealized(true); - sendReshape=true; // ensure a reshape is being send .. - if(DEBUG) { - System.err.println(Thread.currentThread().getName()+" - Realized Drawable: "+drawable); - } - } + // after native peer is valid: Windows + disableBackgroundErase(); + + validateGLDrawable(); + if(DEBUG) { System.err.println(Thread.currentThread().getName()+" - Info: addNotify - end"); } } + private boolean validateGLDrawable() { + boolean realized = false; + if (!Beans.isDesignTime()) { + if ( null != drawable ) { + realized = drawable.isRealized(); + if ( !realized && 0 < drawable.getWidth() * drawable.getHeight() ) { + drawable.setRealized(true); + realized = true; + sendReshape=true; // ensure a reshape is being send .. + if(DEBUG) { + String msg = Thread.currentThread().getName()+" - Realized Drawable: "+drawable.toString(); + // System.err.println(msg); + Throwable t = new Throwable(msg); + t.printStackTrace(); + } + } + } + } + return realized; + } + /** <p>Overridden to track when this component is removed from a container. Subclasses which override this method must call super.removeNotify() in their removeNotify() method in order to @@ -770,13 +818,22 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { } catch (Exception e) { } disableBackgroundEraseInitialized = true; + if(DEBUG) { + System.err.println("GLCanvas: TK disableBackgroundErase method found: "+ + (null!=disableBackgroundEraseMethod)); + } } if (disableBackgroundEraseMethod != null) { + Throwable t=null; try { disableBackgroundEraseMethod.invoke(getToolkit(), new Object[] { this }); } catch (Exception e) { // FIXME: workaround for 6504460 (incorrect backport of 6333613 in 5.0u10) // throw new GLException(e); + t = e; + } + if(DEBUG) { + System.err.println("GLCanvas: TK disableBackgroundErase error: "+t); } } } diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java index c69603e41..5c6be8bc4 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java @@ -61,13 +61,13 @@ import com.jogamp.opengl.impl.awt.*; /** A lightweight Swing component which provides OpenGL rendering support. Provided for compatibility with Swing user interfaces when adding a heavyweight doesn't work either because of - Z-ordering or LayoutManager problems. <P> - + Z-ordering or LayoutManager problems. + <P> The GLJPanel can be made transparent by creating it with a GLCapabilities object with alpha bits specified and calling {@link #setOpaque}(false). Pixels with resulting OpenGL alpha values less - than 1.0 will be overlaid on any underlying Swing rendering. <P> - + than 1.0 will be overlaid on any underlying Swing rendering. </P> + <P> Notes specific to the Reference Implementation: This component attempts to use hardware-accelerated rendering via pbuffers and falls back on to software rendering if problems occur. @@ -79,8 +79,10 @@ import com.jogamp.opengl.impl.awt.*; This behavior is correct, as the textures and display lists for the GLJPanel will have been lost during the resize operation. The application should attempt to make its GLEventListener.init() - methods as side-effect-free as possible. <P> - + methods as side-effect-free as possible. </P> + <P> + * Please read <A HREF="GLCanvas.html#java2dgl">Java2D OpenGL Remarks</A>. + * </P> */ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { diff --git a/src/junit/com/jogamp/test/junit/jogl/awt/TestAWT01GLn.java b/src/junit/com/jogamp/test/junit/jogl/awt/TestAWT01GLn.java index 88551bdb4..0fef76c7d 100644 --- a/src/junit/com/jogamp/test/junit/jogl/awt/TestAWT01GLn.java +++ b/src/junit/com/jogamp/test/junit/jogl/awt/TestAWT01GLn.java @@ -85,7 +85,12 @@ public class TestAWT01GLn extends UITestCase { glCanvas = new GLCanvas(caps); Assert.assertNotNull(glCanvas); frame.add(glCanvas); + + // Revalidate size/layout. + // Always validate if component added/removed. + // Ensure 1st paint of GLCanvas will have a valid size, hence drawable gets created. frame.setSize(512, 512); + frame.validate(); glCanvas.addGLEventListener(new Gears()); diff --git a/src/junit/com/jogamp/test/junit/jogl/awt/TestSwingAWT01GLn.java b/src/junit/com/jogamp/test/junit/jogl/awt/TestSwingAWT01GLn.java index 661f61d37..74ca0a3e7 100644 --- a/src/junit/com/jogamp/test/junit/jogl/awt/TestSwingAWT01GLn.java +++ b/src/junit/com/jogamp/test/junit/jogl/awt/TestSwingAWT01GLn.java @@ -85,7 +85,13 @@ public class TestSwingAWT01GLn extends UITestCase { glCanvas[0] = new GLCanvas(caps); glCanvas[0].addGLEventListener(new Gears()); window.add(glCanvas[0]); + + // Revalidate size/layout. + // Always validate if component added/removed. + // Ensure 1st paint of GLCanvas will have a valid size, hence drawable gets created. window.setSize(512, 512); + window.validate(); + window.setVisible(true); glCanvas[0].display(); } |