diff options
Diffstat (limited to 'src/net/java/games/jogl/GLJPanel.java')
-rw-r--r-- | src/net/java/games/jogl/GLJPanel.java | 109 |
1 files changed, 62 insertions, 47 deletions
diff --git a/src/net/java/games/jogl/GLJPanel.java b/src/net/java/games/jogl/GLJPanel.java index d8c41e006..425160494 100644 --- a/src/net/java/games/jogl/GLJPanel.java +++ b/src/net/java/games/jogl/GLJPanel.java @@ -189,58 +189,73 @@ public final class GLJPanel extends JPanel implements GLDrawable { public void reshape(int x, int y, int width, int height) { super.reshape(x, y, width, height); - GLContext context = null; - neededOffscreenImageWidth = 0; - neededOffscreenImageHeight = 0; + // Move all reshape requests onto AWT EventQueue thread + final int fx = x; + final int fy = y; + final int fwidth = width; + final int fheight = height; - if (!hardwareAccelerationDisabled) { - if (width > pbufferWidth || height > pbufferHeight) { - // Must destroy and recreate pbuffer to fit - pbuffer.destroy(); - if (width > pbufferWidth) { - pbufferWidth = getNextPowerOf2(width); - } - if (height > pbufferHeight) { - pbufferHeight = getNextPowerOf2(height); - } - initialize(); - } - GLPbufferImpl pbufferImpl = (GLPbufferImpl) pbuffer; - context = pbufferImpl.getContext(); - // It looks like NVidia's drivers (at least the ones on my - // notebook) are buggy and don't allow a rectangle of less than - // the pbuffer's width to be read...this doesn't really matter - // because it's the Graphics.drawImage() calls that are the - // bottleneck. Should probably make the size of the offscreen - // image be the exact size of the pbuffer to save some work on - // resize operations... - neededOffscreenImageWidth = pbufferWidth; - neededOffscreenImageHeight = height; - } else { - offscreenContext.resizeOffscreenContext(width, height); - context = offscreenContext; - neededOffscreenImageWidth = width; - neededOffscreenImageHeight = height; - } + Runnable r = new Runnable() { + public void run() { + GLContext context = null; + neededOffscreenImageWidth = 0; + neededOffscreenImageHeight = 0; - if (offscreenImage != null && - (offscreenImage.getWidth() != neededOffscreenImageWidth || - offscreenImage.getHeight() != neededOffscreenImageHeight)) { - offscreenImage.flush(); - offscreenImage = null; - } + if (!hardwareAccelerationDisabled) { + if (fwidth > pbufferWidth || fheight > pbufferHeight) { + // Must destroy and recreate pbuffer to fit + pbuffer.destroy(); + if (fwidth > pbufferWidth) { + pbufferWidth = getNextPowerOf2(fwidth); + } + if (fheight > pbufferHeight) { + pbufferHeight = getNextPowerOf2(fheight); + } + initialize(); + } + GLPbufferImpl pbufferImpl = (GLPbufferImpl) pbuffer; + context = pbufferImpl.getContext(); + // It looks like NVidia's drivers (at least the ones on my + // notebook) are buggy and don't allow a rectangle of less than + // the pbuffer's width to be read...this doesn't really matter + // because it's the Graphics.drawImage() calls that are the + // bottleneck. Should probably make the size of the offscreen + // image be the exact size of the pbuffer to save some work on + // resize operations... + neededOffscreenImageWidth = pbufferWidth; + neededOffscreenImageHeight = fheight; + } else { + offscreenContext.resizeOffscreenContext(fwidth, fheight); + context = offscreenContext; + neededOffscreenImageWidth = fwidth; + neededOffscreenImageHeight = fheight; + } - panelWidth = width; - panelHeight = height; - final int fx = 0; - final int fy = 0; + if (offscreenImage != null && + (offscreenImage.getWidth() != neededOffscreenImageWidth || + offscreenImage.getHeight() != neededOffscreenImageHeight)) { + offscreenImage.flush(); + offscreenImage = null; + } - context.invokeGL(new Runnable() { - public void run() { - getGL().glViewport(fx, fy, panelWidth, panelHeight); - drawableHelper.reshape(GLJPanel.this, fx, fy, panelWidth, panelHeight); + panelWidth = fwidth; + panelHeight = fheight; + + context.invokeGL(new Runnable() { + public void run() { + getGL().glViewport(0, 0, panelWidth, panelHeight); + drawableHelper.reshape(GLJPanel.this, 0, 0, panelWidth, panelHeight); + } + }, true, initAction); } - }, true, initAction); + }; + if (EventQueue.isDispatchThread()) { + r.run(); + } else { + // Avoid blocking EventQueue thread due to possible deadlocks + // during component creation + EventQueue.invokeLater(r); + } } public void addGLEventListener(GLEventListener listener) { |