diff --git a/src/java/org/lwjgl/opengl/AWTGLCanvas.java b/src/java/org/lwjgl/opengl/AWTGLCanvas.java index b044fac8..a10277dc 100644 --- a/src/java/org/lwjgl/opengl/AWTGLCanvas.java +++ b/src/java/org/lwjgl/opengl/AWTGLCanvas.java @@ -136,22 +136,13 @@ public class AWTGLCanvas extends Canvas implements Drawable { */ public void addNotify() { super.addNotify(); - try { - createContext(); - } catch (LWJGLException e) { - throw new RuntimeException(e); - } } /* (non-Javadoc) * @see java.awt.Component#removeNotify() */ public void removeNotify() { - try { - destroyContext(); - } catch (LWJGLException e) { - throw new RuntimeException(e); - } + destroyContext(); super.removeNotify(); } @@ -190,27 +181,41 @@ public class AWTGLCanvas extends Canvas implements Drawable { context.makeCurrent(); } - /** - * Create the OpenGL context. This occurs when the component becomes displayable - * @throws LWJGLException - */ - private synchronized void createContext() throws LWJGLException { - if (context == null) - context = new Context(peer_info, drawable != null ? drawable.getContext() : null); - } - /** * Destroy the OpenGL context. This happens when the component becomes undisplayable */ - private synchronized void destroyContext() throws LWJGLException { - context.forceDestroy(); - context = null; + private synchronized void destroyContext() { + try { + if (context != null) { + context.forceDestroy(); + context = null; + } + } catch (LWJGLException e) { + throw new RuntimeException(e); + } } /** - * Empty paint to avoid clearing + * Override this to do painting */ - public void paint(Graphics g) { + protected void paintGL() { + } + + public final void paint(Graphics g) { + try { + peer_info.lockAndGetHandle(); + try { + if (context == null) + context = new Context(peer_info, drawable != null ? drawable.getContext() : null); + if (!context.isCurrent()) + context.makeCurrent(); + paintGL(); + } finally { + peer_info.unlock(); + } + } catch (LWJGLException e) { + throw new RuntimeException(e); + } } /** diff --git a/src/java/org/lwjgl/opengl/PeerInfo.java b/src/java/org/lwjgl/opengl/PeerInfo.java index 2bc32085..8608a839 100644 --- a/src/java/org/lwjgl/opengl/PeerInfo.java +++ b/src/java/org/lwjgl/opengl/PeerInfo.java @@ -44,6 +44,8 @@ import org.lwjgl.Sys; */ abstract class PeerInfo { private final ByteBuffer handle; + private Thread locking_thread; // Thread that has locked this PeerInfo + private int lock_count; protected PeerInfo(ByteBuffer handle) { this.handle = handle; @@ -54,14 +56,29 @@ abstract class PeerInfo { } public synchronized final void unlock() throws LWJGLException { - doUnlock(); + if (lock_count <= 0) + throw new IllegalStateException("PeerInfo not locked!"); + if (Thread.currentThread() != locking_thread) + throw new IllegalStateException("PeerInfo already locked by " + locking_thread); + lock_count--; + if (lock_count == 0) { + doUnlock(); + locking_thread = null; + } } protected abstract void doLockAndInitHandle() throws LWJGLException; protected abstract void doUnlock() throws LWJGLException; public synchronized final ByteBuffer lockAndGetHandle() throws LWJGLException { - lockAndInitHandle(); + Thread this_thread = Thread.currentThread(); + if (locking_thread != null && locking_thread != this_thread) + throw new IllegalStateException("PeerInfo already locked by " + locking_thread); + if (lock_count == 0) { + locking_thread = this_thread; + doLockAndInitHandle(); + } + lock_count++; return getHandle(); } diff --git a/src/java/org/lwjgl/test/opengl/awt/AWTTest.java b/src/java/org/lwjgl/test/opengl/awt/AWTTest.java index cbe7ee4e..f019b046 100644 --- a/src/java/org/lwjgl/test/opengl/awt/AWTTest.java +++ b/src/java/org/lwjgl/test/opengl/awt/AWTTest.java @@ -37,7 +37,7 @@ public class AWTTest extends Frame { setSize(640, 320); setLayout(null); add(canvas0 = new AWTGLCanvas() { - public void paint(Graphics g) { + public void paintGL() { try { makeCurrent(); GL11.glViewport(0, 0, getWidth(), getHeight()); @@ -61,7 +61,7 @@ public class AWTTest extends Frame { }); canvas0.setBounds(0, 0, 320, 320); add(canvas1 = new AWTGLCanvas() { - public void paint(Graphics g) { + public void paintGL() { try { makeCurrent(); GL11.glViewport(0, 0, getWidth(), getHeight());