Fix AWTGLCanvas to create context and make it current in paint(). GL usage can then only happen from an overidden paintGL().

This commit is contained in:
Elias Naur 2005-02-22 13:35:09 +00:00
parent 5d2e5de4eb
commit 47814d58f4
3 changed files with 50 additions and 28 deletions

View File

@ -136,22 +136,13 @@ public class AWTGLCanvas extends Canvas implements Drawable {
*/ */
public void addNotify() { public void addNotify() {
super.addNotify(); super.addNotify();
try {
createContext();
} catch (LWJGLException e) {
throw new RuntimeException(e);
}
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see java.awt.Component#removeNotify() * @see java.awt.Component#removeNotify()
*/ */
public void removeNotify() { public void removeNotify() {
try { destroyContext();
destroyContext();
} catch (LWJGLException e) {
throw new RuntimeException(e);
}
super.removeNotify(); super.removeNotify();
} }
@ -190,27 +181,41 @@ public class AWTGLCanvas extends Canvas implements Drawable {
context.makeCurrent(); 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 * Destroy the OpenGL context. This happens when the component becomes undisplayable
*/ */
private synchronized void destroyContext() throws LWJGLException { private synchronized void destroyContext() {
context.forceDestroy(); try {
context = null; 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);
}
} }
/** /**

View File

@ -44,6 +44,8 @@ import org.lwjgl.Sys;
*/ */
abstract class PeerInfo { abstract class PeerInfo {
private final ByteBuffer handle; private final ByteBuffer handle;
private Thread locking_thread; // Thread that has locked this PeerInfo
private int lock_count;
protected PeerInfo(ByteBuffer handle) { protected PeerInfo(ByteBuffer handle) {
this.handle = handle; this.handle = handle;
@ -54,14 +56,29 @@ abstract class PeerInfo {
} }
public synchronized final void unlock() throws LWJGLException { 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 doLockAndInitHandle() throws LWJGLException;
protected abstract void doUnlock() throws LWJGLException; protected abstract void doUnlock() throws LWJGLException;
public synchronized final ByteBuffer lockAndGetHandle() 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(); return getHandle();
} }

View File

@ -37,7 +37,7 @@ public class AWTTest extends Frame {
setSize(640, 320); setSize(640, 320);
setLayout(null); setLayout(null);
add(canvas0 = new AWTGLCanvas() { add(canvas0 = new AWTGLCanvas() {
public void paint(Graphics g) { public void paintGL() {
try { try {
makeCurrent(); makeCurrent();
GL11.glViewport(0, 0, getWidth(), getHeight()); GL11.glViewport(0, 0, getWidth(), getHeight());
@ -61,7 +61,7 @@ public class AWTTest extends Frame {
}); });
canvas0.setBounds(0, 0, 320, 320); canvas0.setBounds(0, 0, 320, 320);
add(canvas1 = new AWTGLCanvas() { add(canvas1 = new AWTGLCanvas() {
public void paint(Graphics g) { public void paintGL() {
try { try {
makeCurrent(); makeCurrent();
GL11.glViewport(0, 0, getWidth(), getHeight()); GL11.glViewport(0, 0, getWidth(), getHeight());