From 8f5492988de9fddf61623b7274915c777ad3a97d Mon Sep 17 00:00:00 2001 From: Kenneth Russel Date: Mon, 18 Jul 2005 22:15:42 +0000 Subject: Moved support for instantiating GLPbuffers from X11OnscreenGLContext to X11GLContextFactory. git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/svn-server-sync/jogl/branches/JSR-231@327 232f8b59-042b-4e1e-8c03-345bb8c30851 --- .../jogl/impl/windows/WindowsGLContextFactory.java | 2 +- src/net/java/games/jogl/impl/x11/X11GLContext.java | 31 +-- .../games/jogl/impl/x11/X11GLContextFactory.java | 86 ++++++++ .../games/jogl/impl/x11/X11OnscreenGLContext.java | 8 + .../games/jogl/impl/x11/X11PbufferGLDrawable.java | 229 +++++++++++---------- 5 files changed, 216 insertions(+), 140 deletions(-) (limited to 'src/net/java/games') diff --git a/src/net/java/games/jogl/impl/windows/WindowsGLContextFactory.java b/src/net/java/games/jogl/impl/windows/WindowsGLContextFactory.java index 1ea4c8b95..112afd2e4 100644 --- a/src/net/java/games/jogl/impl/windows/WindowsGLContextFactory.java +++ b/src/net/java/games/jogl/impl/windows/WindowsGLContextFactory.java @@ -179,7 +179,7 @@ public class WindowsGLContextFactory extends GLContextFactory { final int initialWidth, final int initialHeight, final GLContext shareWith) { - if (!canCreateGLPbuffer) { + if (!canCreateGLPbuffer(capabilities, initialWidth, initialHeight)) { throw new GLException("Pbuffer support not available with current graphics card"); } final List returnList = new ArrayList(); diff --git a/src/net/java/games/jogl/impl/x11/X11GLContext.java b/src/net/java/games/jogl/impl/x11/X11GLContext.java index 66520ada3..fd22d0ee5 100644 --- a/src/net/java/games/jogl/impl/x11/X11GLContext.java +++ b/src/net/java/games/jogl/impl/x11/X11GLContext.java @@ -52,7 +52,6 @@ public abstract class X11GLContext extends GLContextImpl { private boolean glXQueryExtensionsStringInitialized; private boolean glXQueryExtensionsStringAvailable; private static final Map/**/ functionNameMap; - private boolean isGLX13; // Table that holds the addresses of the native C-language entry points for // OpenGL functions. private GLProcAddressTable glProcAddressTable; @@ -207,34 +206,6 @@ public abstract class X11GLContext extends GLContextImpl { if (!haveResetGLXProcAddressTable) { resetProcAddressTable(GLX.getGLXProcAddressTable()); } - - // Figure out whether we are running GLX version 1.3 or above and - // therefore have pbuffer support - if (drawable.getDisplay() == 0) { - throw new GLException("Expected non-null DISPLAY for querying GLX version"); - } - int[] major = new int[1]; - int[] minor = new int[1]; - if (!GLX.glXQueryVersion(drawable.getDisplay(), major, 0, minor, 0)) { - throw new GLException("glXQueryVersion failed"); - } - if (DEBUG) { - System.err.println("!!! GLX version: major " + major[0] + - ", minor " + minor[0]); - } - - // Work around bugs in ATI's Linux drivers where they report they - // only implement GLX version 1.2 but actually do support pbuffers - if (major[0] == 1 && minor[0] == 2) { - GL gl = getGL(); - String str = gl.glGetString(GL.GL_VENDOR); - if (str != null && str.indexOf("ATI") >= 0) { - isGLX13 = true; - return; - } - } - - isGLX13 = ((major[0] > 1) || (minor[0] > 2)); } public GLProcAddressTable getGLProcAddressTable() { @@ -289,7 +260,7 @@ public abstract class X11GLContext extends GLContextImpl { public boolean isExtensionAvailable(String glExtensionName) { if (glExtensionName.equals("GL_ARB_pbuffer") || glExtensionName.equals("GL_ARB_pixel_format")) { - return isGLX13; + return X11GLContextFactory.getFactory().canCreateGLPbuffer(null, 0, 0); } return super.isExtensionAvailable(glExtensionName); } diff --git a/src/net/java/games/jogl/impl/x11/X11GLContextFactory.java b/src/net/java/games/jogl/impl/x11/X11GLContextFactory.java index 78d03a28a..109f74e44 100644 --- a/src/net/java/games/jogl/impl/x11/X11GLContextFactory.java +++ b/src/net/java/games/jogl/impl/x11/X11GLContextFactory.java @@ -40,12 +40,18 @@ package net.java.games.jogl.impl.x11; import java.awt.Component; +import java.awt.EventQueue; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.List; import net.java.games.jogl.*; import net.java.games.jogl.impl.*; public class X11GLContextFactory extends GLContextFactory { + private static final boolean DEBUG = Debug.debug("X11GLContextFactory"); + static { NativeLibLoader.load(); } @@ -137,6 +143,72 @@ public class X11GLContextFactory extends GLContextFactory { return new X11OffscreenGLDrawable(capabilities, chooser); } + private boolean pbufferSupportInitialized = false; + private boolean canCreateGLPbuffer = false; + public boolean canCreateGLPbuffer(GLCapabilities capabilities, + int initialWidth, + int initialHeight) { + if (!pbufferSupportInitialized) { + Runnable r = new Runnable() { + public void run() { + long display = getDisplayConnection(); + lockAWT(); + try { + int[] major = new int[1]; + int[] minor = new int[1]; + if (!GLX.glXQueryVersion(display, major, 0, minor, 0)) { + throw new GLException("glXQueryVersion failed"); + } + if (DEBUG) { + System.err.println("!!! GLX version: major " + major[0] + + ", minor " + minor[0]); + } + + int screen = 0; // FIXME: provide way to specify this? + + // Work around bugs in ATI's Linux drivers where they report they + // only implement GLX version 1.2 but actually do support pbuffers + if (major[0] == 1 && minor[0] == 2) { + String str = GLX.glXQueryServerString(display, screen, GLX.GLX_VENDOR); + if (str != null && str.indexOf("ATI") >= 0) { + canCreateGLPbuffer = true; + } + } else { + canCreateGLPbuffer = ((major[0] > 1) || (minor[0] > 2)); + } + + pbufferSupportInitialized = true; + } finally { + unlockAWT(); + } + } + }; + maybeDoSingleThreadedWorkaround(r); + } + return canCreateGLPbuffer; + } + + public GLPbuffer createGLPbuffer(final GLCapabilities capabilities, + final int initialWidth, + final int initialHeight, + final GLContext shareWith) { + if (!canCreateGLPbuffer(capabilities, initialWidth, initialHeight)) { + throw new GLException("Pbuffer support not available with current graphics card"); + } + final List returnList = new ArrayList(); + Runnable r = new Runnable() { + public void run() { + X11PbufferGLDrawable pbufferDrawable = new X11PbufferGLDrawable(capabilities, + initialWidth, + initialHeight); + GLPbufferImpl pbuffer = new GLPbufferImpl(pbufferDrawable, shareWith); + returnList.add(pbuffer); + } + }; + maybeDoSingleThreadedWorkaround(r); + return (GLPbuffer) returnList.get(0); + } + public static GLCapabilities xvi2GLCapabilities(long display, XVisualInfo info) { int[] tmp = new int[1]; int val = glXGetConfig(display, info, GLX.GLX_USE_GL, tmp, 0); @@ -292,4 +364,18 @@ public class X11GLContextFactory extends GLContextFactory { } return tmp[tmp_offset]; } + + private void maybeDoSingleThreadedWorkaround(Runnable action) { + if (SingleThreadedWorkaround.doWorkaround() && !EventQueue.isDispatchThread()) { + try { + EventQueue.invokeAndWait(action); + } catch (InvocationTargetException e) { + throw new GLException(e.getTargetException()); + } catch (InterruptedException e) { + throw new GLException(e); + } + } else { + action.run(); + } + } } diff --git a/src/net/java/games/jogl/impl/x11/X11OnscreenGLContext.java b/src/net/java/games/jogl/impl/x11/X11OnscreenGLContext.java index 7a661e9e3..cc4375117 100644 --- a/src/net/java/games/jogl/impl/x11/X11OnscreenGLContext.java +++ b/src/net/java/games/jogl/impl/x11/X11OnscreenGLContext.java @@ -56,15 +56,21 @@ public class X11OnscreenGLContext extends X11GLContext { } public boolean canCreatePbufferContext() { + return false; + /* return isExtensionAvailable("GL_ARB_pbuffer"); + */ } public GLDrawableImpl createPbufferDrawable(GLCapabilities capabilities, int initialWidth, int initialHeight) { + throw new GLException("No longer supported"); + /* X11PbufferGLDrawable buf = new X11PbufferGLDrawable(capabilities, initialWidth, initialHeight); pbuffersToInstantiate.add(buf); return buf; + */ } protected int makeCurrentImpl() throws GLException { @@ -84,6 +90,7 @@ public class X11OnscreenGLContext extends X11GLContext { } } int ret = super.makeCurrentImpl(); + /* if ((ret == CONTEXT_CURRENT) || (ret == CONTEXT_CURRENT_NEW)) { // Instantiate any pending pbuffers @@ -96,6 +103,7 @@ public class X11OnscreenGLContext extends X11GLContext { } } } + */ return ret; } catch (RuntimeException e) { try { diff --git a/src/net/java/games/jogl/impl/x11/X11PbufferGLDrawable.java b/src/net/java/games/jogl/impl/x11/X11PbufferGLDrawable.java index fc37f331b..775bf649f 100644 --- a/src/net/java/games/jogl/impl/x11/X11PbufferGLDrawable.java +++ b/src/net/java/games/jogl/impl/x11/X11PbufferGLDrawable.java @@ -69,6 +69,8 @@ public class X11PbufferGLDrawable extends X11GLDrawable { (capabilities.getOffscreenRenderToTextureRectangle() ? " [rect]" : "") + (capabilities.getOffscreenFloatingPointBuffers() ? " [float]" : "")); } + + createPbuffer(X11GLContextFactory.getDisplayConnection()); } public GLContext createContext(GLContext shareWith) { @@ -97,141 +99,150 @@ public class X11PbufferGLDrawable extends X11GLDrawable { return height; } - public void createPbuffer(GL gl, long display) { - if (display == 0) { - throw new GLException("Null display"); - } + public void createPbuffer(long display) { + lockAWT(); + try { + if (display == 0) { + throw new GLException("Null display"); + } - if (capabilities.getOffscreenRenderToTexture()) { - throw new GLException("Render-to-texture pbuffers not supported yet on X11"); - } + if (capabilities.getOffscreenRenderToTexture()) { + throw new GLException("Render-to-texture pbuffers not supported yet on X11"); + } - if (capabilities.getOffscreenRenderToTextureRectangle()) { - throw new GLException("Render-to-texture-rectangle pbuffers not supported yet on X11"); - } + if (capabilities.getOffscreenRenderToTextureRectangle()) { + throw new GLException("Render-to-texture-rectangle pbuffers not supported yet on X11"); + } - int[] iattributes = new int [2*MAX_ATTRIBS]; - float[] fattributes = new float[2*MAX_ATTRIBS]; - int nfattribs = 0; - int niattribs = 0; + int[] iattributes = new int [2*MAX_ATTRIBS]; + float[] fattributes = new float[2*MAX_ATTRIBS]; + int nfattribs = 0; + int niattribs = 0; - // Since we are trying to create a pbuffer, the GLXFBConfig we - // request (and subsequently use) must be "p-buffer capable". - iattributes[niattribs++] = GL.GLX_DRAWABLE_TYPE; - iattributes[niattribs++] = GL.GLX_PBUFFER_BIT; + // Since we are trying to create a pbuffer, the GLXFBConfig we + // request (and subsequently use) must be "p-buffer capable". + iattributes[niattribs++] = GL.GLX_DRAWABLE_TYPE; + iattributes[niattribs++] = GL.GLX_PBUFFER_BIT; - iattributes[niattribs++] = GL.GLX_RENDER_TYPE; - iattributes[niattribs++] = GL.GLX_RGBA_BIT; + iattributes[niattribs++] = GL.GLX_RENDER_TYPE; + iattributes[niattribs++] = GL.GLX_RGBA_BIT; - iattributes[niattribs++] = GLX.GLX_DOUBLEBUFFER; - if (capabilities.getDoubleBuffered()) { - iattributes[niattribs++] = GL.GL_TRUE; - } else { - iattributes[niattribs++] = GL.GL_FALSE; - } + iattributes[niattribs++] = GLX.GLX_DOUBLEBUFFER; + if (capabilities.getDoubleBuffered()) { + iattributes[niattribs++] = GL.GL_TRUE; + } else { + iattributes[niattribs++] = GL.GL_FALSE; + } - iattributes[niattribs++] = GLX.GLX_DEPTH_SIZE; - iattributes[niattribs++] = capabilities.getDepthBits(); + iattributes[niattribs++] = GLX.GLX_DEPTH_SIZE; + iattributes[niattribs++] = capabilities.getDepthBits(); - iattributes[niattribs++] = GLX.GLX_RED_SIZE; - iattributes[niattribs++] = capabilities.getRedBits(); + iattributes[niattribs++] = GLX.GLX_RED_SIZE; + iattributes[niattribs++] = capabilities.getRedBits(); - iattributes[niattribs++] = GLX.GLX_GREEN_SIZE; - iattributes[niattribs++] = capabilities.getGreenBits(); + iattributes[niattribs++] = GLX.GLX_GREEN_SIZE; + iattributes[niattribs++] = capabilities.getGreenBits(); - iattributes[niattribs++] = GLX.GLX_BLUE_SIZE; - iattributes[niattribs++] = capabilities.getBlueBits(); + iattributes[niattribs++] = GLX.GLX_BLUE_SIZE; + iattributes[niattribs++] = capabilities.getBlueBits(); - iattributes[niattribs++] = GLX.GLX_ALPHA_SIZE; - iattributes[niattribs++] = capabilities.getAlphaBits(); + iattributes[niattribs++] = GLX.GLX_ALPHA_SIZE; + iattributes[niattribs++] = capabilities.getAlphaBits(); - if (capabilities.getStencilBits() > 0) { - iattributes[niattribs++] = GLX.GLX_STENCIL_SIZE; - iattributes[niattribs++] = capabilities.getStencilBits(); - } + if (capabilities.getStencilBits() > 0) { + iattributes[niattribs++] = GLX.GLX_STENCIL_SIZE; + iattributes[niattribs++] = capabilities.getStencilBits(); + } - if (capabilities.getAccumRedBits() > 0 || - capabilities.getAccumGreenBits() > 0 || - capabilities.getAccumBlueBits() > 0) { - iattributes[niattribs++] = GLX.GLX_ACCUM_RED_SIZE; - iattributes[niattribs++] = capabilities.getAccumRedBits(); - iattributes[niattribs++] = GLX.GLX_ACCUM_GREEN_SIZE; - iattributes[niattribs++] = capabilities.getAccumGreenBits(); - iattributes[niattribs++] = GLX.GLX_ACCUM_BLUE_SIZE; - iattributes[niattribs++] = capabilities.getAccumBlueBits(); - } + if (capabilities.getAccumRedBits() > 0 || + capabilities.getAccumGreenBits() > 0 || + capabilities.getAccumBlueBits() > 0) { + iattributes[niattribs++] = GLX.GLX_ACCUM_RED_SIZE; + iattributes[niattribs++] = capabilities.getAccumRedBits(); + iattributes[niattribs++] = GLX.GLX_ACCUM_GREEN_SIZE; + iattributes[niattribs++] = capabilities.getAccumGreenBits(); + iattributes[niattribs++] = GLX.GLX_ACCUM_BLUE_SIZE; + iattributes[niattribs++] = capabilities.getAccumBlueBits(); + } - if (capabilities.getOffscreenFloatingPointBuffers()) { - if (!gl.isExtensionAvailable("GLX_NV_float_buffer")) { - throw new GLException("Floating-point pbuffers on X11 currently require NVidia hardware"); + int screen = 0; // FIXME: provide way to specify this? + + if (capabilities.getOffscreenFloatingPointBuffers()) { + // FIXME: + String glXExtensions = GLX.glXQueryExtensionsString(display, screen); + if (glXExtensions == null || + glXExtensions.indexOf("GLX_NV_float_buffer") < 0) { + throw new GLException("Floating-point pbuffers on X11 currently require NVidia hardware"); + } + iattributes[niattribs++] = GLX.GLX_FLOAT_COMPONENTS_NV; + iattributes[niattribs++] = GL.GL_TRUE; } - iattributes[niattribs++] = GLX.GLX_FLOAT_COMPONENTS_NV; - iattributes[niattribs++] = GL.GL_TRUE; - } - // FIXME: add FSAA support? Don't want to get into a situation - // where we have to retry the glXChooseFBConfig call if it fails - // due to a lack of an antialiased visual... + // FIXME: add FSAA support? Don't want to get into a situation + // where we have to retry the glXChooseFBConfig call if it fails + // due to a lack of an antialiased visual... - iattributes[niattribs++] = 0; // null-terminate + iattributes[niattribs++] = 0; // null-terminate - int screen = 0; // FIXME: provide way to specify this? - int[] nelementsTmp = new int[1]; - GLXFBConfig[] fbConfigs = GLX.glXChooseFBConfig(display, screen, iattributes, 0, nelementsTmp, 0); - if (fbConfigs == null || fbConfigs.length == 0 || fbConfigs[0] == null) { - throw new GLException("pbuffer creation error: glXChooseFBConfig() failed"); - } - // Note that we currently don't allow selection of anything but - // the first GLXFBConfig in the returned list - GLXFBConfig fbConfig = fbConfigs[0]; - int nelements = nelementsTmp[0]; - if (nelements <= 0) { - throw new GLException("pbuffer creation error: couldn't find a suitable frame buffer configuration"); - } + int[] nelementsTmp = new int[1]; + GLXFBConfig[] fbConfigs = GLX.glXChooseFBConfig(display, screen, iattributes, 0, nelementsTmp, 0); + if (fbConfigs == null || fbConfigs.length == 0 || fbConfigs[0] == null) { + throw new GLException("pbuffer creation error: glXChooseFBConfig() failed"); + } + // Note that we currently don't allow selection of anything but + // the first GLXFBConfig in the returned list + GLXFBConfig fbConfig = fbConfigs[0]; + int nelements = nelementsTmp[0]; + if (nelements <= 0) { + throw new GLException("pbuffer creation error: couldn't find a suitable frame buffer configuration"); + } - if (DEBUG) { - System.err.println("Found " + fbConfigs.length + " matching GLXFBConfigs"); - System.err.println("Parameters of default one:"); - System.err.println("render type: 0x" + Integer.toHexString(queryFBConfig(display, fbConfig, GLX.GLX_RENDER_TYPE))); - System.err.println("rgba: " + ((queryFBConfig(display, fbConfig, GLX.GLX_RENDER_TYPE) & GLX.GLX_RGBA_BIT) != 0)); - System.err.println("r: " + queryFBConfig(display, fbConfig, GLX.GLX_RED_SIZE)); - System.err.println("g: " + queryFBConfig(display, fbConfig, GLX.GLX_GREEN_SIZE)); - System.err.println("b: " + queryFBConfig(display, fbConfig, GLX.GLX_BLUE_SIZE)); - System.err.println("a: " + queryFBConfig(display, fbConfig, GLX.GLX_ALPHA_SIZE)); - System.err.println("depth: " + queryFBConfig(display, fbConfig, GLX.GLX_DEPTH_SIZE)); - System.err.println("double buffered: " + queryFBConfig(display, fbConfig, GLX.GLX_DOUBLEBUFFER)); - } + if (DEBUG) { + System.err.println("Found " + fbConfigs.length + " matching GLXFBConfigs"); + System.err.println("Parameters of default one:"); + System.err.println("render type: 0x" + Integer.toHexString(queryFBConfig(display, fbConfig, GLX.GLX_RENDER_TYPE))); + System.err.println("rgba: " + ((queryFBConfig(display, fbConfig, GLX.GLX_RENDER_TYPE) & GLX.GLX_RGBA_BIT) != 0)); + System.err.println("r: " + queryFBConfig(display, fbConfig, GLX.GLX_RED_SIZE)); + System.err.println("g: " + queryFBConfig(display, fbConfig, GLX.GLX_GREEN_SIZE)); + System.err.println("b: " + queryFBConfig(display, fbConfig, GLX.GLX_BLUE_SIZE)); + System.err.println("a: " + queryFBConfig(display, fbConfig, GLX.GLX_ALPHA_SIZE)); + System.err.println("depth: " + queryFBConfig(display, fbConfig, GLX.GLX_DEPTH_SIZE)); + System.err.println("double buffered: " + queryFBConfig(display, fbConfig, GLX.GLX_DOUBLEBUFFER)); + } - // Create the p-buffer. - niattribs = 0; + // Create the p-buffer. + niattribs = 0; - iattributes[niattribs++] = GL.GLX_PBUFFER_WIDTH; - iattributes[niattribs++] = initWidth; - iattributes[niattribs++] = GL.GLX_PBUFFER_HEIGHT; - iattributes[niattribs++] = initHeight; + iattributes[niattribs++] = GL.GLX_PBUFFER_WIDTH; + iattributes[niattribs++] = initWidth; + iattributes[niattribs++] = GL.GLX_PBUFFER_HEIGHT; + iattributes[niattribs++] = initHeight; - iattributes[niattribs++] = 0; + iattributes[niattribs++] = 0; - long tmpBuffer = GLX.glXCreatePbuffer(display, fbConfig, iattributes, 0); - if (tmpBuffer == 0) { - // FIXME: query X error code for detail error message - throw new GLException("pbuffer creation error: glXCreatePbuffer() failed"); - } + long tmpBuffer = GLX.glXCreatePbuffer(display, fbConfig, iattributes, 0); + if (tmpBuffer == 0) { + // FIXME: query X error code for detail error message + throw new GLException("pbuffer creation error: glXCreatePbuffer() failed"); + } - // Set up instance variables - this.display = display; - drawable = tmpBuffer; - this.fbConfig = fbConfig; + // Set up instance variables + this.display = display; + drawable = tmpBuffer; + this.fbConfig = fbConfig; - // Determine the actual width and height we were able to create. - int[] tmp = new int[1]; - GLX.glXQueryDrawable(display, drawable, GL.GLX_WIDTH, tmp, 0); - width = tmp[0]; - GLX.glXQueryDrawable(display, drawable, GL.GLX_HEIGHT, tmp, 0); - height = tmp[0]; + // Determine the actual width and height we were able to create. + int[] tmp = new int[1]; + GLX.glXQueryDrawable(display, drawable, GL.GLX_WIDTH, tmp, 0); + width = tmp[0]; + GLX.glXQueryDrawable(display, drawable, GL.GLX_HEIGHT, tmp, 0); + height = tmp[0]; - if (DEBUG) { - System.err.println("Created pbuffer " + width + " x " + height); + if (DEBUG) { + System.err.println("Created pbuffer " + width + " x " + height); + } + } finally { + unlockAWT(); } } -- cgit v1.2.3