summaryrefslogtreecommitdiffstats
path: root/src/jogl
diff options
context:
space:
mode:
Diffstat (limited to 'src/jogl')
-rw-r--r--src/jogl/classes/com/jogamp/opengl/GLAutoDrawableDelegate.java6
-rw-r--r--src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java12
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java2
-rw-r--r--src/jogl/classes/javax/media/opengl/GLContext.java2
-rw-r--r--src/jogl/classes/javax/media/opengl/GLProfile.java37
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/GLCanvas.java264
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/GLJPanel.java51
-rw-r--r--src/jogl/classes/jogamp/opengl/FPSCounterImpl.java1
-rw-r--r--src/jogl/classes/jogamp/opengl/GLContextImpl.java80
-rw-r--r--src/jogl/classes/jogamp/opengl/GLVersionNumber.java11
-rw-r--r--src/jogl/classes/jogamp/opengl/awt/AWTThreadingPlugin.java6
-rw-r--r--src/jogl/classes/jogamp/opengl/awt/Java2D.java254
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java41
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java2
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java4
-rw-r--r--src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m322
-rw-r--r--src/jogl/native/macosx/MacOSXWindowSystemInterface.m1
17 files changed, 701 insertions, 395 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/GLAutoDrawableDelegate.java b/src/jogl/classes/com/jogamp/opengl/GLAutoDrawableDelegate.java
index 206331ac0..0f0f03ac4 100644
--- a/src/jogl/classes/com/jogamp/opengl/GLAutoDrawableDelegate.java
+++ b/src/jogl/classes/com/jogamp/opengl/GLAutoDrawableDelegate.java
@@ -51,12 +51,12 @@ import jogamp.opengl.GLDrawableImpl;
* utilizing already created {@link GLDrawable} and {@link GLContext} instances.
* <p>
* Since no native windowing system events are being processed, it is recommended
- * to handle at least:
+ * to handle at least the {@link com.jogamp.newt.event.WindowEvent window events}:
* <ul>
* <li>{@link com.jogamp.newt.event.WindowListener#windowRepaint(com.jogamp.newt.event.WindowUpdateEvent) repaint} using {@link #windowRepaintOp()}</li>
* <li>{@link com.jogamp.newt.event.WindowListener#windowResized(com.jogamp.newt.event.WindowEvent) resize} using {@link #windowResizedOp()}</li>
- * <li>{@link com.jogamp.newt.event.WindowListener#windowDestroyNotify(com.jogamp.newt.event.WindowEvent) destroy-notify} using {@link #windowDestroyNotifyOp()}</li>
- * </ul>
+ * </ul>
+ * and setup a {@link com.jogamp.newt.Window#setWindowDestroyNotifyAction(Runnable) custom toolkit destruction} issuing {@link #windowDestroyNotifyOp()}.
* </p>
* <p>
* See example {@link com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableDelegateNEWT TestGLAutoDrawableDelegateNEWT}.
diff --git a/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java b/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java
index 9a13ff904..715511d1b 100644
--- a/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java
+++ b/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java
@@ -73,12 +73,20 @@ public class GLRendererQuirks {
*/
public static final int GLNonCompliant = 6;
+ /**
+ * The OpenGL Context needs a <code>glFlush()</code> before releasing it, otherwise driver may freeze:
+ * <ul>
+ * <li>OSX < 10.7.3 - NVidia Driver. Bug 533 and Bug 548 @ https://jogamp.org/bugzilla/.</li>
+ * </ul>
+ */
+ public static final int GLFlushBeforeRelease = 7;
+
/** Number of quirks known. */
- public static final int COUNT = 7;
+ public static final int COUNT = 8;
private static final String[] _names = new String[] { "NoDoubleBufferedPBuffer", "NoDoubleBufferedBitmap", "NoSetSwapInterval",
"NoOffscreenBitmap", "NoSetSwapIntervalPostRetarget", "GLSLBuggyDiscard",
- "GLNonCompliant"
+ "GLNonCompliant", "GLFlushBeforeRelease"
};
private final int _bitmask;
diff --git a/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java b/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java
index 53a99b640..aa0e70132 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java
@@ -537,7 +537,7 @@ public abstract class AnimatorBase implements GLAnimatorControl {
remaining -= System.currentTimeMillis() - t1 ;
nok = waitCondition.eval();
}
- if(DEBUG || nok) {
+ if(DEBUG || blocking && nok) { // Info only if DEBUG or ( blocking && not-ok ) ; !blocking possible if AWT
if( remaining<=0 && nok ) {
System.err.println("finishLifecycleAction(" + waitCondition.getClass().getName() + "): ++++++ timeout reached ++++++ " + Thread.currentThread().getName());
}
diff --git a/src/jogl/classes/javax/media/opengl/GLContext.java b/src/jogl/classes/javax/media/opengl/GLContext.java
index 4817add4d..c31b76401 100644
--- a/src/jogl/classes/javax/media/opengl/GLContext.java
+++ b/src/jogl/classes/javax/media/opengl/GLContext.java
@@ -442,7 +442,7 @@ public abstract class GLContext {
* new GLContext implementations; not for use by end users.
*/
protected static void setCurrent(GLContext cur) {
- if(TRACE_SWITCH) {
+ if( TRACE_SWITCH ) {
if(null == cur) {
System.err.println(getThreadName()+": GLContext.ContextSwitch: - setCurrent() - NULL");
} else {
diff --git a/src/jogl/classes/javax/media/opengl/GLProfile.java b/src/jogl/classes/javax/media/opengl/GLProfile.java
index f916ab8b1..25bba1725 100644
--- a/src/jogl/classes/javax/media/opengl/GLProfile.java
+++ b/src/jogl/classes/javax/media/opengl/GLProfile.java
@@ -543,8 +543,20 @@ public class GLProfile {
* </ul>
*
*/
- public static final String[] GL_PROFILE_LIST_MAX_PROGSHADER = new String[] { GL4bc, GL4, GL3bc, GL3, GL2, GLES2 };
+ public static final String[] GL_PROFILE_LIST_MAX_PROGSHADER = new String[] { GL4bc, GL4, GL3bc, GL3, GL2, GLES2 };
+ /**
+ * Order of maximum programmable shader <i>core only</i> profiles
+ *
+ * <ul>
+ * <li> GL4
+ * <li> GL3
+ * <li> GLES2
+ * </ul>
+ *
+ */
+ public static final String[] GL_PROFILE_LIST_MAX_PROGSHADER_CORE = new String[] { GL4, GL3, GLES2 };
+
/** Returns a default GLProfile object, reflecting the best for the running platform.
* It selects the first of the set {@link GLProfile#GL_PROFILE_LIST_ALL}
* and favors hardware acceleration.
@@ -659,6 +671,29 @@ public class GLProfile {
return get(GL_PROFILE_LIST_MAX_PROGSHADER, favorHardwareRasterizer);
}
+ /**
+ * Returns the highest profile, implementing the programmable shader <i>core</i> pipeline <i>only</i>.
+ * It selects the first of the set: {@link GLProfile#GL_PROFILE_LIST_MAX_PROGSHADER_CORE}
+ *
+ * @throws GLException if no programmable core profile is available for the device.
+ * @see #GL_PROFILE_LIST_MAX_PROGSHADER_CORE
+ */
+ public static GLProfile getMaxProgrammableCore(AbstractGraphicsDevice device, boolean favorHardwareRasterizer)
+ throws GLException
+ {
+ return get(device, GL_PROFILE_LIST_MAX_PROGSHADER_CORE, favorHardwareRasterizer);
+ }
+
+ /** Uses the default device
+ * @throws GLException if no programmable core profile is available for the default device.
+ * @see #GL_PROFILE_LIST_MAX_PROGSHADER_CORE
+ */
+ public static GLProfile getMaxProgrammableCore(boolean favorHardwareRasterizer)
+ throws GLException
+ {
+ return get(GL_PROFILE_LIST_MAX_PROGSHADER_CORE, favorHardwareRasterizer);
+ }
+
/**
* Returns the GL2ES1 profile implementation, hence compatible w/ GL2ES1.<br/>
* It returns:
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
index 2de86b545..94e123b3e 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
@@ -174,9 +174,9 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
new AWTWindowClosingProtocol(this, new Runnable() {
@Override
public void run() {
- GLCanvas.this.destroy();
+ GLCanvas.this.destroyImpl( true );
}
- });
+ }, null);
/** Creates a new GLCanvas component with a default set of OpenGL
capabilities, using the default OpenGL capabilities selection
@@ -312,6 +312,11 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
* all platforms since the peer hasn't been created.
*/
final GraphicsConfiguration gc = super.getGraphicsConfiguration();
+
+ if( Beans.isDesignTime() ) {
+ return gc;
+ }
+
/*
* chosen is only non-null on platforms where the GLDrawableFactory
* returns a non-null GraphicsConfiguration (in the GLCanvas
@@ -370,10 +375,15 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
*/
chosen = compatible;
- awtConfig = config;
-
if( !equalCaps && GLAutoDrawable.SCREEN_CHANGE_ACTION_ENABLED ) {
- dispose(true);
+ // complete destruction!
+ destroyImpl( true );
+ // recreation!
+ awtConfig = config;
+ createDrawableAndContext( true );
+ validateGLDrawable();
+ } else {
+ awtConfig = config;
}
}
}
@@ -447,26 +457,33 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
}
return; // not yet available ..
}
- Threading.invoke(true, displayOnEDTAction, getTreeLock());
- awtWindowClosingProtocol.addClosingListenerOneShot();
- }
-
- private void dispose(boolean regenerate) {
- disposeRegenerate=regenerate;
- Threading.invoke(true, disposeOnEDTAction, getTreeLock());
+ if( isVisible() ) {
+ Threading.invoke(true, displayOnEDTAction, getTreeLock());
+ }
}
/**
* {@inheritDoc}
*
* <p>
- * This impl. calls this class's {@link #removeNotify()} AWT override,
- * where the actual implementation resides.
+ * This impl. only destroys all GL related resources.
+ * </p>
+ * <p>
+ * This impl. does not remove the GLCanvas from it's parent AWT container
+ * so this class's {@link #removeNotify()} AWT override won't get called.
+ * To do so, remove this component from it's parent AWT container.
* </p>
*/
@Override
public void destroy() {
- removeNotify();
+ destroyImpl( false );
+ }
+
+ protected void destroyImpl(boolean destroyJAWTWindowAndAWTDevice) {
+ Threading.invoke(true, destroyOnEDTAction, getTreeLock());
+ if( destroyJAWTWindowAndAWTDevice ) {
+ AWTEDTExecutor.singleton.invoke(getTreeLock(), true /* allowOnNonEDT */, true /* wait */, disposeJAWTWindowAndAWTDeviceOnEDT);
+ }
}
/** Overridden to cause OpenGL rendering to be performed during
@@ -476,7 +493,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
*/
@Override
public void paint(Graphics g) {
- if (Beans.isDesignTime()) {
+ if( Beans.isDesignTime() ) {
// Make GLCanvas behave better in NetBeans GUI builder
g.setColor(Color.BLACK);
g.fillRect(0, 0, getWidth(), getHeight());
@@ -494,9 +511,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
g.drawString(name,
(int) ((getWidth() - bounds.getWidth()) / 2),
(int) ((getHeight() + bounds.getHeight()) / 2));
- return;
- }
- if( ! this.helper.isAnimatorAnimatingOnOtherThread() ) {
+ } else if( !this.helper.isAnimatorAnimatingOnOtherThread() ) {
display();
}
}
@@ -513,42 +528,47 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
public void addNotify() {
final RecursiveLock _lock = lock;
_lock.lock();
- try {
+ try {
+ final boolean isBeansDesignTime = Beans.isDesignTime();
+
if(DEBUG) {
- System.err.println(getThreadName()+": Info: addNotify - start, bounds: "+this.getBounds());
+ System.err.println(getThreadName()+": Info: addNotify - start, bounds: "+this.getBounds()+", isBeansDesignTime "+isBeansDesignTime);
Thread.dumpStack();
}
- /**
- * 'super.addNotify()' determines the GraphicsConfiguration,
- * while calling this class's overriden 'getGraphicsConfiguration()' method
- * after which it creates the native peer.
- * Hence we have to set the 'awtConfig' before since it's GraphicsConfiguration
- * is being used in getGraphicsConfiguration().
- * This code order also allows recreation, ie re-adding the GLCanvas.
- */
- awtConfig = chooseGraphicsConfiguration(capsReqUser, capsReqUser, chooser, device);
- if(null==awtConfig) {
- throw new GLException("Error: NULL AWTGraphicsConfiguration");
- }
-
- // before native peer is valid: X11
- disableBackgroundErase();
-
- // issues getGraphicsConfiguration() and creates the native peer
- super.addNotify();
-
- // after native peer is valid: Windows
- disableBackgroundErase();
-
- if (!Beans.isDesignTime()) {
- createDrawableAndContext();
+ if( isBeansDesignTime ) {
+ super.addNotify();
+ } else {
+ /**
+ * 'super.addNotify()' determines the GraphicsConfiguration,
+ * while calling this class's overriden 'getGraphicsConfiguration()' method
+ * after which it creates the native peer.
+ * Hence we have to set the 'awtConfig' before since it's GraphicsConfiguration
+ * is being used in getGraphicsConfiguration().
+ * This code order also allows recreation, ie re-adding the GLCanvas.
+ */
+ awtConfig = chooseGraphicsConfiguration(capsReqUser, capsReqUser, chooser, device);
+ if(null==awtConfig) {
+ throw new GLException("Error: NULL AWTGraphicsConfiguration");
+ }
+
+ // before native peer is valid: X11
+ disableBackgroundErase();
+
+ // issues getGraphicsConfiguration() and creates the native peer
+ super.addNotify();
+
+ // after native peer is valid: Windows
+ disableBackgroundErase();
+
+ createDrawableAndContext( true );
+
+ // init drawable by paint/display makes the init sequence more equal
+ // for all launch flavors (applet/javaws/..)
+ // validateGLDrawable();
}
-
- // init drawable by paint/display makes the init sequence more equal
- // for all launch flavors (applet/javaws/..)
- // validateGLDrawable();
-
+ awtWindowClosingProtocol.addClosingListener();
+
if(DEBUG) {
System.err.println(getThreadName()+": Info: addNotify - end: peer: "+getPeer());
}
@@ -557,27 +577,33 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
}
}
- private void createDrawableAndContext() {
- // no lock required, since this resource ain't available yet
- jawtWindow = (JAWTWindow) NativeWindowFactory.getNativeWindow(this, awtConfig);
- jawtWindow.setShallUseOffscreenLayer(shallUseOffscreenLayer);
- jawtWindow.lockSurface();
- try {
- drawable = (GLDrawableImpl) GLDrawableFactory.getFactory(capsReqUser.getGLProfile()).createGLDrawable(jawtWindow);
- context = (GLContextImpl) drawable.createContext(shareWith);
- context.setContextCreationFlags(additionalCtxCreationFlags);
- } finally {
- jawtWindow.unlockSurface();
+ private void createDrawableAndContext(boolean createJAWTWindow) {
+ if ( !Beans.isDesignTime() ) {
+ if( createJAWTWindow ) {
+ jawtWindow = (JAWTWindow) NativeWindowFactory.getNativeWindow(this, awtConfig);
+ jawtWindow.setShallUseOffscreenLayer(shallUseOffscreenLayer);
+ }
+ jawtWindow.lockSurface();
+ try {
+ drawable = (GLDrawableImpl) GLDrawableFactory.getFactory(capsReqUser.getGLProfile()).createGLDrawable(jawtWindow);
+ context = (GLContextImpl) drawable.createContext(shareWith);
+ context.setContextCreationFlags(additionalCtxCreationFlags);
+ } finally {
+ jawtWindow.unlockSurface();
+ }
}
- }
+ }
private boolean validateGLDrawable() {
+ if( Beans.isDesignTime() || !isDisplayable() ) {
+ return false; // early out!
+ }
final GLDrawable _drawable = drawable;
if ( null != _drawable ) {
if( _drawable.isRealized() ) {
return true;
}
- if( Beans.isDesignTime() || !isDisplayable() || 0 >= _drawable.getWidth() || 0 >= _drawable.getHeight() ) {
+ if( 0 >= _drawable.getWidth() || 0 >= _drawable.getHeight() ) {
return false; // early out!
}
// Make sure drawable realization happens on AWT-EDT and only there. Consider the AWTTree lock!
@@ -627,11 +653,11 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
awtWindowClosingProtocol.removeClosingListener();
- if (Beans.isDesignTime()) {
+ if( Beans.isDesignTime() ) {
super.removeNotify();
} else {
try {
- dispose(false);
+ destroyImpl( true );
} finally {
super.removeNotify();
}
@@ -676,6 +702,9 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
}
}
sendReshape = true; // async if display() doesn't get called below, but avoiding deadlock
+ if(null != jawtWindow && jawtWindow.isOffscreenLayerSurfaceEnabled() ) {
+ jawtWindow.layoutSurfaceLayer();
+ }
}
}
}
@@ -790,7 +819,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
@Override
public GL getGL() {
- if (Beans.isDesignTime()) {
+ if( Beans.isDesignTime() ) {
return null;
}
final GLContext _context = context;
@@ -844,18 +873,18 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
@Override
public GLCapabilitiesImmutable getChosenGLCapabilities() {
- if (awtConfig == null) {
+ if( Beans.isDesignTime() ) {
+ return capsReqUser;
+ } else if( null == awtConfig ) {
throw new GLException("No AWTGraphicsConfiguration: "+this);
}
-
return (GLCapabilitiesImmutable)awtConfig.getChosenCapabilities();
}
public GLCapabilitiesImmutable getRequestedGLCapabilities() {
- if (awtConfig == null) {
+ if( null == awtConfig ) {
return capsReqUser;
}
-
return (GLCapabilitiesImmutable)awtConfig.getRequestedCapabilities();
}
@@ -897,8 +926,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
// Internals only below this point
//
- private boolean disposeRegenerate;
- private final Runnable disposeOnEDTAction = new Runnable() {
+ private final Runnable destroyOnEDTAction = new Runnable() {
@Override
public void run() {
final RecursiveLock _lock = lock;
@@ -907,11 +935,11 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
final GLAnimatorControl animator = getAnimator();
if(DEBUG) {
- System.err.println(getThreadName()+": Info: dispose("+disposeRegenerate+") - START, hasContext " +
+ System.err.println(getThreadName()+": Info: destroyOnEDTAction() - START, hasContext " +
(null!=context) + ", hasDrawable " + (null!=drawable)+", "+animator);
Thread.dumpStack();
}
-
+
final boolean animatorPaused;
if(null!=animator) {
// can't remove us from animator for recreational addNotify()
@@ -926,50 +954,29 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
// so we can continue with the destruction.
try {
helper.disposeGL(GLCanvas.this, context, true);
+ if(DEBUG) {
+ System.err.println(getThreadName()+": destroyOnEDTAction() - post ctx: "+context);
+ }
} catch (GLException gle) {
gle.printStackTrace();
}
- }
- context=null;
+ }
+ context = null;
}
if( null != drawable ) {
drawable.setRealized(false);
if(DEBUG) {
- System.err.println(getThreadName()+": dispose("+disposeRegenerate+") - 1: "+drawable);
+ System.err.println(getThreadName()+": destroyOnEDTAction() - post drawable: "+drawable);
}
- drawable=null;
+ drawable = null;
}
- if( null != jawtWindow ) {
- jawtWindow.destroy();
- if(DEBUG) {
- System.err.println(getThreadName()+": dispose("+disposeRegenerate+") - 2: "+jawtWindow);
- }
- jawtWindow=null;
- }
-
- if(disposeRegenerate) {
- // Similar process as in addNotify()!
-
- // Recreate GLDrawable/GLContext to reflect it's new graphics configuration
- createDrawableAndContext();
- if(DEBUG) {
- System.err.println(getThreadName()+": GLCanvas.dispose(true): new drawable: "+drawable);
- }
- validateGLDrawable(); // immediate attempt to recreate the drawable
- } else {
- if(null != awtConfig) {
- AWTEDTExecutor.singleton.invoke(getTreeLock(), true /* allowOnNonEDT */, true /* wait */, disposeAbstractGraphicsDeviceActionOnEDT);
- }
- awtConfig=null;
- }
-
if(animatorPaused) {
animator.resume();
}
if(DEBUG) {
- System.err.println(getThreadName()+": dispose("+disposeRegenerate+") - END, animator "+animator);
+ System.err.println(getThreadName()+": dispose() - END, animator "+animator);
}
} finally {
@@ -979,28 +986,43 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
};
/**
- * Disposes the AbstractGraphicsDevice within EDT,
+ * Disposes the JAWTWindow and AbstractGraphicsDevice within EDT,
* since resources created (X11: Display), must be destroyed in the same thread, where they have been created.
+ * <p>
+ * The drawable and context handle are null'ed as well, assuming {@link #destroy()} has been called already.
+ * </p>
*
* @see #chooseGraphicsConfiguration(javax.media.opengl.GLCapabilitiesImmutable, javax.media.opengl.GLCapabilitiesImmutable, javax.media.opengl.GLCapabilitiesChooser, java.awt.GraphicsDevice)
*/
- private final Runnable disposeAbstractGraphicsDeviceActionOnEDT = new Runnable() {
+ private final Runnable disposeJAWTWindowAndAWTDeviceOnEDT = new Runnable() {
@Override
public void run() {
- if(null != awtConfig) {
- final AbstractGraphicsConfiguration aconfig = awtConfig.getNativeGraphicsConfiguration();
- final AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice();
- final String adeviceMsg;
- if(DEBUG) {
- adeviceMsg = adevice.toString();
- } else {
- adeviceMsg = null;
- }
- boolean closed = adevice.close();
- if(DEBUG) {
- System.err.println(getThreadName()+": GLCanvas.dispose(false): closed GraphicsDevice: "+adeviceMsg+", result: "+closed);
- }
- }
+ context=null;
+ drawable=null;
+
+ if( null != jawtWindow ) {
+ jawtWindow.destroy();
+ if(DEBUG) {
+ System.err.println(getThreadName()+": GLCanvas.disposeJAWTWindowAndAWTDeviceOnEDT(): post JAWTWindow: "+jawtWindow);
+ }
+ jawtWindow=null;
+ }
+
+ if(null != awtConfig) {
+ final AbstractGraphicsConfiguration aconfig = awtConfig.getNativeGraphicsConfiguration();
+ final AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice();
+ final String adeviceMsg;
+ if(DEBUG) {
+ adeviceMsg = adevice.toString();
+ } else {
+ adeviceMsg = null;
+ }
+ boolean closed = adevice.close();
+ if(DEBUG) {
+ System.err.println(getThreadName()+": GLCanvas.disposeJAWTWindowAndAWTDeviceOnEDT(): post GraphicsDevice: "+adeviceMsg+", result: "+closed);
+ }
+ }
+ awtConfig=null;
}
};
@@ -1139,14 +1161,14 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
* @param device
* @return the chosen AWTGraphicsConfiguration
*
- * @see #disposeAbstractGraphicsDeviceActionOnEDT
+ * @see #disposeJAWTWindowAndAWTDeviceOnEDT
*/
private AWTGraphicsConfiguration chooseGraphicsConfiguration(final GLCapabilitiesImmutable capsChosen,
final GLCapabilitiesImmutable capsRequested,
final GLCapabilitiesChooser chooser,
final GraphicsDevice device) {
// Make GLCanvas behave better in NetBeans GUI builder
- if (Beans.isDesignTime()) {
+ if( Beans.isDesignTime() ) {
return null;
}
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
index 664edb996..6c28c75ab 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
@@ -152,9 +152,9 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
// Used by all backends either directly or indirectly to hook up callbacks
private Updater updater = new Updater();
- // Indicates whether the Java 2D OpenGL pipeline is enabled
- private boolean oglPipelineEnabled =
- Java2D.isOGLPipelineActive() &&
+ // Indicates whether the Java 2D OpenGL pipeline is enabled and resource-compatible
+ private boolean oglPipelineUsable =
+ Java2D.isOGLPipelineResourceCompatible() &&
!Debug.isPropertyDefined("jogl.gljpanel.noogl", true);
// For handling reshape events lazily
@@ -174,13 +174,13 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
public void run() {
GLJPanel.this.destroy();
}
- });
+ }, null);
static {
// Force eager initialization of part of the Java2D class since
// otherwise it's likely it will try to be initialized while on
// the Queue Flusher Thread, which is not allowed
- if (Java2D.isOGLPipelineActive() && Java2D.isFBOEnabled()) {
+ if (Java2D.isOGLPipelineResourceCompatible() && Java2D.isFBOEnabled()) {
Java2D.getShareContext(GraphicsEnvironment.
getLocalGraphicsEnvironment().
getDefaultScreenDevice());
@@ -250,17 +250,19 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
@Override
public void display() {
- if (EventQueue.isDispatchThread()) {
- // Want display() to be synchronous, so call paintImmediately()
- paintImmediately(0, 0, getWidth(), getHeight());
- } else {
- // Multithreaded redrawing of Swing components is not allowed,
- // so do everything on the event dispatch thread
- try {
- EventQueue.invokeAndWait(paintImmediatelyAction);
- } catch (Exception e) {
- throw new GLException(e);
- }
+ if( isVisible() ) {
+ if (EventQueue.isDispatchThread()) {
+ // Want display() to be synchronous, so call paintImmediately()
+ paintImmediately(0, 0, getWidth(), getHeight());
+ } else {
+ // Multithreaded redrawing of Swing components is not allowed,
+ // so do everything on the event dispatch thread
+ try {
+ EventQueue.invokeAndWait(paintImmediatelyAction);
+ } catch (Exception e) {
+ throw new GLException(e);
+ }
+ }
}
}
@@ -350,9 +352,11 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
sendReshape = handleReshape();
}
- updater.setGraphics(g);
-
- backend.doPaintComponent(g);
+ if( isVisible() ) {
+ updater.setGraphics(g);
+
+ backend.doPaintComponent(g);
+ }
}
@@ -365,6 +369,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
@Override
public void addNotify() {
super.addNotify();
+ awtWindowClosingProtocol.addClosingListener();
if (DEBUG) {
System.err.println(getThreadName()+": GLJPanel.addNotify()");
}
@@ -608,7 +613,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
to perform OpenGL rendering using the GLJPanel into the same
OpenGL drawable as the Swing implementation uses. */
public boolean shouldPreserveColorBufferIfTranslucent() {
- return oglPipelineEnabled;
+ return oglPipelineUsable;
}
@Override
@@ -662,7 +667,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
}
if ( null == backend ) {
- if (oglPipelineEnabled) {
+ if (oglPipelineUsable) {
backend = new J2DOGLBackend();
} else {
backend = new OffscreenBackend();
@@ -673,8 +678,6 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
if (!isInitialized) {
backend.initialize();
}
-
- awtWindowClosingProtocol.addClosingListenerOneShot();
}
@Override
@@ -1560,7 +1563,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
}
isInitialized = false;
backend = null;
- oglPipelineEnabled = false;
+ oglPipelineUsable = false;
handleReshape = true;
j2dContext.destroy();
j2dContext = null;
diff --git a/src/jogl/classes/jogamp/opengl/FPSCounterImpl.java b/src/jogl/classes/jogamp/opengl/FPSCounterImpl.java
index 27569d210..b74ac9f41 100644
--- a/src/jogl/classes/jogamp/opengl/FPSCounterImpl.java
+++ b/src/jogl/classes/jogamp/opengl/FPSCounterImpl.java
@@ -103,6 +103,7 @@ public class FPSCounterImpl implements FPSCounter {
fpsLastPeriod = 0;
fpsTotalFrames = 0;
fpsLast = 0f; fpsTotal = 0f;
+ fpsLastPeriod = 0; fpsTotalDuration=0;
}
public final synchronized int getUpdateFPSFrames() {
diff --git a/src/jogl/classes/jogamp/opengl/GLContextImpl.java b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
index b17fce569..42364dbfd 100644
--- a/src/jogl/classes/jogamp/opengl/GLContextImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
@@ -278,14 +278,14 @@ public abstract class GLContextImpl extends GLContext {
release(false);
}
private void release(boolean inDestruction) throws GLException {
- if(TRACE_SWITCH) {
+ if( TRACE_SWITCH ) {
System.err.println(getThreadName() +": GLContext.ContextSwitch[release.0]: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+", surf "+toHexString(drawable.getHandle())+", inDestruction: "+inDestruction+", "+lock);
}
if ( !lock.isOwner(Thread.currentThread()) ) {
final String msg = getThreadName() +": Context not current on current thread, obj " + toHexString(hashCode())+", ctx "+toHexString(contextHandle)+", surf "+toHexString(drawable.getHandle())+", inDestruction: "+inDestruction+", "+lock;
if( DEBUG_TRACE_SWITCH ) {
System.err.println(msg);
- if( null != lastCtxReleaseStack) {
+ if( null != lastCtxReleaseStack ) {
System.err.print("Last release call: ");
lastCtxReleaseStack.printStackTrace();
} else {
@@ -318,7 +318,7 @@ public abstract class GLContextImpl extends GLContext {
if( DEBUG_TRACE_SWITCH ) {
final String msg = getThreadName() +": GLContext.ContextSwitch[release.X]: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+", surf "+toHexString(drawable.getHandle())+" - "+(actualRelease?"switch":"keep ")+" - "+lock;
lastCtxReleaseStack = new Throwable(msg);
- if(TRACE_SWITCH) {
+ if( TRACE_SWITCH ) {
System.err.println(msg);
// Thread.dumpStack();
}
@@ -334,7 +334,7 @@ public abstract class GLContextImpl extends GLContext {
@Override
public final void destroy() {
- if (DEBUG_TRACE_SWITCH) {
+ if ( DEBUG_TRACE_SWITCH ) {
System.err.println(getThreadName() + ": GLContextImpl.destroy.0: obj " + toHexString(hashCode()) + ", ctx " + toHexString(contextHandle) +
", surf "+toHexString(drawable.getHandle())+", isShared "+GLContextShareSet.isShared(this)+" - "+lock);
}
@@ -351,7 +351,7 @@ public abstract class GLContextImpl extends GLContext {
lock.lock(); // holdCount++ -> 1 - n (1: not locked, 2-n: destroy while rendering)
if ( lock.getHoldCount() > 2 ) {
final String msg = getThreadName() + ": GLContextImpl.destroy: obj " + toHexString(hashCode()) + ", ctx " + toHexString(contextHandle);
- if (DEBUG_TRACE_SWITCH) {
+ if ( DEBUG_TRACE_SWITCH ) {
System.err.println(msg+" - Lock was hold more than once - makeCurrent/release imbalance: "+lock);
Thread.dumpStack();
}
@@ -388,7 +388,7 @@ public abstract class GLContextImpl extends GLContext {
}
} finally {
lock.unlock();
- if (TRACE_SWITCH) {
+ if ( DEBUG_TRACE_SWITCH ) {
System.err.println(getThreadName() + ": GLContextImpl.destroy.X: obj " + toHexString(hashCode()) + ", ctx " + toHexString(contextHandle) +
", isShared "+GLContextShareSet.isShared(this)+" - "+lock);
}
@@ -468,14 +468,14 @@ public abstract class GLContextImpl extends GLContext {
*/
@Override
public int makeCurrent() throws GLException {
- if(TRACE_SWITCH) {
+ if( TRACE_SWITCH ) {
System.err.println(getThreadName() +": GLContext.ContextSwitch[makeCurrent.0]: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+", surf "+toHexString(drawable.getHandle())+" - "+lock);
}
// Note: the surface is locked within [makeCurrent .. swap .. release]
final int lockRes = drawable.lockSurface();
if (NativeSurface.LOCK_SURFACE_NOT_READY >= lockRes) {
- if(DEBUG_TRACE_SWITCH) {
+ if( DEBUG_TRACE_SWITCH ) {
System.err.println(getThreadName() +": GLContext.ContextSwitch[makeCurrent.X1]: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+", surf "+toHexString(drawable.getHandle())+" - Surface Not Ready - CONTEXT_NOT_CURRENT - "+lock);
}
return CONTEXT_NOT_CURRENT;
@@ -503,7 +503,7 @@ public abstract class GLContextImpl extends GLContext {
// For Mac OS X, however, we need to update the context to track resizes
drawableUpdatedNotify();
unlockContextAndSurface = false; // success
- if(TRACE_SWITCH) {
+ if( TRACE_SWITCH ) {
System.err.println(getThreadName() +": GLContext.ContextSwitch[makeCurrent.X2]: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+", surf "+toHexString(drawable.getHandle())+" - keep - CONTEXT_CURRENT - "+lock);
}
return CONTEXT_CURRENT;
@@ -526,7 +526,7 @@ public abstract class GLContextImpl extends GLContext {
throw e;
} finally {
if (unlockContextAndSurface) {
- if(DEBUG_TRACE_SWITCH) {
+ if( DEBUG_TRACE_SWITCH ) {
System.err.println(getThreadName() +": GLContext.ContextSwitch[makeCurrent.1]: Context lock.unlock() due to error, res "+makeCurrentResultToString(res)+", "+lock);
}
lock.unlock();
@@ -575,7 +575,7 @@ public abstract class GLContextImpl extends GLContext {
}
*/
}
- if(TRACE_SWITCH) {
+ if( TRACE_SWITCH ) {
System.err.println(getThreadName() +": GLContext.ContextSwitch[makeCurrent.X3]: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+", surf "+toHexString(drawable.getHandle())+" - switch - "+makeCurrentResultToString(res)+" - "+lock);
}
return res;
@@ -611,7 +611,7 @@ public abstract class GLContextImpl extends GLContext {
shareWith.getDrawableImpl().unlockSurface();
}
}
- if (DEBUG_TRACE_SWITCH) {
+ if ( DEBUG_TRACE_SWITCH ) {
if(created) {
System.err.println(getThreadName() + ": Create GL context OK: obj " + toHexString(hashCode()) + ", ctx " + toHexString(contextHandle) + ", surf "+toHexString(drawable.getHandle())+" for " + getClass().getName()+" - "+getGLVersion());
// Thread.dumpStack();
@@ -811,7 +811,7 @@ public abstract class GLContextImpl extends GLContext {
if(PROFILE_ALIASING) {
hasGL3 = true;
}
- resetStates(); // clean this context states, since creation was temporary
+ resetStates(); // clean context states, since creation was temporary
}
}
if(!hasGL3) {
@@ -1301,7 +1301,7 @@ public abstract class GLContextImpl extends GLContext {
// Only validate if a valid int version was fetched, otherwise cont. w/ version-string method -> 3.0 > Version || Version > MAX!
if ( GLContext.isValidGLVersion(glIntMajor[0], glIntMinor[0]) ) {
if( glIntMajor[0]<major || ( glIntMajor[0]==major && glIntMinor[0]<minor ) || 0 == major ) {
- if( strictMatch && 0 < major ) {
+ if( strictMatch && 2 < major ) { // relaxed match for versions major < 3 requests, last resort!
if(DEBUG) {
System.err.println(getThreadName() + ": GLContext.setGLFuncAvail.X: FAIL, GL version mismatch (Int): "+GLContext.getGLVersion(major, minor, ctxProfileBits, null)+" -> "+glVersion+", "+glIntMajor[0]+"."+glIntMinor[0]);
}
@@ -1326,7 +1326,7 @@ public abstract class GLContextImpl extends GLContext {
// Only validate if a valid string version was fetched -> MIN > Version || Version > MAX!
if( null != strGLVersionNumber ) {
if( strGLVersionNumber.compareTo(setGLVersionNumber) < 0 || 0 == major ) {
- if( strictMatch && 0 < major ) {
+ if( strictMatch && 2 < major ) { // relaxed match for versions major < 3 requests, last resort!
if(DEBUG) {
System.err.println(getThreadName() + ": GLContext.setGLFuncAvail.X: FAIL, GL version mismatch (String): "+GLContext.getGLVersion(major, minor, ctxProfileBits, null)+" -> "+glVersion+", "+strGLVersionNumber);
}
@@ -1462,29 +1462,55 @@ public abstract class GLContextImpl extends GLContext {
final boolean hwAccel = 0 == ( ctp & GLContext.CTX_IMPL_ACCEL_SOFT );
final boolean compatCtx = 0 != ( ctp & GLContext.CTX_PROFILE_COMPAT );
+ //
// OS related quirks
+ //
if( Platform.getOSType() == Platform.OSType.MACOS ) {
- final int quirk1 = GLRendererQuirks.NoOffscreenBitmap;
- if(DEBUG) {
- System.err.println("Quirk: "+GLRendererQuirks.toString(quirk1)+": cause: OS "+Platform.getOSType());
+ //
+ // OSX
+ //
+ {
+ final int quirk = GLRendererQuirks.NoOffscreenBitmap;
+ if(DEBUG) {
+ System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: OS "+Platform.getOSType());
+ }
+ quirks[i++] = quirk;
+ }
+
+ final VersionNumber OSXVersion173 = new VersionNumber(1,7,3);
+ if( Platform.getOSVersionNumber().compareTo(OSXVersion173) < 0 && glRendererLowerCase.contains("nvidia") ) {
+ final int quirk = GLRendererQuirks.GLFlushBeforeRelease;
+ if(DEBUG) {
+ System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: OS "+Platform.getOSType()+", OS Version "+Platform.getOSVersionNumber()+", Renderer "+glRenderer);
+ }
+ quirks[i++] = quirk;
}
- quirks[i++] = quirk1;
} else if( Platform.getOSType() == Platform.OSType.WINDOWS ) {
+ //
+ // WINDOWS
+ //
final int quirk = GLRendererQuirks.NoDoubleBufferedBitmap;
if(DEBUG) {
System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: OS "+Platform.getOSType());
}
quirks[i++] = quirk;
- }
-
- // Renderer related quirks, may also involve OS
- if( Platform.OSType.ANDROID == Platform.getOSType() && glRendererLowerCase.contains("powervr") ) {
- final int quirk = GLRendererQuirks.NoSetSwapInterval;
- if(DEBUG) {
- System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: OS "+Platform.getOSType() + " / Renderer " + glRenderer);
+ } else if( Platform.OSType.ANDROID == Platform.getOSType() ) {
+ //
+ // ANDROID
+ //
+ // Renderer related quirks, may also involve OS
+ if( glRendererLowerCase.contains("powervr") ) {
+ final int quirk = GLRendererQuirks.NoSetSwapInterval;
+ if(DEBUG) {
+ System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: OS "+Platform.getOSType() + " / Renderer " + glRenderer);
+ }
+ quirks[i++] = quirk;
}
- quirks[i++] = quirk;
}
+
+ //
+ // RENDERER related quirks
+ //
if( glRendererLowerCase.contains("mesa") || glRendererLowerCase.contains("gallium") ) {
{
final int quirk = GLRendererQuirks.NoSetSwapIntervalPostRetarget;
diff --git a/src/jogl/classes/jogamp/opengl/GLVersionNumber.java b/src/jogl/classes/jogamp/opengl/GLVersionNumber.java
index 1004f04c6..83815f7a4 100644
--- a/src/jogl/classes/jogamp/opengl/GLVersionNumber.java
+++ b/src/jogl/classes/jogamp/opengl/GLVersionNumber.java
@@ -29,6 +29,9 @@
package jogamp.opengl;
import java.util.StringTokenizer;
+
+import javax.media.opengl.GLContext;
+
import com.jogamp.common.util.VersionNumber;
/**
@@ -90,9 +93,11 @@ class GLVersionNumber extends VersionNumber {
// Avoid possibly confusing situations by putting some
// constraints on the upgrades we do to the major and
// minor versions
- if ((altMajor == val[0] && altMinor > val[1]) || altMajor == val[0] + 1) {
- val[0] = altMajor;
- val[1] = altMinor;
+ if ( (altMajor == val[0] && altMinor > val[1]) || altMajor == val[0] + 1 ) {
+ if( GLContext.isValidGLVersion(altMajor, altMinor) ) {
+ val[0] = altMajor;
+ val[1] = altMinor;
+ }
}
}
}
diff --git a/src/jogl/classes/jogamp/opengl/awt/AWTThreadingPlugin.java b/src/jogl/classes/jogamp/opengl/awt/AWTThreadingPlugin.java
index 983f11133..ae8969d07 100644
--- a/src/jogl/classes/jogamp/opengl/awt/AWTThreadingPlugin.java
+++ b/src/jogl/classes/jogamp/opengl/awt/AWTThreadingPlugin.java
@@ -94,11 +94,7 @@ public class AWTThreadingPlugin implements ToolkitThreadingPlugin {
// QFT which is not allowed. For now, on X11 platforms,
// continue to perform this work on the EDT.
if (wait && Java2D.isOGLPipelineActive() && !ThreadingImpl.isX11()) {
- if(wait) {
- Java2D.invokeWithOGLContextCurrent(null, r);
- } else {
-
- }
+ Java2D.invokeWithOGLContextCurrent(null, r);
} else {
AWTEDTExecutor.singleton.invoke(wait, r);
}
diff --git a/src/jogl/classes/jogamp/opengl/awt/Java2D.java b/src/jogl/classes/jogamp/opengl/awt/Java2D.java
index 3dbfefb19..edf9e89f8 100644
--- a/src/jogl/classes/jogamp/opengl/awt/Java2D.java
+++ b/src/jogl/classes/jogamp/opengl/awt/Java2D.java
@@ -69,6 +69,7 @@ public class Java2D {
private static boolean DEBUG = Debug.debug("Java2D");
private static boolean isHeadless;
private static boolean isOGLPipelineActive;
+ private static boolean isOGLPipelineResourceCompatible;
private static Method invokeWithOGLContextCurrentMethod;
private static Method isQueueFlusherThreadMethod;
private static Method getOGLViewportMethod;
@@ -124,19 +125,37 @@ public class Java2D {
isHeadless = true;
// Figure out whether the default graphics configuration is an
// OpenGL graphics configuration
- GraphicsConfiguration cfg =
- GraphicsEnvironment.getLocalGraphicsEnvironment().
- getDefaultScreenDevice().
- getDefaultConfiguration();
+ final GraphicsConfiguration cfg;
+ final String cfgName;
+ final boolean java2dOGLDisabledByOS = Platform.OS_TYPE == Platform.OSType.MACOS;
+ final boolean java2dOGLDisabledByProp;
+ {
+ boolean enabled = true;
+ final String sVal = System.getProperty("sun.java2d.opengl");
+ if( null != sVal ) {
+ enabled = Boolean.valueOf(sVal);
+ }
+ java2dOGLDisabledByProp = !enabled;
+ }
+ if( !java2dOGLDisabledByProp && !java2dOGLDisabledByOS ) {
+ cfg = GraphicsEnvironment.getLocalGraphicsEnvironment().
+ getDefaultScreenDevice().getDefaultConfiguration();
+ cfgName = cfg.getClass().getName();
+ } else {
+ if (DEBUG) {
+ System.err.println("Java2D support disabled: by Property "+java2dOGLDisabledByProp+", by OS "+java2dOGLDisabledByOS);
+ }
+ cfg = null;
+ cfgName = "nil";
+ }
// If we get here, we aren't running in headless mode
isHeadless = false;
- String name = cfg.getClass().getName();
if (DEBUG) {
- System.err.println("Java2D support: default GraphicsConfiguration = " + name);
+ System.err.println("Java2D support: default GraphicsConfiguration = " + cfgName);
}
- isOGLPipelineActive = Platform.OS_TYPE != Platform.OSType.MACOS &&
- (name.startsWith("sun.java2d.opengl"));
-
+ isOGLPipelineActive = cfgName.startsWith("sun.java2d.opengl");
+ isOGLPipelineResourceCompatible = isOGLPipelineActive;
+
if (isOGLPipelineActive) {
try {
// Try to get methods we need to integrate
@@ -152,99 +171,101 @@ public class Java2D {
new Class[] {});
isQueueFlusherThreadMethod.setAccessible(true);
- getOGLViewportMethod = utils.getDeclaredMethod("getOGLViewport",
- new Class[] {
- Graphics.class,
- Integer.TYPE,
- Integer.TYPE
- });
- getOGLViewportMethod.setAccessible(true);
-
- getOGLScissorBoxMethod = utils.getDeclaredMethod("getOGLScissorBox",
- new Class[] {
- Graphics.class
- });
- getOGLScissorBoxMethod.setAccessible(true);
-
- getOGLSurfaceIdentifierMethod = utils.getDeclaredMethod("getOGLSurfaceIdentifier",
+ if( isOGLPipelineResourceCompatible ) {
+ getOGLViewportMethod = utils.getDeclaredMethod("getOGLViewport",
+ new Class[] {
+ Graphics.class,
+ Integer.TYPE,
+ Integer.TYPE
+ });
+ getOGLViewportMethod.setAccessible(true);
+
+ getOGLScissorBoxMethod = utils.getDeclaredMethod("getOGLScissorBox",
+ new Class[] {
+ Graphics.class
+ });
+ getOGLScissorBoxMethod.setAccessible(true);
+
+ getOGLSurfaceIdentifierMethod = utils.getDeclaredMethod("getOGLSurfaceIdentifier",
+ new Class[] {
+ Graphics.class
+ });
+ getOGLSurfaceIdentifierMethod.setAccessible(true);
+
+ // Try to get additional methods required for proper FBO support
+ fbObjectSupportInitialized = true;
+ try {
+ invokeWithOGLSharedContextCurrentMethod = utils.getDeclaredMethod("invokeWithOGLSharedContextCurrent",
+ new Class[] {
+ GraphicsConfiguration.class,
+ Runnable.class
+ });
+ invokeWithOGLSharedContextCurrentMethod.setAccessible(true);
+
+ getOGLSurfaceTypeMethod = utils.getDeclaredMethod("getOGLSurfaceType",
new Class[] {
Graphics.class
});
- getOGLSurfaceIdentifierMethod.setAccessible(true);
-
- // Try to get additional methods required for proper FBO support
- fbObjectSupportInitialized = true;
- try {
- invokeWithOGLSharedContextCurrentMethod = utils.getDeclaredMethod("invokeWithOGLSharedContextCurrent",
- new Class[] {
- GraphicsConfiguration.class,
- Runnable.class
- });
- invokeWithOGLSharedContextCurrentMethod.setAccessible(true);
-
- getOGLSurfaceTypeMethod = utils.getDeclaredMethod("getOGLSurfaceType",
- new Class[] {
- Graphics.class
- });
- getOGLSurfaceTypeMethod.setAccessible(true);
- } catch (Exception e) {
- fbObjectSupportInitialized = false;
- if (DEBUG) {
- e.printStackTrace();
- System.err.println("Info: Disabling Java2D/JOGL FBO support");
- }
- }
-
- // Try to get an additional method for FBO support in recent Mustang builds
- try {
- getOGLTextureTypeMethod = utils.getDeclaredMethod("getOGLTextureType",
- new Class[] {
- Graphics.class
- });
- getOGLTextureTypeMethod.setAccessible(true);
- } catch (Exception e) {
- if (DEBUG) {
- e.printStackTrace();
- System.err.println("Info: GL_ARB_texture_rectangle FBO support disabled");
- }
- }
-
- // Try to set up APIs for enabling the bridge on OS X,
- // where it isn't possible to create generalized
- // external GLDrawables
- Class<?> cglSurfaceData = null;
- try {
- cglSurfaceData = Class.forName("sun.java2d.opengl.CGLSurfaceData");
- } catch (Exception e) {
- if (DEBUG) {
- e.printStackTrace();
- System.err.println("Info: Unable to find class sun.java2d.opengl.CGLSurfaceData for OS X");
- }
- }
- if (cglSurfaceData != null) {
- // FIXME: for now, assume that FBO support is not enabled on OS X
- fbObjectSupportInitialized = false;
-
- // We need to find these methods in order to make the bridge work on OS X
- createOGLContextOnSurfaceMethod = cglSurfaceData.getDeclaredMethod("createOGLContextOnSurface",
- new Class[] {
- Graphics.class,
- Long.TYPE
- });
- createOGLContextOnSurfaceMethod.setAccessible(true);
-
- makeOGLContextCurrentOnSurfaceMethod = cglSurfaceData.getDeclaredMethod("makeOGLContextCurrentOnSurface",
- new Class[] {
- Graphics.class,
- Long.TYPE
- });
- makeOGLContextCurrentOnSurfaceMethod.setAccessible(true);
-
- destroyOGLContextMethod = cglSurfaceData.getDeclaredMethod("destroyOGLContext",
- new Class[] {
- Long.TYPE
- });
- destroyOGLContextMethod.setAccessible(true);
+ getOGLSurfaceTypeMethod.setAccessible(true);
+ } catch (Exception e) {
+ fbObjectSupportInitialized = false;
+ if (DEBUG) {
+ e.printStackTrace();
+ System.err.println("Info: Disabling Java2D/JOGL FBO support");
+ }
+ }
+
+ // Try to get an additional method for FBO support in recent Mustang builds
+ try {
+ getOGLTextureTypeMethod = utils.getDeclaredMethod("getOGLTextureType",
+ new Class[] {
+ Graphics.class
+ });
+ getOGLTextureTypeMethod.setAccessible(true);
+ } catch (Exception e) {
+ if (DEBUG) {
+ e.printStackTrace();
+ System.err.println("Info: GL_ARB_texture_rectangle FBO support disabled");
+ }
+ }
+
+ // Try to set up APIs for enabling the bridge on OS X,
+ // where it isn't possible to create generalized
+ // external GLDrawables
+ Class<?> cglSurfaceData = null;
+ try {
+ cglSurfaceData = Class.forName("sun.java2d.opengl.CGLSurfaceData");
+ } catch (Exception e) {
+ if (DEBUG) {
+ e.printStackTrace();
+ System.err.println("Info: Unable to find class sun.java2d.opengl.CGLSurfaceData for OS X");
+ }
+ }
+ if (cglSurfaceData != null) {
+ // FIXME: for now, assume that FBO support is not enabled on OS X
+ fbObjectSupportInitialized = false;
+
+ // We need to find these methods in order to make the bridge work on OS X
+ createOGLContextOnSurfaceMethod = cglSurfaceData.getDeclaredMethod("createOGLContextOnSurface",
+ new Class[] {
+ Graphics.class,
+ Long.TYPE
+ });
+ createOGLContextOnSurfaceMethod.setAccessible(true);
+
+ makeOGLContextCurrentOnSurfaceMethod = cglSurfaceData.getDeclaredMethod("makeOGLContextCurrentOnSurface",
+ new Class[] {
+ Graphics.class,
+ Long.TYPE
+ });
+ makeOGLContextCurrentOnSurfaceMethod.setAccessible(true);
+
+ destroyOGLContextMethod = cglSurfaceData.getDeclaredMethod("destroyOGLContext",
+ new Class[] {
+ Long.TYPE
+ });
+ destroyOGLContextMethod.setAccessible(true);
+ }
}
} catch (Exception e) {
catched = e;
@@ -252,6 +273,7 @@ public class Java2D {
System.err.println("Info: Disabling Java2D/JOGL integration");
}
isOGLPipelineActive = false;
+ isOGLPipelineResourceCompatible = false;
}
}
} catch (HeadlessException e) {
@@ -265,7 +287,7 @@ public class Java2D {
if(null != catched) {
catched.printStackTrace();
}
- System.err.println("JOGL/Java2D integration " + (isOGLPipelineActive ? "enabled" : "disabled"));
+ System.err.println("JOGL/Java2D OGL Pipeline active " + isOGLPipelineActive + ", resourceCompatible "+isOGLPipelineResourceCompatible);
}
return null;
}
@@ -275,6 +297,10 @@ public class Java2D {
public static boolean isOGLPipelineActive() {
return isOGLPipelineActive;
}
+
+ public static boolean isOGLPipelineResourceCompatible() {
+ return isOGLPipelineResourceCompatible;
+ }
public static boolean isFBOEnabled() {
return fbObjectSupportInitialized;
@@ -330,7 +356,7 @@ public class Java2D {
false if the passed GraphicsConfiguration was not an OpenGL
GraphicsConfiguration. */
public static boolean invokeWithOGLSharedContextCurrent(GraphicsConfiguration g, Runnable r) throws GLException {
- checkActive();
+ checkCompatible();
try {
AWTUtil.lockToolkit();
@@ -355,7 +381,7 @@ public class Java2D {
public static Rectangle getOGLViewport(Graphics g,
int componentWidth,
int componentHeight) {
- checkActive();
+ checkCompatible();
try {
return (Rectangle) getOGLViewportMethod.invoke(null, new Object[] {g,
@@ -375,7 +401,7 @@ public class Java2D {
passed to a call to glScissor(). Should only be called from the
Queue Flusher Thread. */
public static Rectangle getOGLScissorBox(Graphics g) {
- checkActive();
+ checkCompatible();
try {
return (Rectangle) getOGLScissorBoxMethod.invoke(null, new Object[] {g});
@@ -393,7 +419,7 @@ public class Java2D {
created (and the old ones destroyed). Should only be called from
the Queue Flusher Thread.*/
public static Object getOGLSurfaceIdentifier(Graphics g) {
- checkActive();
+ checkCompatible();
try {
return getOGLSurfaceIdentifierMethod.invoke(null, new Object[] {g});
@@ -408,7 +434,7 @@ public class Java2D {
object. This indicates, in particular, whether Java2D is
currently rendering into a pbuffer or FBO. */
public static int getOGLSurfaceType(Graphics g) {
- checkActive();
+ checkCompatible();
try {
// FIXME: fallback path for pre-b73 (?) Mustang builds -- remove
@@ -429,7 +455,7 @@ public class Java2D {
object assuming it is rendering to an FBO. Returns either
GL_TEXTURE_2D or GL_TEXTURE_RECTANGLE_ARB. */
public static int getOGLTextureType(Graphics g) {
- checkActive();
+ checkCompatible();
if (getOGLTextureTypeMethod == null) {
return GL.GL_TEXTURE_2D;
@@ -483,7 +509,7 @@ public class Java2D {
associated with the given Graphics object, sharing textures and
display lists with the specified (CGLContextObj) share context. */
public static long createOGLContextOnSurface(Graphics g, long shareCtx) {
- checkActive();
+ checkCompatible();
try {
return ((Long) createOGLContextOnSurfaceMethod.invoke(null, new Object[] { g, new Long(shareCtx) })).longValue();
@@ -497,7 +523,7 @@ public class Java2D {
/** (Mac OS X-specific) Makes the given OpenGL context current on
the surface associated with the given Graphics object. */
public static boolean makeOGLContextCurrentOnSurface(Graphics g, long ctx) {
- checkActive();
+ checkCompatible();
try {
return ((Boolean) makeOGLContextCurrentOnSurfaceMethod.invoke(null, new Object[] { g, new Long(ctx) })).booleanValue();
@@ -510,7 +536,7 @@ public class Java2D {
/** (Mac OS X-specific) Destroys the given OpenGL context. */
public static void destroyOGLContext(long ctx) {
- checkActive();
+ checkCompatible();
try {
destroyOGLContextMethod.invoke(null, new Object[] { new Long(ctx) });
@@ -527,7 +553,13 @@ public class Java2D {
private static void checkActive() {
if (!isOGLPipelineActive()) {
- throw new GLException("Java2D OpenGL pipeline not active (or necessary support not present)");
+ throw new GLException("Java2D OpenGL pipeline not active");
+ }
+ }
+
+ private static void checkCompatible() {
+ if ( !isOGLPipelineResourceCompatible() ) {
+ throw new GLException("Java2D OpenGL pipeline not resource compatible");
}
}
@@ -562,7 +594,7 @@ public class Java2D {
// Note 2: the first execution of this method must not be from the
// Java2D Queue Flusher Thread.
- if (isOGLPipelineActive() &&
+ if (isOGLPipelineResourceCompatible() &&
isFBOEnabled() &&
!initializedJ2DFBOShareContext) {
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
index 838a0387d..3825f855c 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
@@ -74,6 +74,7 @@ import com.jogamp.common.util.VersionNumber;
import com.jogamp.gluegen.runtime.ProcAddressTable;
import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver;
import com.jogamp.opengl.GLExtensions;
+import com.jogamp.opengl.GLRendererQuirks;
import com.jogamp.opengl.util.PMVMatrix;
import com.jogamp.opengl.util.glsl.ShaderCode;
import com.jogamp.opengl.util.glsl.ShaderProgram;
@@ -687,13 +688,33 @@ public abstract class MacOSXCGLContext extends GLContextImpl
} else {
gl3ShaderProgramName = 0;
}
- nsOpenGLLayer = CGL.createNSOpenGLLayer(ctx, gl3ShaderProgramName, nsOpenGLLayerPFmt, pbufferHandle, texID, chosenCaps.isBackgroundOpaque(), lastWidth, lastHeight);
- nsOpenGLLayerPFmt = 0; // NSOpenGLLayer will release pfmt
- if (DEBUG) {
- System.err.println("NS create nsOpenGLLayer "+toHexString(nsOpenGLLayer)+" w/ pbuffer "+toHexString(pbufferHandle)+", texID "+texID+", texSize "+lastWidth+"x"+lastHeight+", "+drawable);
+
+ /**
+ * Perform NSOpenGLLayer creation and attaching on main-thread,
+ * hence release the lock on our context - which will be used to
+ * create a shared context within NSOpenGLLayer.
+ */
+ final long cglCtx = CGL.getCGLContext(ctx);
+ if(0 == cglCtx) {
+ throw new InternalError("Null CGLContext for: "+this);
+ }
+ final boolean ctxUnlocked = CGL.kCGLNoError == CGL.CGLUnlockContext(cglCtx);
+ try {
+ nsOpenGLLayer = CGL.createNSOpenGLLayer(ctx, gl3ShaderProgramName, nsOpenGLLayerPFmt, pbufferHandle, texID, chosenCaps.isBackgroundOpaque(), lastWidth, lastHeight);
+ nsOpenGLLayerPFmt = 0; // NSOpenGLLayer will release pfmt
+ if (DEBUG) {
+ System.err.println("NS create nsOpenGLLayer "+toHexString(nsOpenGLLayer)+" w/ pbuffer "+toHexString(pbufferHandle)+", texID "+texID+", texSize "+lastWidth+"x"+lastHeight+", "+drawable);
+ }
+ backingLayerHost.attachSurfaceLayer(nsOpenGLLayer);
+ setSwapInterval(1); // enabled per default in layered surface
+ } finally {
+ if( ctxUnlocked ) {
+ if( CGL.kCGLNoError != CGL.CGLLockContext(cglCtx) ) {
+ throw new InternalError("Could not re-lock CGLContext for: "+this);
+ }
+ }
}
- backingLayerHost.attachSurfaceLayer(nsOpenGLLayer);
- setSwapInterval(1); // enabled per default in layered surface
+ backingLayerHost.layoutSurfaceLayer();
} else {
lastWidth = drawable.getWidth();
lastHeight = drawable.getHeight();
@@ -773,7 +794,9 @@ public abstract class MacOSXCGLContext extends GLContextImpl
@Override
public boolean release(long ctx) {
try {
- gl.glFlush(); // w/o glFlush()/glFinish() OSX < 10.7 (NVidia driver) may freeze
+ if( hasRendererQuirk(GLRendererQuirks.GLFlushBeforeRelease) && null != MacOSXCGLContext.this.getGLProcAddressTable() ) {
+ gl.glFlush();
+ }
} catch (GLException gle) {
if(DEBUG) {
System.err.println("MacOSXCGLContext.NSOpenGLImpl.release: INFO: glFlush() catched exception:");
@@ -953,7 +976,9 @@ public abstract class MacOSXCGLContext extends GLContextImpl
@Override
public boolean release(long ctx) {
try {
- gl.glFlush(); // w/o glFlush()/glFinish() OSX < 10.7 (NVidia driver) may freeze
+ if( hasRendererQuirk(GLRendererQuirks.GLFlushBeforeRelease) && null != MacOSXCGLContext.this.getGLProcAddressTable() ) {
+ gl.glFlush();
+ }
} catch (GLException gle) {
if(DEBUG) {
System.err.println("MacOSXCGLContext.CGLImpl.release: INFO: glFlush() catched exception:");
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java
index e76c39805..9f034adb1 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java
@@ -346,7 +346,7 @@ public class WindowsWGLContext extends GLContextImpl {
if(glCaps.getGLProfile().isGL3()) {
WGL.wglMakeCurrent(0, 0);
WGL.wglDeleteContext(temp_ctx);
- throw new GLException("WindowsWGLContext.createContext ctx !ARB, context > GL2 requested "+getGLVersion());
+ throw new GLException(getThreadName()+": WindowsWGLContex.createContextImpl ctx !ARB, profile > GL2 requested (OpenGL >= 3.0.1). Requested: "+glCaps.getGLProfile()+", current: "+getGLVersion());
}
if(DEBUG) {
System.err.println("WindowsWGLContext.createContext failed, fall back to !ARB context "+getGLVersion());
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java
index feda64f30..575ff51b8 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java
@@ -166,7 +166,7 @@ public abstract class X11GLXContext extends GLContextImpl {
throw new InternalError("Given readDrawable but no driver support");
}
} catch (RuntimeException re) {
- if(DEBUG_TRACE_SWITCH) {
+ if( DEBUG_TRACE_SWITCH ) {
System.err.println(getThreadName()+": Warning: X11GLXContext.glXMakeContextCurrent failed: "+re+", with "+
"dpy "+toHexString(dpy)+
", write "+toHexString(writeDrawable)+
@@ -374,7 +374,7 @@ public abstract class X11GLXContext extends GLContextImpl {
if(glp.isGL3()) {
glXMakeContextCurrent(display, 0, 0, 0);
GLX.glXDestroyContext(display, temp_ctx);
- throw new GLException(getThreadName()+": X11GLXContext.createContextImpl ctx !ARB, context > GL2 requested - requested: "+glp+", current: "+getGLVersion()+", ");
+ throw new GLException(getThreadName()+": X11GLXContext.createContextImpl ctx !ARB, profile > GL2 requested (OpenGL >= 3.0.1). Requested: "+glp+", current: "+getGLVersion());
}
if(DEBUG) {
System.err.println(getThreadName()+": X11GLXContext.createContextImpl failed, fall back to !ARB context "+getGLVersion());
diff --git a/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m b/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m
index b37930587..2cf74380c 100644
--- a/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m
+++ b/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m
@@ -1,6 +1,7 @@
#import "MacOSXWindowSystemInterface.h"
#import <QuartzCore/QuartzCore.h>
#import <pthread.h>
+#import "NativeWindowProtocols.h"
#include "timespec.h"
#import <OpenGL/glext.h>
@@ -41,6 +42,8 @@ extern GLboolean glIsVertexArray (GLuint array);
//
// #define DBG_PERF 1
+// #define DBG_LIFECYCLE 1
+
/**
* Capture setView(NULL), which produces a 'invalid drawable' message
*
@@ -52,6 +55,10 @@ extern GLboolean glIsVertexArray (GLuint array);
- (id)initWithFormat:(NSOpenGLPixelFormat *)format shareContext:(NSOpenGLContext *)share;
- (void)setView:(NSView *)view;
- (void)update;
+#ifdef DBG_LIFECYCLE
+- (id)retain;
+- (oneway void)release;
+#endif
- (void)dealloc;
@end
@@ -69,8 +76,11 @@ extern GLboolean glIsVertexArray (GLuint array);
- (void)setView:(NSView *)view
{
DBG_PRINT("MyNSOpenGLContext.setView: this.0 %p, view %p\n", self, view);
+ // NSLog(@"MyNSOpenGLContext::setView: %@",[NSThread callStackSymbols]);
if(NULL != view) {
[super setView:view];
+ } else {
+ [self clearDrawable];
}
DBG_PRINT("MyNSOpenGLContext.setView.X\n");
}
@@ -82,19 +92,47 @@ extern GLboolean glIsVertexArray (GLuint array);
DBG_PRINT("MyNSOpenGLContext.update.X\n");
}
+#ifdef DBG_LIFECYCLE
+
+- (id)retain
+{
+ DBG_PRINT("MyNSOpenGLContext::retain.0: %p (refcnt %d)\n", self, (int)[self retainCount]);
+ // NSLog(@"MyNSOpenGLContext::retain: %@",[NSThread callStackSymbols]);
+ id o = [super retain];
+ DBG_PRINT("MyNSOpenGLContext::retain.X: %p (refcnt %d)\n", o, (int)[o retainCount]);
+ return o;
+}
+
+- (oneway void)release
+{
+ DBG_PRINT("MyNSOpenGLContext::release.0: %p (refcnt %d)\n", self, (int)[self retainCount]);
+ [super release];
+ // DBG_PRINT("MyNSOpenGLContext::release.X: %p (refcnt %d)\n", self, (int)[self retainCount]);
+}
+
+#endif
+
- (void)dealloc
{
- DBG_PRINT("MyNSOpenGLContext.dealloc: this.0 %p\n", self);
+ CGLContextObj cglCtx = [self CGLContextObj];
+
+ DBG_PRINT("MyNSOpenGLContext::dealloc.0 %p (refcnt %d) - CGL-Ctx %p\n", self, (int)[self retainCount], cglCtx);
+ [self clearDrawable];
+ if( NULL != cglCtx ) {
+ CGLDestroyContext( cglCtx );
+ }
[super dealloc];
- DBG_PRINT("MyNSOpenGLContext.dealloc.X: %p\n", self);
+ // DBG_PRINT("MyNSOpenGLContext.dealloc.X: %p\n", self);
}
@end
-@interface MyNSOpenGLLayer: NSOpenGLLayer
+@interface MyNSOpenGLLayer: NSOpenGLLayer <NWDedicatedSize>
{
@private
GLfloat gl_texCoords[8];
+ NSOpenGLContext* myCtx;
+ Bool isGLEnabled;
@protected
NSOpenGLContext* parentCtx;
@@ -106,8 +144,8 @@ extern GLboolean glIsVertexArray (GLuint array);
NSOpenGLPixelFormat* parentPixelFmt;
int texWidth;
int texHeight;
- int newTexWidth;
- int newTexHeight;
+ int dedicatedWidth;
+ int dedicatedHeight;
volatile NSOpenGLPixelBuffer* pbuffer;
volatile GLuint textureID;
volatile NSOpenGLPixelBuffer* newPBuffer;
@@ -136,7 +174,17 @@ extern GLboolean glIsVertexArray (GLuint array);
texWidth: (int) texWidth
texHeight: (int) texHeight;
-- (Bool) validateTexSizeWithNewSize;
+- (void)releaseLayer;
+- (void)deallocPBuffer;
+- (void)disableAnimation;
+- (void)pauseAnimation:(Bool)pause;
+- (void)setSwapInterval:(int)interval;
+- (void)tick;
+- (void)waitUntilRenderSignal: (long) to_micros;
+- (Bool)isGLSourceValid;
+
+- (void) setGLEnabled: (Bool) enable;
+- (Bool) validateTexSizeWithDedicatedSize;
- (Bool) validateTexSize: (int) _texWidth texHeight: (int) _texHeight;
- (void) setTextureID: (int) _texID;
@@ -144,17 +192,22 @@ extern GLboolean glIsVertexArray (GLuint array);
- (void) setNewPBuffer: (NSOpenGLPixelBuffer*)p;
- (void) applyNewPBuffer;
+- (void)setDedicatedSize:(CGSize)size; // @NWDedicatedSize
+- (CGRect)fixMyFrame;
+- (CGRect)fixSuperPosition;
+- (id<CAAction>)actionForKey:(NSString *)key ;
- (NSOpenGLPixelFormat *)openGLPixelFormatForDisplayMask:(uint32_t)mask;
- (NSOpenGLContext *)openGLContextForPixelFormat:(NSOpenGLPixelFormat *)pixelFormat;
-- (void)disableAnimation;
-- (void)pauseAnimation:(Bool)pause;
-- (void)deallocPBuffer;
-- (void)releaseLayer;
+- (BOOL)canDrawInOpenGLContext:(NSOpenGLContext *)context pixelFormat:(NSOpenGLPixelFormat *)pixelFormat
+ forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp;
+- (void)drawInOpenGLContext:(NSOpenGLContext *)context pixelFormat:(NSOpenGLPixelFormat *)pixelFormat
+ forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp;
+
+#ifdef DBG_LIFECYCLE
+- (id)retain;
+- (oneway void)release;
+#endif
- (void)dealloc;
-- (void)setSwapInterval:(int)interval;
-- (void)tick;
-- (void)waitUntilRenderSignal: (long) to_micros;
-- (Bool)isGLSourceValid;
@end
@@ -209,6 +262,7 @@ static const GLfloat gl_verts[] = {
pthread_mutex_init(&renderLock, &renderLockAttr); // recursive
pthread_cond_init(&renderSignal, NULL); // no attribute
+ myCtx = NULL;
{
int i;
for(i=0; i<8; i++) {
@@ -226,9 +280,10 @@ static const GLfloat gl_verts[] = {
swapIntervalCounter = 0;
timespec_now(&lastWaitTime);
shallDraw = NO;
- newTexWidth = _texWidth;
- newTexHeight = _texHeight;
- [self validateTexSizeWithNewSize];
+ isGLEnabled = YES;
+ dedicatedWidth = _texWidth;
+ dedicatedHeight = _texHeight;
+ [self validateTexSizeWithDedicatedSize];
[self setTextureID: texID];
newPBuffer = NULL;
@@ -265,13 +320,6 @@ static const GLfloat gl_verts[] = {
}
}
if(NULL != displayLink) {
- cvres = CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(displayLink, [parentCtx CGLContextObj], [parentPixelFmt CGLPixelFormatObj]);
- if(kCVReturnSuccess != cvres) {
- DBG_PRINT("MyNSOpenGLLayer::init %p, CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext failed: %d\n", self, cvres);
- displayLink = NULL;
- }
- }
- if(NULL != displayLink) {
cvres = CVDisplayLinkSetOutputCallback(displayLink, renderMyNSOpenGLLayer, self);
if(kCVReturnSuccess != cvres) {
DBG_PRINT("MyNSOpenGLLayer::init %p, CVDisplayLinkSetOutputCallback failed: %d\n", self, cvres);
@@ -302,9 +350,15 @@ static const GLfloat gl_verts[] = {
return self;
}
-- (Bool) validateTexSizeWithNewSize
+- (void) setGLEnabled: (Bool) enable
{
- return [self validateTexSize: newTexWidth texHeight: newTexHeight];
+ DBG_PRINT("MyNSOpenGLLayer::setGLEnabled: %p, %d -> %d\n", self, (int)isGLEnabled, (int)enable);
+ isGLEnabled = enable;
+}
+
+- (Bool) validateTexSizeWithDedicatedSize
+{
+ return [self validateTexSize: dedicatedWidth texHeight: dedicatedHeight];
}
- (Bool) validateTexSize: (int) _texWidth texHeight: (int) _texHeight
@@ -312,12 +366,14 @@ static const GLfloat gl_verts[] = {
if(_texHeight != texHeight || _texWidth != texWidth) {
texWidth = _texWidth;
texHeight = _texHeight;
+ /**
CGRect lRect = [self bounds];
lRect.origin.x = 0;
lRect.origin.y = 0;
lRect.size.width = texWidth;
lRect.size.height = texHeight;
- [self setFrame: lRect];
+ [self setFrame: lRect]; */
+ CGRect lRect = [self fixMyFrame];
GLfloat texCoordWidth, texCoordHeight;
if(NULL != pbuffer) {
@@ -339,8 +395,14 @@ static const GLfloat gl_verts[] = {
gl_texCoords[5] = texCoordHeight;
gl_texCoords[4] = texCoordWidth;
gl_texCoords[6] = texCoordWidth;
+#ifdef VERBOSE_ON
+ DBG_PRINT("MyNSOpenGLLayer::validateTexSize %p -> tex %dx%d, bounds: %lf/%lf %lfx%lf\n",
+ self, texWidth, texHeight,
+ lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height);
+#endif
return YES;
} else {
+ [self fixMyFrame];
return NO;
}
}
@@ -407,26 +469,9 @@ static const GLfloat gl_verts[] = {
}
}
-- (NSOpenGLPixelFormat *)openGLPixelFormatForDisplayMask:(uint32_t)mask
-{
- DBG_PRINT("MyNSOpenGLLayer::openGLPixelFormatForDisplayMask: %p (refcnt %d) - parent-pfmt %p -> new-pfmt %p\n",
- self, (int)[self retainCount], parentPixelFmt, parentPixelFmt);
- return parentPixelFmt;
-}
-
-- (NSOpenGLContext *)openGLContextForPixelFormat:(NSOpenGLPixelFormat *)pixelFormat
-{
- DBG_PRINT("MyNSOpenGLLayer::openGLContextForPixelFormat.0: %p (refcnt %d) - pfmt %p, parent %p\n",
- self, (int)[self retainCount], pixelFormat, parentCtx);
- NSOpenGLContext * nctx = [[MyNSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:parentCtx];
- DBG_PRINT("MyNSOpenGLLayer::openGLContextForPixelFormat.X: new-ctx %p\n", nctx);
- return nctx;
-}
-
- (void)disableAnimation
{
- DBG_PRINT("MyNSOpenGLLayer::disableAnimation: %p (refcnt %d) - displayLink %p\n", self, (int)[self retainCount], displayLink);
- pthread_mutex_lock(&renderLock);
+ DBG_PRINT("MyNSOpenGLLayer::disableAnimation.0: %p (refcnt %d) - displayLink %p\n", self, (int)[self retainCount], displayLink);
[self setAsynchronous: NO];
if(NULL != displayLink) {
#ifdef HAS_CADisplayLink
@@ -438,35 +483,60 @@ static const GLfloat gl_verts[] = {
#endif
displayLink = NULL;
}
- pthread_mutex_unlock(&renderLock);
+ DBG_PRINT("MyNSOpenGLLayer::disableAnimation.X: %p (refcnt %d) - displayLink %p\n", self, (int)[self retainCount], displayLink);
}
- (void)releaseLayer
{
DBG_PRINT("MyNSOpenGLLayer::releaseLayer.0: %p (refcnt %d)\n", self, (int)[self retainCount]);
- pthread_mutex_lock(&renderLock);
[self disableAnimation];
+ pthread_mutex_lock(&renderLock);
[self deallocPBuffer];
- [[self openGLContext] release];
+ // [[self openGLContext] release];
+ if( NULL != myCtx ) {
+ [myCtx release];
+ myCtx = NULL;
+ }
+ parentCtx = NULL;
[parentPixelFmt release];
- [self release];
- DBG_PRINT("MyNSOpenGLLayer::releaseLayer.X: %p (refcnt %d)\n", self, (int)[self retainCount]);
pthread_mutex_unlock(&renderLock);
+ [self release];
+ DBG_PRINT("MyNSOpenGLLayer::releaseLayer.X: %p\n", self);
+}
+
+#ifdef DBG_LIFECYCLE
+
+- (id)retain
+{
+ DBG_PRINT("MyNSOpenGLLayer::retain.0: %p (refcnt %d)\n", self, (int)[self retainCount]);
+ // NSLog(@"MyNSOpenGLLayer::retain: %@",[NSThread callStackSymbols]);
+ id o = [super retain];
+ DBG_PRINT("MyNSOpenGLLayer::retain.X: %p (refcnt %d)\n", o, (int)[o retainCount]);
+ return o;
}
+- (oneway void)release
+{
+ DBG_PRINT("MyNSOpenGLLayer::release.0: %p (refcnt %d)\n", self, (int)[self retainCount]);
+ // NSLog(@"MyNSOpenGLLayer::release: %@",[NSThread callStackSymbols]);
+ [super release];
+ // DBG_PRINT("MyNSOpenGLLayer::release.X: %p (refcnt %d)\n", self, (int)[self retainCount]);
+}
+
+#endif
+
- (void)dealloc
{
DBG_PRINT("MyNSOpenGLLayer::dealloc.0 %p (refcnt %d)\n", self, (int)[self retainCount]);
// NSLog(@"MyNSOpenGLLayer::dealloc: %@",[NSThread callStackSymbols]);
-
- pthread_mutex_lock(&renderLock);
[self disableAnimation];
+ pthread_mutex_lock(&renderLock);
[self deallocPBuffer];
pthread_mutex_unlock(&renderLock);
pthread_cond_destroy(&renderSignal);
pthread_mutex_destroy(&renderLock);
[super dealloc];
- DBG_PRINT("MyNSOpenGLLayer::dealloc.X %p\n", self);
+ // DBG_PRINT("MyNSOpenGLLayer::dealloc.X %p\n", self);
}
- (Bool)isGLSourceValid
@@ -474,26 +544,114 @@ static const GLfloat gl_verts[] = {
return NULL != pbuffer || NULL != newPBuffer || 0 != textureID ;
}
-- (void)resizeWithOldSuperlayerSize:(CGSize)size
- {
- CGRect lRectS = [[self superlayer] bounds];
+// @NWDedicatedSize
+- (void)setDedicatedSize:(CGSize)size {
+ DBG_PRINT("MyNSOpenGLLayer::setDedicatedSize: %p, texSize %dx%d <- %lfx%lf\n",
+ self, texWidth, texHeight, size.width, size.height);
+
+ [CATransaction begin];
+ [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
+
+ dedicatedWidth = size.width;
+ dedicatedHeight = size.height;
- DBG_PRINT("MyNSOpenGLLayer::resizeWithOldSuperlayerSize: %p, texSize %dx%d, bounds: %lfx%lf -> %lfx%lf (refcnt %d)\n",
- self, texWidth, texHeight, size.width, size.height, lRectS.size.width, lRectS.size.height, (int)[self retainCount]);
+ CGRect rect = CGRectMake(0, 0, dedicatedWidth, dedicatedHeight);
+ [self setFrame: rect];
- newTexWidth = lRectS.size.width;
- newTexHeight = lRectS.size.height;
- shallDraw = [self isGLSourceValid];
- SYNC_PRINT("<SZ %dx%d>", newTexWidth, newTexHeight);
+ [CATransaction commit];
+}
- [super resizeWithOldSuperlayerSize: size];
+- (void) setFrame:(CGRect) frame {
+ CGRect rect = CGRectMake(0, 0, dedicatedWidth, dedicatedHeight);
+ [super setFrame: rect];
+}
+
+- (CGRect)fixMyFrame
+{
+ CGRect lRect = [self frame];
+
+ // With Java7 our root CALayer's frame gets off-limit -> force 0/0 origin!
+ if( lRect.origin.x!=0 || lRect.origin.y!=0 || lRect.size.width!=texWidth || lRect.size.height!=texHeight) {
+ DBG_PRINT("MyNSOpenGLLayer::fixMyFrame: %p, 0/0 texSize %dx%d -> Frame[%lf/%lf %lfx%lf]\n",
+ self, texWidth, texHeight,
+ lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height);
+
+ [CATransaction begin];
+ [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
+
+ lRect.origin.x = 0;
+ lRect.origin.y = 0;
+ lRect.size.width=texWidth;
+ lRect.size.height=texHeight;
+ [self setFrame: lRect];
+
+ [CATransaction commit];
+ }
+ return lRect;
+}
+
+- (CGRect)fixSuperPosition
+{
+ CALayer * superL = [self superlayer];
+ CGRect lRect = [superL frame];
+
+ // With Java7 our root CALayer's frame gets off-limit -> force 0/0 origin!
+ if( lRect.origin.x!=0 || lRect.origin.y!=0 ) {
+ DBG_PRINT("MyNSOpenGLLayer::fixSuperPosition: %p, 0/0 -> Super Frame[%lf/%lf %lfx%lf]\n",
+ self, lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height);
+
+ [CATransaction begin];
+ [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
+
+ lRect.origin.x = 0;
+ lRect.origin.y = 0;
+ [superL setPosition: lRect.origin];
+
+ [CATransaction commit];
+ }
+ return lRect;
+}
+
+- (id<CAAction>)actionForKey:(NSString *)key
+{
+ DBG_PRINT("MyNSOpenGLLayer::actionForKey.0 %p key %s -> NIL\n", self, [key UTF8String]);
+ return nil;
+ // return [super actionForKey: key];
+}
+
+- (NSOpenGLPixelFormat *)openGLPixelFormatForDisplayMask:(uint32_t)mask
+{
+ DBG_PRINT("MyNSOpenGLLayer::openGLPixelFormatForDisplayMask: %p (refcnt %d) - parent-pfmt %p -> new-pfmt %p\n",
+ self, (int)[self retainCount], parentPixelFmt, parentPixelFmt);
+ // We simply take over ownership of parent PixelFormat ..
+ return parentPixelFmt;
+}
+
+- (NSOpenGLContext *)openGLContextForPixelFormat:(NSOpenGLPixelFormat *)pixelFormat
+{
+ DBG_PRINT("MyNSOpenGLLayer::openGLContextForPixelFormat.0: %p (refcnt %d) - pfmt %p, parent %p, DisplayLink %p\n",
+ self, (int)[self retainCount], pixelFormat, parentCtx, displayLink);
+ // NSLog(@"MyNSOpenGLLayer::openGLContextForPixelFormat: %@",[NSThread callStackSymbols]);
+ myCtx = [[MyNSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:parentCtx];
+#ifndef HAS_CADisplayLink
+ if(NULL != displayLink) {
+ CVReturn cvres;
+ DBG_PRINT("MyNSOpenGLLayer::openGLContextForPixelFormat.1: setup DisplayLink %p\n", displayLink);
+ cvres = CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(displayLink, [myCtx CGLContextObj], [pixelFormat CGLPixelFormatObj]);
+ if(kCVReturnSuccess != cvres) {
+ DBG_PRINT("MyNSOpenGLLayer::init %p, CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext failed: %d\n", self, cvres);
+ }
+ }
+#endif
+ DBG_PRINT("MyNSOpenGLLayer::openGLContextForPixelFormat.X: new-ctx %p\n", myCtx);
+ return myCtx;
}
- (BOOL)canDrawInOpenGLContext:(NSOpenGLContext *)context pixelFormat:(NSOpenGLPixelFormat *)pixelFormat
forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp
{
- SYNC_PRINT("<? %d>", (int)shallDraw);
- return shallDraw;
+ SYNC_PRINT("<? %d, %d>", (int)shallDraw, (int)isGLEnabled);
+ return shallDraw && isGLEnabled;
}
- (void)drawInOpenGLContext:(NSOpenGLContext *)context pixelFormat:(NSOpenGLPixelFormat *)pixelFormat
@@ -503,7 +661,7 @@ static const GLfloat gl_verts[] = {
SYNC_PRINT("<* ");
// NSLog(@"MyNSOpenGLLayer::DRAW: %@",[NSThread callStackSymbols]);
- if( shallDraw && ( NULL != pbuffer || NULL != newPBuffer || 0 != textureID ) ) {
+ if( isGLEnabled && shallDraw && ( NULL != pbuffer || NULL != newPBuffer || 0 != textureID ) ) {
[context makeCurrentContext];
if( NULL != newPBuffer ) { // volatile OK
@@ -512,7 +670,7 @@ static const GLfloat gl_verts[] = {
GLenum textureTarget;
- Bool texSizeChanged = [self validateTexSizeWithNewSize];
+ Bool texSizeChanged = [self validateTexSizeWithDedicatedSize];
if( NULL != pbuffer ) {
if( texSizeChanged && 0 != textureID ) {
@@ -752,32 +910,34 @@ static const GLfloat gl_verts[] = {
@end
NSOpenGLLayer* createNSOpenGLLayer(NSOpenGLContext* ctx, int gl3ShaderProgramName, NSOpenGLPixelFormat* fmt, NSOpenGLPixelBuffer* p, uint32_t texID, Bool opaque, int texWidth, int texHeight) {
- // This simply crashes after dealloc() has been called .. ie. ref-count -> 0 too early ?
- // However using alloc/init, actual dealloc happens at JAWT destruction, hence too later IMHO.
- // return [[MyNSOpenGLLayer layer] setupWithContext:ctx pixelFormat: fmt pbuffer: p texIDArg: (GLuint)texID
- // opaque: opaque texWidth: texWidth texHeight: texHeight];
-
return [[[MyNSOpenGLLayer alloc] init] setupWithContext:ctx gl3ShaderProgramName: (GLuint)gl3ShaderProgramName pixelFormat: fmt pbuffer: p texIDArg: (GLuint)texID
opaque: opaque texWidth: texWidth texHeight: texHeight];
}
+
+void setNSOpenGLLayerEnabled(NSOpenGLLayer* layer, Bool enable) {
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
+ [l setGLEnabled: enable];
+ [pool release];
+}
void setNSOpenGLLayerSwapInterval(NSOpenGLLayer* layer, int interval) {
- MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
[l setSwapInterval: interval];
[pool release];
}
void waitUntilNSOpenGLLayerIsReady(NSOpenGLLayer* layer, long to_micros) {
- MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
[l waitUntilRenderSignal: to_micros];
[pool release];
}
void setNSOpenGLLayerNeedsDisplayFBO(NSOpenGLLayer* layer, uint32_t texID) {
- MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
Bool shallDraw;
// volatile OK
@@ -799,8 +959,8 @@ void setNSOpenGLLayerNeedsDisplayFBO(NSOpenGLLayer* layer, uint32_t texID) {
}
void setNSOpenGLLayerNeedsDisplayPBuffer(NSOpenGLLayer* layer, NSOpenGLPixelBuffer* p) {
- MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
Bool shallDraw;
if( NO == [l isSamePBuffer: p] ) {
@@ -825,16 +985,10 @@ void setNSOpenGLLayerNeedsDisplayPBuffer(NSOpenGLLayer* layer, NSOpenGLPixelBuff
}
void releaseNSOpenGLLayer(NSOpenGLLayer* layer) {
- MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
DBG_PRINT("MyNSOpenGLLayer::releaseNSOpenGLLayer.0: %p\n", l);
-
- if ( [NSThread isMainThread] == YES ) {
- [l releaseLayer];
- } else {
- [l performSelectorOnMainThread:@selector(releaseLayer) withObject:nil waitUntilDone:NO];
- }
-
+ [l releaseLayer];
DBG_PRINT("MyNSOpenGLLayer::releaseNSOpenGLLayer.X: %p\n", l);
[pool release];
}
diff --git a/src/jogl/native/macosx/MacOSXWindowSystemInterface.m b/src/jogl/native/macosx/MacOSXWindowSystemInterface.m
index e8925f8e8..f8faeb8d0 100644
--- a/src/jogl/native/macosx/MacOSXWindowSystemInterface.m
+++ b/src/jogl/native/macosx/MacOSXWindowSystemInterface.m
@@ -575,7 +575,6 @@ void setContextView(NSOpenGLContext* ctx, NSView* view) {
[ctx setView:view];
}
[pool release];
- return ctx;
}
Bool makeCurrentContext(NSOpenGLContext* ctx) {