aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/javax/media/opengl
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2014-08-30 00:21:00 +0200
committerSven Gothel <[email protected]>2014-08-30 00:21:00 +0200
commit11347ad39059836f3e2a4f1fc592dc1e3fab6a09 (patch)
treedf73acd41f7d0d8ae932cbd594336c98d388a113 /src/jogl/classes/javax/media/opengl
parentdfb9ed47ac6d8e85f6ae5fe166e7a6e28ca8ff83 (diff)
Bug 1054: GLContext: makeCurrent() needs a null-check of [mutable] drawable; Review null checks and synchronization/locking.
'drawable' field of GLContextImpl is mutable via setGLDrawable(..), which requires high-level locking as documented. The required high-level locking allows us to _not_ add special synchronization to this field (and drawableRead). A simple null-check in makeCurrent() shall be sufficient, plus ensuring mentioned high-level locking is applied. GLContextImpl 'drawable' and 'drawableRead' synchronization: - commit ad79bd072b600a3f2416cc6f0c61e2925000069d check of null drawable is sufficient - Add GLAutoDrawable upstream-lock locking to: - AWT GLCanvas setupPrint/releasePrint - AWT GLJPanel (was missing) Misc: - validate shared-context native-surface locking, throw exception if not successful - pixelDataEvaluated does not need to be synchronized, since it's being called while context is current, locking - GLDrawableHelper.recreateGLDrawable(..): Remove redundant glFinish() call
Diffstat (limited to 'src/jogl/classes/javax/media/opengl')
-rw-r--r--src/jogl/classes/javax/media/opengl/GLContext.java32
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/GLCanvas.java160
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/GLJPanel.java337
3 files changed, 302 insertions, 227 deletions
diff --git a/src/jogl/classes/javax/media/opengl/GLContext.java b/src/jogl/classes/javax/media/opengl/GLContext.java
index e10579df1..9389ccabb 100644
--- a/src/jogl/classes/javax/media/opengl/GLContext.java
+++ b/src/jogl/classes/javax/media/opengl/GLContext.java
@@ -326,6 +326,9 @@ public abstract class GLContext {
* If the read-drawable has not been changed manually via {@link #setGLReadDrawable(GLDrawable)},
* it equals to the write-drawable (default).
* </p>
+ * <p>
+ * Method is only thread-safe while context is {@link #makeCurrent() made current}.
+ * </p>
* @see #setGLDrawable(GLDrawable, boolean)
* @see #setGLReadDrawable(GLDrawable)
*/
@@ -364,6 +367,9 @@ public abstract class GLContext {
* If the read-drawable has not been changed manually via {@link #setGLReadDrawable(GLDrawable)},
* it equals to the write-drawable (default).
* </p>
+ * <p>
+ * Method is only thread-safe while context is {@link #makeCurrent() made current}.
+ * </p>
* @see #isGLReadDrawableAvailable()
* @see #setGLReadDrawable(GLDrawable)
* @see #getGLReadDrawable()
@@ -1262,6 +1268,9 @@ public abstract class GLContext {
/**
* Return the framebuffer name bound to this context,
* see {@link GL#glBindFramebuffer(int, int)}.
+ * <p>
+ * Method is only thread-safe while context is {@link #makeCurrent() made current}.
+ * </p>
*/
public abstract int getBoundFramebuffer(int target);
@@ -1272,6 +1281,9 @@ public abstract class GLContext {
* in case an framebuffer object ({@link com.jogamp.opengl.FBObject}) based drawable
* is being used.
* </p>
+ * <p>
+ * Method is only thread-safe while context is {@link #makeCurrent() made current}.
+ * </p>
*/
public abstract int getDefaultDrawFramebuffer();
@@ -1282,6 +1294,9 @@ public abstract class GLContext {
* in case an framebuffer object ({@link com.jogamp.opengl.FBObject}) based drawable
* is being used.
* </p>
+ * <p>
+ * Method is only thread-safe while context is {@link #makeCurrent() made current}.
+ * </p>
*/
public abstract int getDefaultReadFramebuffer();
@@ -1306,13 +1321,26 @@ public abstract class GLContext {
* Note-3: See {@link com.jogamp.opengl.util.GLDrawableUtil#swapBuffersBeforeRead(GLCapabilitiesImmutable) swapBuffersBeforeRead}
* for read-pixels and swap-buffers implications.
* </p>
+ * <p>
+ * Method is only thread-safe while context is {@link #makeCurrent() made current}.
+ * </p>
*/
public abstract int getDefaultReadBuffer();
- /** Get the default pixel data type, as required by e.g. {@link GL#glReadPixels(int, int, int, int, int, int, java.nio.Buffer)}. */
+ /**
+ * Get the default pixel data type, as required by e.g. {@link GL#glReadPixels(int, int, int, int, int, int, java.nio.Buffer)}.
+ * <p>
+ * Method is only thread-safe while context is {@link #makeCurrent() made current}.
+ * </p>
+ */
public abstract int getDefaultPixelDataType();
- /** Get the default pixel data format, as required by e.g. {@link GL#glReadPixels(int, int, int, int, int, int, java.nio.Buffer)}. */
+ /**
+ * Get the default pixel data format, as required by e.g. {@link GL#glReadPixels(int, int, int, int, int, int, java.nio.Buffer)}.
+ * <p>
+ * Method is only thread-safe while context is {@link #makeCurrent() made current}.
+ * </p>
+ */
public abstract int getDefaultPixelDataFormat();
/**
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
index b8e518ea5..563158a72 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
@@ -842,68 +842,74 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
private final Runnable setupPrintOnEDT = new Runnable() {
@Override
public void run() {
- if( !validateGLDrawable() ) {
- if(DEBUG) {
- System.err.println(getThreadName()+": Info: GLCanvas setupPrint - skipped GL render, drawable not valid yet");
+ final RecursiveLock _lock = lock;
+ _lock.lock();
+ try {
+ if( !validateGLDrawable() ) {
+ if(DEBUG) {
+ System.err.println(getThreadName()+": Info: GLCanvas setupPrint - skipped GL render, drawable not valid yet");
+ }
+ printActive = false;
+ return; // not yet available ..
}
- printActive = false;
- return; // not yet available ..
- }
- if( !isVisible() ) {
- if(DEBUG) {
- System.err.println(getThreadName()+": Info: GLCanvas setupPrint - skipped GL render, canvas not visible");
+ if( !isVisible() ) {
+ if(DEBUG) {
+ System.err.println(getThreadName()+": Info: GLCanvas setupPrint - skipped GL render, canvas not visible");
+ }
+ printActive = false;
+ return; // not yet available ..
}
- printActive = false;
- return; // not yet available ..
- }
- sendReshape = false; // clear reshape flag
- printAnimator = helper.getAnimator();
- if( null != printAnimator ) {
- printAnimator.remove(GLCanvas.this);
- }
- printGLAD = GLCanvas.this; // _not_ default, shall be replaced by offscreen GLAD
- final GLCapabilitiesImmutable gladCaps = getChosenGLCapabilities();
- final int printNumSamples = printAWTTiles.getNumSamples(gladCaps);
- GLDrawable printDrawable = printGLAD.getDelegatedDrawable();
- final boolean reqNewGLADSamples = printNumSamples != gladCaps.getNumSamples();
- final boolean reqNewGLADSize = printAWTTiles.customTileWidth != -1 && printAWTTiles.customTileWidth != printDrawable.getSurfaceWidth() ||
- printAWTTiles.customTileHeight != -1 && printAWTTiles.customTileHeight != printDrawable.getSurfaceHeight();
- final boolean reqNewGLADOnscrn = gladCaps.isOnscreen();
-
- final GLCapabilities newGLADCaps = (GLCapabilities)gladCaps.cloneMutable();
- newGLADCaps.setDoubleBuffered(false);
- newGLADCaps.setOnscreen(false);
- if( printNumSamples != newGLADCaps.getNumSamples() ) {
- newGLADCaps.setSampleBuffers(0 < printNumSamples);
- newGLADCaps.setNumSamples(printNumSamples);
- }
- final boolean reqNewGLADSafe = GLDrawableUtil.isSwapGLContextSafe(getRequestedGLCapabilities(), gladCaps, newGLADCaps);
+ sendReshape = false; // clear reshape flag
+ printAnimator = helper.getAnimator();
+ if( null != printAnimator ) {
+ printAnimator.remove(GLCanvas.this);
+ }
+ printGLAD = GLCanvas.this; // _not_ default, shall be replaced by offscreen GLAD
+ final GLCapabilitiesImmutable gladCaps = getChosenGLCapabilities();
+ final int printNumSamples = printAWTTiles.getNumSamples(gladCaps);
+ GLDrawable printDrawable = printGLAD.getDelegatedDrawable();
+ final boolean reqNewGLADSamples = printNumSamples != gladCaps.getNumSamples();
+ final boolean reqNewGLADSize = printAWTTiles.customTileWidth != -1 && printAWTTiles.customTileWidth != printDrawable.getSurfaceWidth() ||
+ printAWTTiles.customTileHeight != -1 && printAWTTiles.customTileHeight != printDrawable.getSurfaceHeight();
+ final boolean reqNewGLADOnscrn = gladCaps.isOnscreen();
+
+ final GLCapabilities newGLADCaps = (GLCapabilities)gladCaps.cloneMutable();
+ newGLADCaps.setDoubleBuffered(false);
+ newGLADCaps.setOnscreen(false);
+ if( printNumSamples != newGLADCaps.getNumSamples() ) {
+ newGLADCaps.setSampleBuffers(0 < printNumSamples);
+ newGLADCaps.setNumSamples(printNumSamples);
+ }
+ final boolean reqNewGLADSafe = GLDrawableUtil.isSwapGLContextSafe(getRequestedGLCapabilities(), gladCaps, newGLADCaps);
- final boolean reqNewGLAD = ( reqNewGLADOnscrn || reqNewGLADSamples || reqNewGLADSize ) && reqNewGLADSafe;
+ final boolean reqNewGLAD = ( reqNewGLADOnscrn || reqNewGLADSamples || reqNewGLADSize ) && reqNewGLADSafe;
- if( DEBUG ) {
- System.err.println("AWT print.setup: reqNewGLAD "+reqNewGLAD+"[ onscreen "+reqNewGLADOnscrn+", samples "+reqNewGLADSamples+", size "+reqNewGLADSize+", safe "+reqNewGLADSafe+"], "+
- ", drawableSize "+printDrawable.getSurfaceWidth()+"x"+printDrawable.getSurfaceHeight()+
- ", customTileSize "+printAWTTiles.customTileWidth+"x"+printAWTTiles.customTileHeight+
- ", scaleMat "+printAWTTiles.scaleMatX+" x "+printAWTTiles.scaleMatY+
- ", numSamples "+printAWTTiles.customNumSamples+" -> "+printNumSamples+", printAnimator "+printAnimator);
- }
- if( reqNewGLAD ) {
- final GLDrawableFactory factory = GLDrawableFactory.getFactory(newGLADCaps.getGLProfile());
- printGLAD = factory.createOffscreenAutoDrawable(null, newGLADCaps, null,
- printAWTTiles.customTileWidth != -1 ? printAWTTiles.customTileWidth : DEFAULT_PRINT_TILE_SIZE,
- printAWTTiles.customTileHeight != -1 ? printAWTTiles.customTileHeight : DEFAULT_PRINT_TILE_SIZE);
- GLDrawableUtil.swapGLContextAndAllGLEventListener(GLCanvas.this, printGLAD);
- printDrawable = printGLAD.getDelegatedDrawable();
- }
- printAWTTiles.setGLOrientation(printGLAD.isGLOriented(), printGLAD.isGLOriented());
- printAWTTiles.renderer.setTileSize(printDrawable.getSurfaceWidth(), printDrawable.getSurfaceHeight(), 0);
- printAWTTiles.renderer.attachAutoDrawable(printGLAD);
- if( DEBUG ) {
- System.err.println("AWT print.setup "+printAWTTiles);
- System.err.println("AWT print.setup AA "+printNumSamples+", "+newGLADCaps);
- System.err.println("AWT print.setup printGLAD: "+printGLAD.getSurfaceWidth()+"x"+printGLAD.getSurfaceHeight()+", "+printGLAD);
- System.err.println("AWT print.setup printDraw: "+printDrawable.getSurfaceWidth()+"x"+printDrawable.getSurfaceHeight()+", "+printDrawable);
+ if( DEBUG ) {
+ System.err.println("AWT print.setup: reqNewGLAD "+reqNewGLAD+"[ onscreen "+reqNewGLADOnscrn+", samples "+reqNewGLADSamples+", size "+reqNewGLADSize+", safe "+reqNewGLADSafe+"], "+
+ ", drawableSize "+printDrawable.getSurfaceWidth()+"x"+printDrawable.getSurfaceHeight()+
+ ", customTileSize "+printAWTTiles.customTileWidth+"x"+printAWTTiles.customTileHeight+
+ ", scaleMat "+printAWTTiles.scaleMatX+" x "+printAWTTiles.scaleMatY+
+ ", numSamples "+printAWTTiles.customNumSamples+" -> "+printNumSamples+", printAnimator "+printAnimator);
+ }
+ if( reqNewGLAD ) {
+ final GLDrawableFactory factory = GLDrawableFactory.getFactory(newGLADCaps.getGLProfile());
+ printGLAD = factory.createOffscreenAutoDrawable(null, newGLADCaps, null,
+ printAWTTiles.customTileWidth != -1 ? printAWTTiles.customTileWidth : DEFAULT_PRINT_TILE_SIZE,
+ printAWTTiles.customTileHeight != -1 ? printAWTTiles.customTileHeight : DEFAULT_PRINT_TILE_SIZE);
+ GLDrawableUtil.swapGLContextAndAllGLEventListener(GLCanvas.this, printGLAD);
+ printDrawable = printGLAD.getDelegatedDrawable();
+ }
+ printAWTTiles.setGLOrientation(printGLAD.isGLOriented(), printGLAD.isGLOriented());
+ printAWTTiles.renderer.setTileSize(printDrawable.getSurfaceWidth(), printDrawable.getSurfaceHeight(), 0);
+ printAWTTiles.renderer.attachAutoDrawable(printGLAD);
+ if( DEBUG ) {
+ System.err.println("AWT print.setup "+printAWTTiles);
+ System.err.println("AWT print.setup AA "+printNumSamples+", "+newGLADCaps);
+ System.err.println("AWT print.setup printGLAD: "+printGLAD.getSurfaceWidth()+"x"+printGLAD.getSurfaceHeight()+", "+printGLAD);
+ System.err.println("AWT print.setup printDraw: "+printDrawable.getSurfaceWidth()+"x"+printDrawable.getSurfaceHeight()+", "+printDrawable);
+ }
+ } finally {
+ _lock.unlock();
}
}
};
@@ -919,23 +925,29 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
private final Runnable releasePrintOnEDT = new Runnable() {
@Override
public void run() {
- if( DEBUG ) {
- System.err.println("AWT print.release "+printAWTTiles);
- }
- printAWTTiles.dispose();
- printAWTTiles= null;
- if( printGLAD != GLCanvas.this ) {
- GLDrawableUtil.swapGLContextAndAllGLEventListener(printGLAD, GLCanvas.this);
- printGLAD.destroy();
- }
- printGLAD = null;
- if( null != printAnimator ) {
- printAnimator.add(GLCanvas.this);
- printAnimator = null;
+ final RecursiveLock _lock = lock;
+ _lock.lock();
+ try {
+ if( DEBUG ) {
+ System.err.println("AWT print.release "+printAWTTiles);
+ }
+ printAWTTiles.dispose();
+ printAWTTiles= null;
+ if( printGLAD != GLCanvas.this ) {
+ GLDrawableUtil.swapGLContextAndAllGLEventListener(printGLAD, GLCanvas.this);
+ printGLAD.destroy();
+ }
+ printGLAD = null;
+ if( null != printAnimator ) {
+ printAnimator.add(GLCanvas.this);
+ printAnimator = null;
+ }
+ sendReshape = true; // trigger reshape, i.e. gl-viewport and -listener - this component might got resized!
+ printActive = false;
+ display();
+ } finally {
+ _lock.unlock();
}
- sendReshape = true; // trigger reshape, i.e. gl-viewport and -listener - this component might got resized!
- printActive = false;
- display();
}
};
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
index a95681ee7..e2ccc1097 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
@@ -239,7 +239,6 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
return singleAWTGLPixelBufferProvider;
}
- /** Currently not used internally, exist merely to satisfy {@link #getUpstreamLock()}. */
private final RecursiveLock lock = LockFactory.createRecursiveLock();
private final GLDrawableHelper helper;
@@ -538,28 +537,34 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
return;
}
- if( !isInitialized ) {
- initializeBackendImpl();
- }
-
- if (!isInitialized || printActive) {
- return;
- }
+ final RecursiveLock _lock = lock;
+ _lock.lock();
+ try {
+ if( !isInitialized ) {
+ initializeBackendImpl();
+ }
- // NOTE: must do this when the context is not current as it may
- // involve destroying the pbuffer (current context) and
- // re-creating it -- tricky to do properly while the context is
- // current
- if( !printActive ) {
- if (handleReshape) {
- handleReshape = false;
- sendReshape = handleReshape();
+ if (!isInitialized || printActive) {
+ return;
}
- if( isShowing ) {
- updater.setGraphics(g);
- backend.doPaintComponent(g);
+ // NOTE: must do this when the context is not current as it may
+ // involve destroying the pbuffer (current context) and
+ // re-creating it -- tricky to do properly while the context is
+ // current
+ if( !printActive ) {
+ if (handleReshape) {
+ handleReshape = false;
+ sendReshape = handleReshape();
+ }
+
+ if( isShowing ) {
+ updater.setGraphics(g);
+ backend.doPaintComponent(g);
+ }
}
+ } finally {
+ _lock.unlock();
}
}
@@ -689,72 +694,78 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
private final Runnable setupPrintOnEDT = new Runnable() {
@Override
public void run() {
- if( !isInitialized ) {
- initializeBackendImpl();
- }
- if (!isInitialized) {
- if(DEBUG) {
- System.err.println(getThreadName()+": Info: GLJPanel setupPrint - skipped GL render, drawable not valid yet");
+ final RecursiveLock _lock = lock;
+ _lock.lock();
+ try {
+ if( !isInitialized ) {
+ initializeBackendImpl();
}
- printActive = false;
- return; // not yet available ..
- }
- if( !isVisible() ) {
- if(DEBUG) {
- System.err.println(getThreadName()+": Info: GLJPanel setupPrint - skipped GL render, panel not visible");
+ if (!isInitialized) {
+ if(DEBUG) {
+ System.err.println(getThreadName()+": Info: GLJPanel setupPrint - skipped GL render, drawable not valid yet");
+ }
+ printActive = false;
+ return; // not yet available ..
+ }
+ if( !isVisible() ) {
+ if(DEBUG) {
+ System.err.println(getThreadName()+": Info: GLJPanel setupPrint - skipped GL render, panel not visible");
+ }
+ printActive = false;
+ return; // not yet available ..
+ }
+ sendReshape = false; // clear reshape flag
+ handleReshape = false; // ditto
+ printAnimator = helper.getAnimator();
+ if( null != printAnimator ) {
+ printAnimator.remove(GLJPanel.this);
}
- printActive = false;
- return; // not yet available ..
- }
- sendReshape = false; // clear reshape flag
- handleReshape = false; // ditto
- printAnimator = helper.getAnimator();
- if( null != printAnimator ) {
- printAnimator.remove(GLJPanel.this);
- }
- printGLAD = GLJPanel.this; // default: re-use
- final GLCapabilitiesImmutable gladCaps = getChosenGLCapabilities();
- final int printNumSamples = printAWTTiles.getNumSamples(gladCaps);
- GLDrawable printDrawable = printGLAD.getDelegatedDrawable();
- final boolean reqNewGLADSamples = printNumSamples != gladCaps.getNumSamples();
- final boolean reqNewGLADSize = printAWTTiles.customTileWidth != -1 && printAWTTiles.customTileWidth != printDrawable.getSurfaceWidth() ||
- printAWTTiles.customTileHeight != -1 && printAWTTiles.customTileHeight != printDrawable.getSurfaceHeight();
-
- final GLCapabilities newGLADCaps = (GLCapabilities)gladCaps.cloneMutable();
- newGLADCaps.setDoubleBuffered(false);
- newGLADCaps.setOnscreen(false);
- if( printNumSamples != newGLADCaps.getNumSamples() ) {
- newGLADCaps.setSampleBuffers(0 < printNumSamples);
- newGLADCaps.setNumSamples(printNumSamples);
- }
- final boolean reqNewGLADSafe = GLDrawableUtil.isSwapGLContextSafe(getRequestedGLCapabilities(), gladCaps, newGLADCaps);
+ printGLAD = GLJPanel.this; // default: re-use
+ final GLCapabilitiesImmutable gladCaps = getChosenGLCapabilities();
+ final int printNumSamples = printAWTTiles.getNumSamples(gladCaps);
+ GLDrawable printDrawable = printGLAD.getDelegatedDrawable();
+ final boolean reqNewGLADSamples = printNumSamples != gladCaps.getNumSamples();
+ final boolean reqNewGLADSize = printAWTTiles.customTileWidth != -1 && printAWTTiles.customTileWidth != printDrawable.getSurfaceWidth() ||
+ printAWTTiles.customTileHeight != -1 && printAWTTiles.customTileHeight != printDrawable.getSurfaceHeight();
+
+ final GLCapabilities newGLADCaps = (GLCapabilities)gladCaps.cloneMutable();
+ newGLADCaps.setDoubleBuffered(false);
+ newGLADCaps.setOnscreen(false);
+ if( printNumSamples != newGLADCaps.getNumSamples() ) {
+ newGLADCaps.setSampleBuffers(0 < printNumSamples);
+ newGLADCaps.setNumSamples(printNumSamples);
+ }
+ final boolean reqNewGLADSafe = GLDrawableUtil.isSwapGLContextSafe(getRequestedGLCapabilities(), gladCaps, newGLADCaps);
- final boolean reqNewGLAD = ( reqNewGLADSamples || reqNewGLADSize ) && reqNewGLADSafe;
+ final boolean reqNewGLAD = ( reqNewGLADSamples || reqNewGLADSize ) && reqNewGLADSafe;
- if( DEBUG ) {
- System.err.println("AWT print.setup: reqNewGLAD "+reqNewGLAD+"[ samples "+reqNewGLADSamples+", size "+reqNewGLADSize+", safe "+reqNewGLADSafe+"], "+
- ", drawableSize "+printDrawable.getSurfaceWidth()+"x"+printDrawable.getSurfaceHeight()+
- ", customTileSize "+printAWTTiles.customTileWidth+"x"+printAWTTiles.customTileHeight+
- ", scaleMat "+printAWTTiles.scaleMatX+" x "+printAWTTiles.scaleMatY+
- ", numSamples "+printAWTTiles.customNumSamples+" -> "+printNumSamples+", printAnimator "+printAnimator);
- }
- if( reqNewGLAD ) {
- final GLDrawableFactory factory = GLDrawableFactory.getFactory(newGLADCaps.getGLProfile());
- printGLAD = factory.createOffscreenAutoDrawable(null, newGLADCaps, null,
- printAWTTiles.customTileWidth != -1 ? printAWTTiles.customTileWidth : DEFAULT_PRINT_TILE_SIZE,
- printAWTTiles.customTileHeight != -1 ? printAWTTiles.customTileHeight : DEFAULT_PRINT_TILE_SIZE);
- GLDrawableUtil.swapGLContextAndAllGLEventListener(GLJPanel.this, printGLAD);
- printDrawable = printGLAD.getDelegatedDrawable();
- }
- printAWTTiles.setGLOrientation( !GLJPanel.this.skipGLOrientationVerticalFlip && printGLAD.isGLOriented(), printGLAD.isGLOriented() );
- printAWTTiles.renderer.setTileSize(printDrawable.getSurfaceWidth(), printDrawable.getSurfaceHeight(), 0);
- printAWTTiles.renderer.attachAutoDrawable(printGLAD);
- if( DEBUG ) {
- System.err.println("AWT print.setup "+printAWTTiles);
- System.err.println("AWT print.setup AA "+printNumSamples+", "+newGLADCaps);
- System.err.println("AWT print.setup printGLAD: "+printGLAD.getSurfaceWidth()+"x"+printGLAD.getSurfaceHeight()+", "+printGLAD);
- System.err.println("AWT print.setup printDraw: "+printDrawable.getSurfaceWidth()+"x"+printDrawable.getSurfaceHeight()+", "+printDrawable);
+ if( DEBUG ) {
+ System.err.println("AWT print.setup: reqNewGLAD "+reqNewGLAD+"[ samples "+reqNewGLADSamples+", size "+reqNewGLADSize+", safe "+reqNewGLADSafe+"], "+
+ ", drawableSize "+printDrawable.getSurfaceWidth()+"x"+printDrawable.getSurfaceHeight()+
+ ", customTileSize "+printAWTTiles.customTileWidth+"x"+printAWTTiles.customTileHeight+
+ ", scaleMat "+printAWTTiles.scaleMatX+" x "+printAWTTiles.scaleMatY+
+ ", numSamples "+printAWTTiles.customNumSamples+" -> "+printNumSamples+", printAnimator "+printAnimator);
+ }
+ if( reqNewGLAD ) {
+ final GLDrawableFactory factory = GLDrawableFactory.getFactory(newGLADCaps.getGLProfile());
+ printGLAD = factory.createOffscreenAutoDrawable(null, newGLADCaps, null,
+ printAWTTiles.customTileWidth != -1 ? printAWTTiles.customTileWidth : DEFAULT_PRINT_TILE_SIZE,
+ printAWTTiles.customTileHeight != -1 ? printAWTTiles.customTileHeight : DEFAULT_PRINT_TILE_SIZE);
+ GLDrawableUtil.swapGLContextAndAllGLEventListener(GLJPanel.this, printGLAD);
+ printDrawable = printGLAD.getDelegatedDrawable();
+ }
+ printAWTTiles.setGLOrientation( !GLJPanel.this.skipGLOrientationVerticalFlip && printGLAD.isGLOriented(), printGLAD.isGLOriented() );
+ printAWTTiles.renderer.setTileSize(printDrawable.getSurfaceWidth(), printDrawable.getSurfaceHeight(), 0);
+ printAWTTiles.renderer.attachAutoDrawable(printGLAD);
+ if( DEBUG ) {
+ System.err.println("AWT print.setup "+printAWTTiles);
+ System.err.println("AWT print.setup AA "+printNumSamples+", "+newGLADCaps);
+ System.err.println("AWT print.setup printGLAD: "+printGLAD.getSurfaceWidth()+"x"+printGLAD.getSurfaceHeight()+", "+printGLAD);
+ System.err.println("AWT print.setup printDraw: "+printDrawable.getSurfaceWidth()+"x"+printDrawable.getSurfaceHeight()+", "+printDrawable);
+ }
+ } finally {
+ _lock.unlock();
}
}
};
@@ -772,43 +783,49 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
private final Runnable releasePrintOnEDT = new Runnable() {
@Override
public void run() {
- if( DEBUG ) {
- System.err.println(getThreadName()+": GLJPanel.releasePrintOnEDT.0 "+printAWTTiles);
- }
- printAWTTiles.dispose();
- printAWTTiles= null;
- if( printGLAD != GLJPanel.this ) {
- GLDrawableUtil.swapGLContextAndAllGLEventListener(printGLAD, GLJPanel.this);
- printGLAD.destroy();
- }
- printGLAD = null;
- if( null != printAnimator ) {
- printAnimator.add(GLJPanel.this);
- printAnimator = null;
- }
+ final RecursiveLock _lock = lock;
+ _lock.lock();
+ try {
+ if( DEBUG ) {
+ System.err.println(getThreadName()+": GLJPanel.releasePrintOnEDT.0 "+printAWTTiles);
+ }
+ printAWTTiles.dispose();
+ printAWTTiles= null;
+ if( printGLAD != GLJPanel.this ) {
+ GLDrawableUtil.swapGLContextAndAllGLEventListener(printGLAD, GLJPanel.this);
+ printGLAD.destroy();
+ }
+ printGLAD = null;
+ if( null != printAnimator ) {
+ printAnimator.add(GLJPanel.this);
+ printAnimator = null;
+ }
- // trigger reshape, i.e. gl-viewport and -listener - this component might got resized!
- final int awtWidth = GLJPanel.this.getWidth();
- final int awtHeight= GLJPanel.this.getHeight();
- final int scaledAWTWidth = awtWidth * hasPixelScale[0];
- final int scaledAWTHeight= awtHeight * hasPixelScale[1];
- final GLDrawable drawable = GLJPanel.this.getDelegatedDrawable();
- if( scaledAWTWidth != panelWidth || scaledAWTHeight != panelHeight ||
- drawable.getSurfaceWidth() != panelWidth || drawable.getSurfaceHeight() != panelHeight ) {
- // -> !( awtSize == panelSize == drawableSize )
- if ( DEBUG ) {
- System.err.println(getThreadName()+": GLJPanel.releasePrintOnEDT.0: resizeWithinPrint panel " +panelWidth+"x"+panelHeight + " @ scale "+getPixelScaleStr()+
- ", draw "+drawable.getSurfaceWidth()+"x"+drawable.getSurfaceHeight()+
- " -> " + awtWidth+"x"+awtHeight+" * "+getPixelScaleStr()+" -> "+scaledAWTWidth+"x"+scaledAWTHeight);
+ // trigger reshape, i.e. gl-viewport and -listener - this component might got resized!
+ final int awtWidth = GLJPanel.this.getWidth();
+ final int awtHeight= GLJPanel.this.getHeight();
+ final int scaledAWTWidth = awtWidth * hasPixelScale[0];
+ final int scaledAWTHeight= awtHeight * hasPixelScale[1];
+ final GLDrawable drawable = GLJPanel.this.getDelegatedDrawable();
+ if( scaledAWTWidth != panelWidth || scaledAWTHeight != panelHeight ||
+ drawable.getSurfaceWidth() != panelWidth || drawable.getSurfaceHeight() != panelHeight ) {
+ // -> !( awtSize == panelSize == drawableSize )
+ if ( DEBUG ) {
+ System.err.println(getThreadName()+": GLJPanel.releasePrintOnEDT.0: resizeWithinPrint panel " +panelWidth+"x"+panelHeight + " @ scale "+getPixelScaleStr()+
+ ", draw "+drawable.getSurfaceWidth()+"x"+drawable.getSurfaceHeight()+
+ " -> " + awtWidth+"x"+awtHeight+" * "+getPixelScaleStr()+" -> "+scaledAWTWidth+"x"+scaledAWTHeight);
+ }
+ reshapeWidth = scaledAWTWidth;
+ reshapeHeight = scaledAWTHeight;
+ sendReshape = handleReshape(); // reshapeSize -> panelSize, backend reshape w/ GL reshape
+ } else {
+ sendReshape = true; // only GL reshape
}
- reshapeWidth = scaledAWTWidth;
- reshapeHeight = scaledAWTHeight;
- sendReshape = handleReshape(); // reshapeSize -> panelSize, backend reshape w/ GL reshape
- } else {
- sendReshape = true; // only GL reshape
+ printActive = false;
+ display();
+ } finally {
+ _lock.unlock();
}
- printActive = false;
- display();
}
};
@@ -966,11 +983,17 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
@Override
public GLContext createContext(final GLContext shareWith) {
- final Backend b = backend;
- if ( null == b ) {
- return null;
+ final RecursiveLock _lock = lock;
+ _lock.lock();
+ try {
+ final Backend b = backend;
+ if ( null == b ) {
+ return null;
+ }
+ return b.createContext(shareWith);
+ } finally {
+ _lock.unlock();
}
- return b.createContext(shareWith);
}
@Override
@@ -984,14 +1007,20 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
@Override
public GLContext setContext(final GLContext newCtx, final boolean destroyPrevCtx) {
- final Backend b = backend;
- if ( null == b ) {
- return null;
+ final RecursiveLock _lock = lock;
+ _lock.lock();
+ try {
+ final Backend b = backend;
+ if ( null == b ) {
+ return null;
+ }
+ final GLContext oldCtx = b.getContext();
+ GLDrawableHelper.switchContext(b.getDrawable(), oldCtx, destroyPrevCtx, newCtx, additionalCtxCreationFlags);
+ b.setContext(newCtx);
+ return oldCtx;
+ } finally {
+ _lock.unlock();
}
- final GLContext oldCtx = b.getContext();
- GLDrawableHelper.switchContext(b.getDrawable(), oldCtx, destroyPrevCtx, newCtx, additionalCtxCreationFlags);
- b.setContext(newCtx);
- return oldCtx;
}
@@ -1342,36 +1371,42 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
private final Runnable disposeAction = new Runnable() {
@Override
public void run() {
- if ( null != backend ) {
- final GLContext _context = backend.getContext();
- final boolean backendDestroy = !backend.isUsingOwnLifecycle();
-
- GLException exceptionOnDisposeGL = null;
- if( null != _context && _context.isCreated() ) {
- try {
- helper.disposeGL(GLJPanel.this, _context, !backendDestroy);
- } catch (final GLException gle) {
- exceptionOnDisposeGL = gle;
+ final RecursiveLock _lock = lock;
+ _lock.lock();
+ try {
+ if ( null != backend ) {
+ final GLContext _context = backend.getContext();
+ final boolean backendDestroy = !backend.isUsingOwnLifecycle();
+
+ GLException exceptionOnDisposeGL = null;
+ if( null != _context && _context.isCreated() ) {
+ try {
+ helper.disposeGL(GLJPanel.this, _context, !backendDestroy);
+ } catch (final GLException gle) {
+ exceptionOnDisposeGL = gle;
+ }
}
- }
- Throwable exceptionBackendDestroy = null;
- if ( backendDestroy ) {
- try {
- backend.destroy();
- } catch( final Throwable re ) {
- exceptionBackendDestroy = re;
+ Throwable exceptionBackendDestroy = null;
+ if ( backendDestroy ) {
+ try {
+ backend.destroy();
+ } catch( final Throwable re ) {
+ exceptionBackendDestroy = re;
+ }
+ backend = null;
+ isInitialized = false;
}
- backend = null;
- isInitialized = false;
- }
- // throw exception in order of occurrence ..
- if( null != exceptionOnDisposeGL ) {
- throw exceptionOnDisposeGL;
- }
- if( null != exceptionBackendDestroy ) {
- throw GLException.newGLException(exceptionBackendDestroy);
+ // throw exception in order of occurrence ..
+ if( null != exceptionOnDisposeGL ) {
+ throw exceptionOnDisposeGL;
+ }
+ if( null != exceptionBackendDestroy ) {
+ throw GLException.newGLException(exceptionBackendDestroy);
+ }
}
+ } finally {
+ _lock.unlock();
}
}
};