diff options
author | Kenneth Russel <[email protected]> | 2008-12-20 08:58:00 +0000 |
---|---|---|
committer | Kenneth Russel <[email protected]> | 2008-12-20 08:58:00 +0000 |
commit | 6eda9476e8168bacdeb1854540d89bd9db0d5029 (patch) | |
tree | 692317f9924638836b16bf83a9cefe0c1047bb66 /src/classes/com/sun/opengl/impl/x11 | |
parent | 14a94c810910f88d3b7214ae9be5027dc74df39f (diff) |
Factored out the remaining toolkit, and specifically AWT, dependencies
from GLDrawableFactory implementations into NativeWindowFactory
implementations. These dependencies were the up-front selection of the
GraphicsConfiguration and the locking and unlocking of the toolkit,
which are both currently needed only on X11 platforms due to how
OpenGL and the window system interact there. Added X11GraphicsDevice
and X11GraphicsConfiguration classes which are intended to be used by
Newt or potentially other third-party window toolkits. Unified the
separate NativeWindow and AWT GLDrawableFactory implementations in the
GLDrawableFactory class.
Exposed the toolkit locking mechanism through the NativeWindowFactory
and introduced the concept of a default NativeWindowFactory which is
used by the X11 drawable and context implementations. Removed
unnecessary toolkit locking calls from Mac OS X and Windows drawable
and context implementations.
Added a registration mechanism for new NativeWindowFactories, allowing
third parties to plug in new window toolkits orthogonally to the
OpenGL drawable and context code.
The public APIs for the NativeWindowFactory and the GLDrawableFactory,
in particular how they are fetched, changed as a result of these
refactorings. Updated all uses.
Fixed bug in X11OffscreenGLXDrawable introduced during last set of
changes.
Tested demos on Solaris, Mac OS X and Windows.
git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/svn-server-sync/jogl/branches/JOGL_2_SANDBOX@1824 232f8b59-042b-4e1e-8c03-345bb8c30851
Diffstat (limited to 'src/classes/com/sun/opengl/impl/x11')
9 files changed, 440 insertions, 278 deletions
diff --git a/src/classes/com/sun/opengl/impl/x11/glx/X11GLXContext.java b/src/classes/com/sun/opengl/impl/x11/glx/X11GLXContext.java index b18cc6623..88f11d259 100644 --- a/src/classes/com/sun/opengl/impl/x11/glx/X11GLXContext.java +++ b/src/classes/com/sun/opengl/impl/x11/glx/X11GLXContext.java @@ -250,10 +250,7 @@ public abstract class X11GLXContext extends GLContextImpl { } if (glXQueryExtensionsStringAvailable) { GLDrawableFactoryImpl factory = getDrawableImpl().getFactoryImpl(); - boolean wasLocked = factory.isToolkitLocked(); - if(!wasLocked) { - factory.lockToolkit(); - } + factory.lockToolkit(); try { String ret = GLX.glXQueryExtensionsString(drawable.getNativeWindow().getDisplayHandle(), drawable.getNativeWindow().getScreenIndex()); @@ -262,9 +259,7 @@ public abstract class X11GLXContext extends GLContextImpl { } return ret; } finally { - if(!wasLocked) { - factory.unlockToolkit(); - } + factory.unlockToolkit(); } } else { return ""; @@ -339,7 +334,7 @@ public abstract class X11GLXContext extends GLContextImpl { public boolean isOptimizable() { return (super.isOptimizable() && - !((X11GLXDrawableFactory)getGLDrawable().getFactory()).isVendorATI()); + !X11Util.isVendorATI()); } //---------------------------------------------------------------------- diff --git a/src/classes/com/sun/opengl/impl/x11/glx/X11GLXDrawable.java b/src/classes/com/sun/opengl/impl/x11/glx/X11GLXDrawable.java index cf34d9492..96e2d897f 100644 --- a/src/classes/com/sun/opengl/impl/x11/glx/X11GLXDrawable.java +++ b/src/classes/com/sun/opengl/impl/x11/glx/X11GLXDrawable.java @@ -105,11 +105,7 @@ public abstract class X11GLXDrawable extends GLDrawableImpl { template.screen(screen); XVisualInfo[] infos = null; GLCapabilities[] caps = null; - boolean didLock = false; - if (!getFactoryImpl().isToolkitLocked()) { - getFactoryImpl().lockToolkit(); - didLock = true; - } + getFactoryImpl().lockToolkit(); try { infos = X11Lib.XGetVisualInfo(display, X11Lib.VisualScreenMask, template, count, 0); if (infos == null) { @@ -120,9 +116,7 @@ public abstract class X11GLXDrawable extends GLDrawableImpl { caps[i] = ((X11GLXDrawableFactory)getFactory()).xvi2GLCapabilities(display, infos[i]); } } finally { - if (didLock) { - getFactoryImpl().unlockToolkit(); - } + getFactoryImpl().unlockToolkit(); } GLCapabilities capabilities = getRequestedGLCapabilities(); int chosen = chooser.chooseCapabilities(capabilities, caps, -1); diff --git a/src/classes/com/sun/opengl/impl/x11/glx/X11GLXDrawableFactory.java b/src/classes/com/sun/opengl/impl/x11/glx/X11GLXDrawableFactory.java index 75011ec88..d99b237e5 100644 --- a/src/classes/com/sun/opengl/impl/x11/glx/X11GLXDrawableFactory.java +++ b/src/classes/com/sun/opengl/impl/x11/glx/X11GLXDrawableFactory.java @@ -48,14 +48,11 @@ import com.sun.opengl.impl.x11.*; public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { protected static final boolean DEBUG = Debug.debug("X11GLXDrawableFactory"); - // ATI's proprietary drivers apparently send GLX tokens even for - // direct contexts, so we need to disable the context optimizations - // in this case - private static boolean isVendorATI; - // Map for rediscovering the GLCapabilities associated with a // particular screen and visualID after the fact protected static Map visualToGLCapsMap = Collections.synchronizedMap(new HashMap()); + // The screens for which we've already initialized it + protected static Set/*<Integer>*/ initializedScreenSet = Collections.synchronizedSet(new HashSet()); public static class ScreenAndVisualIDKey { private int screen; @@ -110,6 +107,21 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { return new X11OnscreenGLXDrawable(this, target); } + public void initializeVisualToGLCapabilitiesMap(int screen, + XVisualInfo[] infos, + GLCapabilities[] caps) { + Integer key = new Integer(screen); + if (!initializedScreenSet.contains(key)) { + for (int i = 0; i < infos.length; i++) { + if (caps[i] != null) { + visualToGLCapsMap.put(new ScreenAndVisualIDKey(screen, infos[i].visualid()), + caps[i].clone()); + } + } + initializedScreenSet.add(key); + } + } + public GLCapabilities lookupCapabilitiesByScreenAndVisualID(int screenIndex, long visualID) { return (GLCapabilities) visualToGLCapsMap.get(new ScreenAndVisualIDKey(screenIndex, visualID)); @@ -128,7 +140,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { if (!pbufferSupportInitialized) { Runnable r = new Runnable() { public void run() { - long display = getDisplayConnection(); + long display = X11Util.getDisplayConnection(); lockToolkit(); try { int[] major = new int[1]; @@ -245,7 +257,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { res.setAccumGreenBits(glXGetConfig(display, info, GLX.GLX_ACCUM_GREEN_SIZE, tmp, 0)); res.setAccumBlueBits (glXGetConfig(display, info, GLX.GLX_ACCUM_BLUE_SIZE, tmp, 0)); res.setAccumAlphaBits(glXGetConfig(display, info, GLX.GLX_ACCUM_ALPHA_SIZE, tmp, 0)); - if (isMultisampleAvailable()) { + if (X11Util.isMultisampleAvailable()) { res.setSampleBuffers(glXGetConfig(display, info, GLX.GLX_SAMPLE_BUFFERS, tmp, 0) != 0); res.setNumSamples (glXGetConfig(display, info, GLX.GLX_SAMPLES, tmp, 0)); } @@ -419,63 +431,6 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { return caps; } - // Display connection for use by visual selection algorithm and by all offscreen surfaces - private static long staticDisplay=0; - private static boolean xineramaEnabled=false; - private static boolean multisampleAvailable=false; - public static long getDisplayConnection() { - if (staticDisplay == 0) { - // FIXME: lockToolkit(); - try { - staticDisplay = X11Lib.XOpenDisplay(null); - if (DEBUG && (staticDisplay != 0)) { - long display = staticDisplay; - int screen = X11Lib.DefaultScreen(display); - System.err.println("!!! GLX server vendor : " + - GLX.glXQueryServerString(display, screen, GLX.GLX_VENDOR)); - System.err.println("!!! GLX server version: " + - GLX.glXQueryServerString(display, screen, GLX.GLX_VERSION)); - System.err.println("!!! GLX client vendor : " + - GLX.glXGetClientString(display, GLX.GLX_VENDOR)); - System.err.println("!!! GLX client version: " + - GLX.glXGetClientString(display, GLX.GLX_VERSION)); - } - - if (staticDisplay != 0) { - String vendor = GLX.glXGetClientString(staticDisplay, GLX.GLX_VENDOR); - if (vendor != null && vendor.startsWith("ATI")) { - isVendorATI = true; - } - xineramaEnabled = X11Lib.XineramaEnabled(staticDisplay); - String exts = GLX.glXGetClientString(staticDisplay, GLX.GLX_EXTENSIONS); - if (exts != null) { - multisampleAvailable = (exts.indexOf("GLX_ARB_multisample") >= 0); - } - } - } finally { - // FIXME: unlockToolkit(); - } - if (staticDisplay == 0) { - throw new GLException("Unable to open default display, needed for visual selection and offscreen surface handling"); - } - } - return staticDisplay; - } - - public boolean isXineramaEnabled() { - if (staticDisplay == 0) { - getDisplayConnection(); // will set xineramaEnabled - } - return xineramaEnabled; - } - - public boolean isMultisampleAvailable() { - if (staticDisplay == 0) { - getDisplayConnection(); // will set multisampleAvailable - } - return multisampleAvailable; - } - private static String glXGetConfigErrorCode(int err) { switch (err) { case GLX.GLX_NO_EXTENSION: return "GLX_NO_EXTENSION"; @@ -497,12 +452,6 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { return tmp[tmp_offset]; } - /** Workaround for apparent issue with ATI's proprietary drivers - where direct contexts still send GLX tokens for GL calls */ - public static boolean isVendorATI() { - return isVendorATI; - } - private void maybeDoSingleThreadedWorkaround(Runnable action) { if (Threading.isSingleThreaded() && !Threading.isOpenGLThread()) { @@ -534,7 +483,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { int[] size = new int[1]; lockToolkit(); - long display = getDisplayConnection(); + long display = X11Util.getDisplayConnection(); boolean res = X11Lib.XF86VidModeGetGammaRampSize(display, X11Lib.DefaultScreen(display), size, 0); @@ -554,7 +503,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { } lockToolkit(); - long display = getDisplayConnection(); + long display = X11Util.getDisplayConnection(); boolean res = X11Lib.XF86VidModeSetGammaRamp(display, X11Lib.DefaultScreen(display), rampData.length, @@ -578,7 +527,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { rampData.limit(3 * size); ShortBuffer blueRampData = rampData.slice(); lockToolkit(); - long display = getDisplayConnection(); + long display = X11Util.getDisplayConnection(); boolean res = X11Lib.XF86VidModeGetGammaRamp(display, X11Lib.DefaultScreen(display), size, @@ -610,7 +559,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { rampData.limit(3 * size); ShortBuffer blueRampData = rampData.slice(); lockToolkit(); - long display = getDisplayConnection(); + long display = X11Util.getDisplayConnection(); X11Lib.XF86VidModeSetGammaRamp(display, X11Lib.DefaultScreen(display), size, diff --git a/src/classes/com/sun/opengl/impl/x11/glx/X11GLXNativeWindowFactory.java b/src/classes/com/sun/opengl/impl/x11/glx/X11GLXNativeWindowFactory.java new file mode 100644 index 000000000..98ade1c06 --- /dev/null +++ b/src/classes/com/sun/opengl/impl/x11/glx/X11GLXNativeWindowFactory.java @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +package com.sun.opengl.impl.x11.glx; + +import javax.media.opengl.*; + +import com.sun.opengl.impl.*; +import com.sun.opengl.impl.x11.*; + +/** Subclass of NativeWindowFactory used when non-AWT tookits are used + on X11 platforms. Toolkits will likely need to subclass this one + to add synchronization in certain places and change the accepted + and returned types of the GraphicsDevice and GraphicsConfiguration + abstractions. */ + +public class X11GLXNativeWindowFactory extends NativeWindowFactoryImpl { + public AbstractGraphicsConfiguration chooseGraphicsConfiguration(GLCapabilities capabilities, + GLCapabilitiesChooser chooser, + AbstractGraphicsDevice absDevice) { + if (absDevice != null && + !(absDevice instanceof X11GraphicsDevice)) { + throw new IllegalArgumentException("This NativeWindowFactory accepts only X11GraphicsDevice objects"); + } + + int screen = 0; + if (absDevice != null) { + screen = ((X11GraphicsDevice) absDevice).getScreen(); + } + + long visualID = chooseGraphicsConfigurationImpl(capabilities, chooser, screen); + return new X11GraphicsConfiguration(visualID); + } + + /** Returns the visual ID of the chosen GraphicsConfiguration. */ + protected long chooseGraphicsConfigurationImpl(GLCapabilities capabilities, + GLCapabilitiesChooser chooser, + int screen) { + if (capabilities == null) { + capabilities = new GLCapabilities(); + } + if (chooser == null) { + chooser = new DefaultGLCapabilitiesChooser(); + } + + if (X11Util.isXineramaEnabled()) { + screen = 0; + } + + // Until we have a rock-solid visual selection algorithm written + // in pure Java, we're going to provide the underlying window + // system's selection to the chooser as a hint + + int[] attribs = X11GLXDrawableFactory.glCapabilities2AttribList(capabilities, X11Util.isMultisampleAvailable(), false, 0, 0); + XVisualInfo[] infos = null; + GLCapabilities[] caps = null; + int recommendedIndex = -1; + getDefaultFactory().getToolkitLock().lock(); + try { + long display = X11Util.getDisplayConnection(); + XVisualInfo recommendedVis = GLX.glXChooseVisual(display, screen, attribs, 0); + if (DEBUG) { + System.err.print("!!! glXChooseVisual recommended "); + if (recommendedVis == null) { + System.err.println("null visual"); + } else { + System.err.println("visual id 0x" + Long.toHexString(recommendedVis.visualid())); + } + } + int[] count = new int[1]; + XVisualInfo template = XVisualInfo.create(); + template.screen(screen); + infos = X11Lib.XGetVisualInfo(display, X11Lib.VisualScreenMask, template, count, 0); + if (infos == null) { + throw new GLException("Error while enumerating available XVisualInfos"); + } + caps = new GLCapabilities[infos.length]; + for (int i = 0; i < infos.length; i++) { + caps[i] = ((X11GLXDrawableFactory) GLDrawableFactory.getFactory()).xvi2GLCapabilities(display, infos[i]); + // Attempt to find the visual chosen by glXChooseVisual + if (recommendedVis != null && recommendedVis.visualid() == infos[i].visualid()) { + recommendedIndex = i; + } + } + } finally { + getDefaultFactory().getToolkitLock().unlock(); + } + // Store these away for later + ((X11GLXDrawableFactory) GLDrawableFactory.getFactory()). + initializeVisualToGLCapabilitiesMap(screen, infos, caps); + int chosen = chooser.chooseCapabilities(capabilities, caps, recommendedIndex); + if (chosen < 0 || chosen >= caps.length) { + throw new GLException("GLCapabilitiesChooser specified invalid index (expected 0.." + (caps.length - 1) + ")"); + } + XVisualInfo vis = infos[chosen]; + if (vis == null) { + throw new GLException("GLCapabilitiesChooser chose an invalid visual"); + } + return vis.visualid(); + } + + // On X11 platforms we need to do some locking; this basic + // implementation should suffice for some simple window toolkits + private ToolkitLock toolkitLock = new ToolkitLock() { + private Thread owner; + private int recursionCount; + + public synchronized void lock() { + Thread cur = Thread.currentThread(); + if (owner == cur) { + ++recursionCount; + return; + } + while (owner != null) { + try { + wait(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + owner = cur; + } + + public synchronized void unlock() { + if (owner != Thread.currentThread()) { + throw new RuntimeException("Not owner"); + } + if (recursionCount > 0) { + --recursionCount; + return; + } + owner = null; + } + }; + + public ToolkitLock getToolkitLock() { + return toolkitLock; + } +} diff --git a/src/classes/com/sun/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java b/src/classes/com/sun/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java index bd2eb9921..035b86708 100644 --- a/src/classes/com/sun/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java +++ b/src/classes/com/sun/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java @@ -54,6 +54,7 @@ public class X11OffscreenGLXDrawable extends X11GLXDrawable { int height) { super(factory, new NullWindow(), true, requestedCapabilities, chooser); ((NullWindow) getNativeWindow()).setSize(width, height); + create(); } public GLContext createContext(GLContext shareWith) { @@ -62,7 +63,7 @@ public class X11OffscreenGLXDrawable extends X11GLXDrawable { private void create() { NullWindow nw = (NullWindow) getNativeWindow(); - long dpy = X11GLXDrawableFactory.getDisplayConnection(); + long dpy = X11Util.getDisplayConnection(); nw.setDisplayHandle(dpy); XVisualInfo vis = chooseVisual(false); int bitsPerPixel = vis.depth(); diff --git a/src/classes/com/sun/opengl/impl/x11/glx/X11PbufferGLXDrawable.java b/src/classes/com/sun/opengl/impl/x11/glx/X11PbufferGLXDrawable.java index 3df6d486a..aa84b034a 100644 --- a/src/classes/com/sun/opengl/impl/x11/glx/X11PbufferGLXDrawable.java +++ b/src/classes/com/sun/opengl/impl/x11/glx/X11PbufferGLXDrawable.java @@ -70,7 +70,7 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable { (requestedCapabilities.getPbufferFloatingPointBuffers() ? " [float]" : "")); } - nw.setDisplayHandle(X11GLXDrawableFactory.getDisplayConnection()); + nw.setDisplayHandle(X11Util.getDisplayConnection()); createPbuffer(); } @@ -115,7 +115,7 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable { } int[] iattributes = X11GLXDrawableFactory.glCapabilities2AttribList(capabilities, - ((X11GLXDrawableFactory)getFactory()).isMultisampleAvailable(), + X11Util.isMultisampleAvailable(), true, display, screen); int[] nelementsTmp = new int[1]; @@ -165,8 +165,8 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable { this.fbConfig = fbConfig; // Pick innocent query values if multisampling or floating point buffers not available - int sbAttrib = ((X11GLXDrawableFactory)getFactory()).isMultisampleAvailable() ? GLXExt.GLX_SAMPLE_BUFFERS: GLX.GLX_RED_SIZE; - int samplesAttrib = ((X11GLXDrawableFactory)getFactory()).isMultisampleAvailable() ? GLXExt.GLX_SAMPLES: GLX.GLX_RED_SIZE; + int sbAttrib = X11Util.isMultisampleAvailable() ? GLXExt.GLX_SAMPLE_BUFFERS: GLX.GLX_RED_SIZE; + int samplesAttrib = X11Util.isMultisampleAvailable() ? GLXExt.GLX_SAMPLES: GLX.GLX_RED_SIZE; int floatNV = capabilities.getPbufferFloatingPointBuffers() ? GLXExt.GLX_FLOAT_COMPONENTS_NV : GLX.GLX_RED_SIZE; // Query the fbconfig to determine its GLCapabilities diff --git a/src/classes/com/sun/opengl/impl/x11/glx/X11Util.java b/src/classes/com/sun/opengl/impl/x11/glx/X11Util.java new file mode 100644 index 000000000..480c607a4 --- /dev/null +++ b/src/classes/com/sun/opengl/impl/x11/glx/X11Util.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +package com.sun.opengl.impl.x11.glx; + +import javax.media.opengl.*; + +import com.sun.opengl.impl.*; +import com.sun.opengl.impl.x11.*; + +public class X11Util { + private static final boolean DEBUG = Debug.debug("X11Util"); + + private X11Util() {} + + // ATI's proprietary drivers apparently send GLX tokens even for + // direct contexts, so we need to disable the context optimizations + // in this case + private static boolean isVendorATI; + + // Display connection for use by visual selection algorithm and by all offscreen surfaces + private static long staticDisplay=0; + private static boolean xineramaEnabled=false; + private static boolean multisampleAvailable=false; + public static long getDisplayConnection() { + if (staticDisplay == 0) { + NativeWindowFactory.getDefaultFactory().getToolkitLock().lock(); + try { + staticDisplay = X11Lib.XOpenDisplay(null); + if (DEBUG && (staticDisplay != 0)) { + long display = staticDisplay; + int screen = X11Lib.DefaultScreen(display); + System.err.println("!!! GLX server vendor : " + + GLX.glXQueryServerString(display, screen, GLX.GLX_VENDOR)); + System.err.println("!!! GLX server version: " + + GLX.glXQueryServerString(display, screen, GLX.GLX_VERSION)); + System.err.println("!!! GLX client vendor : " + + GLX.glXGetClientString(display, GLX.GLX_VENDOR)); + System.err.println("!!! GLX client version: " + + GLX.glXGetClientString(display, GLX.GLX_VERSION)); + } + + if (staticDisplay != 0) { + String vendor = GLX.glXGetClientString(staticDisplay, GLX.GLX_VENDOR); + if (vendor != null && vendor.startsWith("ATI")) { + isVendorATI = true; + } + xineramaEnabled = X11Lib.XineramaEnabled(staticDisplay); + String exts = GLX.glXGetClientString(staticDisplay, GLX.GLX_EXTENSIONS); + if (exts != null) { + multisampleAvailable = (exts.indexOf("GLX_ARB_multisample") >= 0); + } + } + } finally { + NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock(); + } + if (staticDisplay == 0) { + throw new GLException("Unable to open default display, needed for visual selection and offscreen surface handling"); + } + } + return staticDisplay; + } + + public static boolean isXineramaEnabled() { + if (staticDisplay == 0) { + getDisplayConnection(); // will set xineramaEnabled + } + return xineramaEnabled; + } + + public static boolean isMultisampleAvailable() { + if (staticDisplay == 0) { + getDisplayConnection(); // will set multisampleAvailable + } + return multisampleAvailable; + } + + /** Workaround for apparent issue with ATI's proprietary drivers + where direct contexts still send GLX tokens for GL calls */ + public static boolean isVendorATI() { + return isVendorATI; + } +} diff --git a/src/classes/com/sun/opengl/impl/x11/glx/awt/X11AWTGLXDrawableFactory.java b/src/classes/com/sun/opengl/impl/x11/glx/awt/X11AWTGLXDrawableFactory.java deleted file mode 100644 index a5ec4c46c..000000000 --- a/src/classes/com/sun/opengl/impl/x11/glx/awt/X11AWTGLXDrawableFactory.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - * You acknowledge that this software is not designed or intended for use - * in the design, construction, operation or maintenance of any nuclear - * facility. - */ - -package com.sun.opengl.impl.x11.glx.awt; - -import com.sun.opengl.impl.*; -import com.sun.opengl.impl.x11.*; -import com.sun.opengl.impl.x11.glx.*; -import com.sun.opengl.impl.jawt.*; -import com.sun.opengl.impl.jawt.x11.*; -import java.awt.Graphics; -import java.awt.GraphicsConfiguration; -import java.awt.GraphicsDevice; -import java.awt.GraphicsEnvironment; -import java.nio.*; -import java.security.*; -import java.util.*; -import javax.media.opengl.*; -import javax.media.opengl.awt.*; -import com.sun.gluegen.runtime.*; - -public class X11AWTGLXDrawableFactory extends X11GLXDrawableFactory { - - static { - // See DRIHack.java for an explanation of why this is necessary - DRIHack.begin(); - - com.sun.opengl.impl.NativeLibLoader.loadGL2(); - - DRIHack.end(); - } - - public AbstractGraphicsConfiguration chooseGraphicsConfiguration(GLCapabilities capabilities, - GLCapabilitiesChooser chooser, - AbstractGraphicsDevice absDevice) { - if (capabilities == null) { - capabilities = new GLCapabilities(); - } - if (chooser == null) { - chooser = new DefaultGLCapabilitiesChooser(); - } - GraphicsDevice device = null; - if (absDevice != null && - !(absDevice instanceof AWTGraphicsDevice)) { - throw new IllegalArgumentException("This GLDrawableFactory accepts only AWTGraphicsDevice objects"); - } - - if ((absDevice == null) || - (((AWTGraphicsDevice) absDevice).getGraphicsDevice() == null)) { - device = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice(); - } else { - device = ((AWTGraphicsDevice) absDevice).getGraphicsDevice(); - } - - int screen; - if (isXineramaEnabled()) { - screen = 0; - } else { - screen = X11SunJDKReflection.graphicsDeviceGetScreen(device); - } - - // Until we have a rock-solid visual selection algorithm written - // in pure Java, we're going to provide the underlying window - // system's selection to the chooser as a hint - - int[] attribs = glCapabilities2AttribList(capabilities, isMultisampleAvailable(), false, 0, 0); - XVisualInfo[] infos = null; - GLCapabilities[] caps = null; - int recommendedIndex = -1; - lockToolkit(); - try { - long display = getDisplayConnection(); - XVisualInfo recommendedVis = GLX.glXChooseVisual(display, screen, attribs, 0); - if (DEBUG) { - System.err.print("!!! glXChooseVisual recommended "); - if (recommendedVis == null) { - System.err.println("null visual"); - } else { - System.err.println("visual id 0x" + Long.toHexString(recommendedVis.visualid())); - } - } - int[] count = new int[1]; - XVisualInfo template = XVisualInfo.create(); - template.screen(screen); - infos = X11Lib.XGetVisualInfo(display, X11Lib.VisualScreenMask, template, count, 0); - if (infos == null) { - throw new GLException("Error while enumerating available XVisualInfos"); - } - caps = new GLCapabilities[infos.length]; - for (int i = 0; i < infos.length; i++) { - caps[i] = xvi2GLCapabilities(display, infos[i]); - // Attempt to find the visual chosen by glXChooseVisual - if (recommendedVis != null && recommendedVis.visualid() == infos[i].visualid()) { - recommendedIndex = i; - } - } - } finally { - unlockToolkit(); - } - // Store these away for later - for (int i = 0; i < infos.length; i++) { - if (caps[i] != null) { - visualToGLCapsMap.put(new ScreenAndVisualIDKey(screen, infos[i].visualid()), - caps[i].clone()); - } - } - int chosen = chooser.chooseCapabilities(capabilities, caps, recommendedIndex); - if (chosen < 0 || chosen >= caps.length) { - throw new GLException("GLCapabilitiesChooser specified invalid index (expected 0.." + (caps.length - 1) + ")"); - } - XVisualInfo vis = infos[chosen]; - if (vis == null) { - throw new GLException("GLCapabilitiesChooser chose an invalid visual"); - } - // FIXME: need to look at glue code and see type of this field - long visualID = vis.visualid(); - // FIXME: the storage for the infos array, as well as that for the - // recommended visual, is leaked; should free them here with XFree() - - // Now figure out which GraphicsConfiguration corresponds to this - // visual by matching the visual ID - GraphicsConfiguration[] configs = device.getConfigurations(); - for (int i = 0; i < configs.length; i++) { - GraphicsConfiguration config = configs[i]; - if (config != null) { - if (X11SunJDKReflection.graphicsConfigurationGetVisualID(config) == visualID) { - return new AWTGraphicsConfiguration(config); - } - } - } - - // Either we weren't able to reflectively introspect on the - // X11GraphicsConfig or something went wrong in the steps above; - // we're going to return null without signaling an error condition - // in this case (although we should distinguish between the two - // and possibly report more of an error in the latter case) - return null; - } - - public void lockToolkit() { - super.lockToolkit(); - JAWTUtil.lockToolkit(); - } - - public void unlockToolkit() { - JAWTUtil.unlockToolkit(); - super.unlockToolkit(); - } - -} diff --git a/src/classes/com/sun/opengl/impl/x11/glx/awt/X11AWTGLXNativeWindowFactory.java b/src/classes/com/sun/opengl/impl/x11/glx/awt/X11AWTGLXNativeWindowFactory.java new file mode 100644 index 000000000..11da7af05 --- /dev/null +++ b/src/classes/com/sun/opengl/impl/x11/glx/awt/X11AWTGLXNativeWindowFactory.java @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +package com.sun.opengl.impl.x11.glx.awt; + +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import javax.media.opengl.*; +import javax.media.opengl.awt.*; + +import com.sun.opengl.impl.*; +import com.sun.opengl.impl.jawt.*; +import com.sun.opengl.impl.jawt.x11.*; +import com.sun.opengl.impl.x11.*; +import com.sun.opengl.impl.x11.glx.*; + +public class X11AWTGLXNativeWindowFactory extends X11GLXNativeWindowFactory { + public AbstractGraphicsConfiguration chooseGraphicsConfiguration(GLCapabilities capabilities, + GLCapabilitiesChooser chooser, + AbstractGraphicsDevice absDevice) { + GraphicsDevice device = null; + if (absDevice != null && + !(absDevice instanceof AWTGraphicsDevice)) { + throw new IllegalArgumentException("This NativeWindowFactory accepts only AWTGraphicsDevice objects"); + } + + if ((absDevice == null) || + (((AWTGraphicsDevice) absDevice).getGraphicsDevice() == null)) { + device = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice(); + } else { + device = ((AWTGraphicsDevice) absDevice).getGraphicsDevice(); + } + + long visualID = chooseGraphicsConfigurationImpl(capabilities, chooser, + X11SunJDKReflection.graphicsDeviceGetScreen(device)); + + // Now figure out which GraphicsConfiguration corresponds to this + // visual by matching the visual ID + GraphicsConfiguration[] configs = device.getConfigurations(); + for (int i = 0; i < configs.length; i++) { + GraphicsConfiguration config = configs[i]; + if (config != null) { + if (X11SunJDKReflection.graphicsConfigurationGetVisualID(config) == visualID) { + return new AWTGraphicsConfiguration(config); + } + } + } + + // Either we weren't able to reflectively introspect on the + // X11GraphicsConfig or something went wrong in the steps above; + // we're going to return null without signaling an error condition + // in this case (although we should distinguish between the two + // and possibly report more of an error in the latter case) + return null; + } + + // When running the AWT on X11 platforms, we use the AWT native + // interface (JAWT) to lock and unlock the toolkit + private ToolkitLock toolkitLock = new ToolkitLock() { + private Thread owner; + private int recursionCount; + + public synchronized void lock() { + Thread cur = Thread.currentThread(); + if (owner == cur) { + ++recursionCount; + return; + } + while (owner != null) { + try { + wait(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + owner = cur; + JAWTUtil.lockToolkit(); + } + + public synchronized void unlock() { + if (owner != Thread.currentThread()) { + throw new RuntimeException("Not owner"); + } + if (recursionCount > 0) { + --recursionCount; + return; + } + owner = null; + JAWTUtil.unlockToolkit(); + } + }; + + public ToolkitLock getToolkitLock() { + return toolkitLock; + } +} |