summaryrefslogtreecommitdiffstats
path: root/src/net/java
diff options
context:
space:
mode:
Diffstat (limited to 'src/net/java')
-rw-r--r--src/net/java/games/jogl/DefaultGLCapabilitiesChooser.java17
-rw-r--r--src/net/java/games/jogl/GLCanvas.java8
-rw-r--r--src/net/java/games/jogl/GLCapabilitiesChooser.java9
-rw-r--r--src/net/java/games/jogl/GLDrawableFactory.java83
-rw-r--r--src/net/java/games/jogl/Version.java2
-rw-r--r--src/net/java/games/jogl/impl/GLContextFactory.java14
-rw-r--r--src/net/java/games/jogl/impl/macosx/MacOSXGLContextFactory.java8
-rw-r--r--src/net/java/games/jogl/impl/windows/WindowsGLContext.java5
-rw-r--r--src/net/java/games/jogl/impl/windows/WindowsGLContextFactory.java8
-rw-r--r--src/net/java/games/jogl/impl/x11/X11GLContext.java194
-rw-r--r--src/net/java/games/jogl/impl/x11/X11GLContextFactory.java169
-rw-r--r--src/net/java/games/jogl/impl/x11/X11OffscreenGLContext.java17
-rw-r--r--src/net/java/games/jogl/impl/x11/X11OnscreenGLContext.java5
13 files changed, 360 insertions, 179 deletions
diff --git a/src/net/java/games/jogl/DefaultGLCapabilitiesChooser.java b/src/net/java/games/jogl/DefaultGLCapabilitiesChooser.java
index de7f500b5..8d5ecabc9 100644
--- a/src/net/java/games/jogl/DefaultGLCapabilitiesChooser.java
+++ b/src/net/java/games/jogl/DefaultGLCapabilitiesChooser.java
@@ -71,13 +71,28 @@ package net.java.games.jogl;
than accumulation buffer (including alpha) and stencil buffer
depth mismatches.
+ <LI> If a valid windowSystemRecommendedChoice parameter is
+ supplied, chooses that instead of using the cross-platform code.
+
</UL>
*/
public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser {
private static final boolean DEBUG = false;
- public int chooseCapabilities(GLCapabilities desired, GLCapabilities[] available) {
+ public int chooseCapabilities(GLCapabilities desired,
+ GLCapabilities[] available,
+ int windowSystemRecommendedChoice) {
+ if (windowSystemRecommendedChoice >= 0 &&
+ windowSystemRecommendedChoice < available.length &&
+ available[windowSystemRecommendedChoice] != null) {
+ if (DEBUG) {
+ System.err.println("Choosing window system's recommended choice of " + windowSystemRecommendedChoice);
+ System.err.println(available[windowSystemRecommendedChoice]);
+ }
+ return windowSystemRecommendedChoice;
+ }
+
if (DEBUG) {
for (int i = 0; i < available.length; i++) {
System.err.println("Available " + i + ": " + available[i]);
diff --git a/src/net/java/games/jogl/GLCanvas.java b/src/net/java/games/jogl/GLCanvas.java
index 9d58930e4..ee33a14c9 100644
--- a/src/net/java/games/jogl/GLCanvas.java
+++ b/src/net/java/games/jogl/GLCanvas.java
@@ -61,14 +61,6 @@ public final class GLCanvas extends Canvas implements GLDrawable {
private GLDrawableHelper drawableHelper = new GLDrawableHelper();
private GLContext context;
- GLCanvas(GLCapabilities capabilities,
- GLCapabilitiesChooser chooser,
- GLDrawable shareWith) {
- super();
- context = GLContextFactory.getFactory().createGLContext(this, capabilities, chooser,
- GLContextHelper.getContext(shareWith));
- }
-
GLCanvas(GraphicsConfiguration config,
GLCapabilities capabilities,
GLCapabilitiesChooser chooser,
diff --git a/src/net/java/games/jogl/GLCapabilitiesChooser.java b/src/net/java/games/jogl/GLCapabilitiesChooser.java
index 16b0e2b76..78486f1e9 100644
--- a/src/net/java/games/jogl/GLCapabilitiesChooser.java
+++ b/src/net/java/games/jogl/GLCapabilitiesChooser.java
@@ -47,6 +47,11 @@ public interface GLCapabilitiesChooser {
GLCapabilities} most closely matching the desired one from the
list of all supported. Some of the entries in the
<code>available</code> array may be null; the chooser must
- ignore these. */
- public int chooseCapabilities(GLCapabilities desired, GLCapabilities[] available);
+ ignore these. The <em>windowSystemRecommendedChoice</em>
+ parameter may be provided to the chooser by the underlying
+ window system; if this index is valid, it is recommended, but
+ not necessarily required, that the chooser select that entry. */
+ public int chooseCapabilities(GLCapabilities desired,
+ GLCapabilities[] available,
+ int windowSystemRecommendedChoice);
}
diff --git a/src/net/java/games/jogl/GLDrawableFactory.java b/src/net/java/games/jogl/GLDrawableFactory.java
index 79109771c..113453d54 100644
--- a/src/net/java/games/jogl/GLDrawableFactory.java
+++ b/src/net/java/games/jogl/GLDrawableFactory.java
@@ -39,6 +39,10 @@
package net.java.games.jogl;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import net.java.games.jogl.impl.*;
+
/** <P> Provides a virtual machine- and operating system-independent
mechanism for creating {@link net.java.games.jogl.GLCanvas} and {@link
net.java.games.jogl.GLJPanel} objects. </P>
@@ -74,47 +78,80 @@ public class GLDrawableFactory {
return factory;
}
- /** Creates a {@link GLCanvas} with the specified capabilities using
- the default capabilities selection algorithm. */
+ /** Creates a {@link GLCanvas} on the default graphics device with
+ the specified capabilities using the default capabilities
+ selection algorithm. */
public GLCanvas createGLCanvas(GLCapabilities capabilities) {
return createGLCanvas(capabilities, null, null);
}
- /** Creates a {@link GLCanvas} with the specified capabilities using
- the default capabilities selection algorithm. The canvas will
- share textures and display lists with the specified {@link
- GLDrawable}; the drawable must either be null or have been
- fabricated from this factory or by classes in this package. A
- null drawable indicates no sharing. */
+ /** Creates a {@link GLCanvas} on the default graphics device with
+ the specified capabilities using the default capabilities
+ selection algorithm. The canvas will share textures and display
+ lists with the specified {@link GLDrawable}; the drawable must
+ either be null or have been fabricated from this factory or by
+ classes in this package. A null drawable indicates no
+ sharing. */
public GLCanvas createGLCanvas(GLCapabilities capabilities, GLDrawable shareWith) {
return createGLCanvas(capabilities, null, shareWith);
}
- /** Creates a {@link GLCanvas} with the specified capabilities using
- the supplied capabilities selection algorithm. A null chooser is
- equivalent to using the {@link DefaultGLCapabilitiesChooser}. */
+ /** Creates a {@link GLCanvas} on the default graphics device with
+ the specified capabilities using the supplied capabilities
+ selection algorithm. A null chooser is equivalent to using the
+ {@link DefaultGLCapabilitiesChooser}. */
public GLCanvas createGLCanvas(GLCapabilities capabilities, GLCapabilitiesChooser chooser) {
return createGLCanvas(capabilities, chooser, null);
}
- /** Creates a {@link GLCanvas} with the specified capabilities using
- the supplied capabilities selection algorithm. A null chooser is
- equivalent to using the {@link DefaultGLCapabilitiesChooser}.
- The canvas will share textures and display lists with the
- specified {@link GLDrawable}; the drawable must either be null
- or have been fabricated from this factory or by classes in this
- package. A null drawable indicates no sharing. */
+ /** Creates a {@link GLCanvas} on the default graphics device with
+ the specified capabilities using the supplied capabilities
+ selection algorithm. A null chooser is equivalent to using the
+ {@link DefaultGLCapabilitiesChooser}. The canvas will share
+ textures and display lists with the specified {@link
+ GLDrawable}; the drawable must either be null or have been
+ fabricated from this factory or by classes in this package. A
+ null drawable indicates no sharing. */
public GLCanvas createGLCanvas(GLCapabilities capabilities,
GLCapabilitiesChooser chooser,
GLDrawable shareWith) {
- // FIXME: do we need to select a GraphicsConfiguration here as in
- // GL4Java? If so, this class will have to be made abstract and
- // we'll have to provide hooks into this package to get at the
- // GLCanvas and GLJPanel constructors.
+ return createGLCanvas(capabilities, chooser, shareWith, null);
+ }
+
+ /** Creates a {@link GLCanvas} on the specified graphics device with
+ the specified capabilities using the supplied capabilities
+ selection algorithm. A null chooser is equivalent to using the
+ {@link DefaultGLCapabilitiesChooser}. The canvas will share
+ textures and display lists with the specified {@link
+ GLDrawable}; the drawable must either be null or have been
+ fabricated from this factory or by classes in this package. A
+ null drawable indicates no sharing. A null GraphicsDevice is
+ equivalent to using that returned from
+ <code>GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice()</code>. */
+ public GLCanvas createGLCanvas(GLCapabilities capabilities,
+ GLCapabilitiesChooser chooser,
+ GLDrawable shareWith,
+ GraphicsDevice device) {
if (chooser == null) {
chooser = new DefaultGLCapabilitiesChooser();
}
- return new GLCanvas(capabilities, chooser, shareWith);
+ if (device == null) {
+ device = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
+ }
+ // The platform-specific GLContextFactory will only provide a
+ // non-null GraphicsConfiguration on platforms where this is
+ // necessary (currently only X11, as Windows allows the pixel
+ // format of the window to be set later and Mac OS X seems to
+ // handle this very differently than all other platforms). On
+ // other platforms this method returns null; it is the case (at
+ // least in the Sun AWT implementation) that this will result in
+ // equivalent behavior to calling the no-arg super() constructor
+ // for Canvas.
+ return new GLCanvas(GLContextFactory.getFactory().
+ chooseGraphicsConfiguration(capabilities, chooser, device),
+ capabilities,
+ chooser,
+ shareWith);
}
/** Creates a {@link GLJPanel} with the specified capabilities using
diff --git a/src/net/java/games/jogl/Version.java b/src/net/java/games/jogl/Version.java
index fb8c3f3c1..3f2acd88b 100644
--- a/src/net/java/games/jogl/Version.java
+++ b/src/net/java/games/jogl/Version.java
@@ -89,7 +89,7 @@ public final class Version {
/**
* Version string of this build.
*/
- private static final String version = "1.0.0-b01";
+ private static final String version = "1.1.0-b01";
/**
* Returns the verison string and build number of
diff --git a/src/net/java/games/jogl/impl/GLContextFactory.java b/src/net/java/games/jogl/impl/GLContextFactory.java
index b686d3543..4aa23c397 100644
--- a/src/net/java/games/jogl/impl/GLContextFactory.java
+++ b/src/net/java/games/jogl/impl/GLContextFactory.java
@@ -40,6 +40,8 @@
package net.java.games.jogl.impl;
import java.awt.Component;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
import net.java.games.jogl.*;
public abstract class GLContextFactory {
@@ -84,6 +86,18 @@ public abstract class GLContextFactory {
return factory;
}
+ /** Selects a GraphicsConfiguration on the specified GraphicsDevice
+ that matches the desired GLCapabilities according to the
+ specified GLCapabilitiesChooser's selection algorithm and any
+ hints provided by the underlying window system. This routine is
+ currently only implemented on X11, where it is necessary to
+ choose the desired visual before creating the underlying AWT
+ Canvas; on other platforms it returns null, yielding the default
+ behavior. */
+ public abstract GraphicsConfiguration chooseGraphicsConfiguration(GLCapabilities capabilities,
+ GLCapabilitiesChooser chooser,
+ GraphicsDevice device);
+
public abstract GLContext createGLContext(Component component,
GLCapabilities capabilities,
GLCapabilitiesChooser chooser,
diff --git a/src/net/java/games/jogl/impl/macosx/MacOSXGLContextFactory.java b/src/net/java/games/jogl/impl/macosx/MacOSXGLContextFactory.java
index f3e002c22..3e08c9b67 100644
--- a/src/net/java/games/jogl/impl/macosx/MacOSXGLContextFactory.java
+++ b/src/net/java/games/jogl/impl/macosx/MacOSXGLContextFactory.java
@@ -40,10 +40,18 @@
package net.java.games.jogl.impl.macosx;
import java.awt.Component;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
import net.java.games.jogl.*;
import net.java.games.jogl.impl.*;
public class MacOSXGLContextFactory extends GLContextFactory {
+ public GraphicsConfiguration chooseGraphicsConfiguration(GLCapabilities capabilities,
+ GLCapabilitiesChooser chooser,
+ GraphicsDevice device) {
+ return null;
+ }
+
public GLContext createGLContext(Component component,
GLCapabilities capabilities,
GLCapabilitiesChooser chooser,
diff --git a/src/net/java/games/jogl/impl/windows/WindowsGLContext.java b/src/net/java/games/jogl/impl/windows/WindowsGLContext.java
index 87073e22d..f40d7d3d5 100644
--- a/src/net/java/games/jogl/impl/windows/WindowsGLContext.java
+++ b/src/net/java/games/jogl/impl/windows/WindowsGLContext.java
@@ -280,7 +280,10 @@ public abstract class WindowsGLContext extends GLContext {
availableCaps[i] = pfd2GLCapabilities(pfd);
}
// Supply information to chooser
- pixelFormat = chooser.chooseCapabilities(capabilities, availableCaps);
+ // FIXME: should provide a hint to the pixel format selection
+ // algorithm, and should be using wglChoosePixelFormatARB in
+ // order to do so
+ pixelFormat = chooser.chooseCapabilities(capabilities, availableCaps, -1);
if ((pixelFormat < 0) || (pixelFormat >= numFormats)) {
throw new GLException("Invalid result " + pixelFormat +
" from GLCapabilitiesChooser (should be between 0 and " +
diff --git a/src/net/java/games/jogl/impl/windows/WindowsGLContextFactory.java b/src/net/java/games/jogl/impl/windows/WindowsGLContextFactory.java
index cfad54025..0c8d54431 100644
--- a/src/net/java/games/jogl/impl/windows/WindowsGLContextFactory.java
+++ b/src/net/java/games/jogl/impl/windows/WindowsGLContextFactory.java
@@ -40,10 +40,18 @@
package net.java.games.jogl.impl.windows;
import java.awt.Component;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
import net.java.games.jogl.*;
import net.java.games.jogl.impl.*;
public class WindowsGLContextFactory extends GLContextFactory {
+ public GraphicsConfiguration chooseGraphicsConfiguration(GLCapabilities capabilities,
+ GLCapabilitiesChooser chooser,
+ GraphicsDevice device) {
+ return null;
+ }
+
public GLContext createGLContext(Component component,
GLCapabilities capabilities,
GLCapabilitiesChooser chooser,
diff --git a/src/net/java/games/jogl/impl/x11/X11GLContext.java b/src/net/java/games/jogl/impl/x11/X11GLContext.java
index 3f59b5314..f1de46d5a 100644
--- a/src/net/java/games/jogl/impl/x11/X11GLContext.java
+++ b/src/net/java/games/jogl/impl/x11/X11GLContext.java
@@ -49,6 +49,7 @@ public abstract class X11GLContext extends GLContext {
private static JAWT jawt;
protected long display;
protected long drawable;
+ protected long visualID;
protected long context;
private boolean glXQueryExtensionsStringInitialized;
private boolean glXQueryExtensionsStringAvailable;
@@ -262,47 +263,76 @@ public abstract class X11GLContext extends GLContext {
}
protected XVisualInfo chooseVisual() {
- int screen = 0; // FIXME: provide way to specify this?
- XVisualInfo vis = null;
- if (chooser == null) {
- // Note: this code path isn't taken any more now that the
- // DefaultGLCapabilitiesChooser is present. However, it is being
- // left in place for debugging purposes.
- int[] attribs = glCapabilities2AttribList(capabilities);
- vis = GLX.glXChooseVisual(display, screen, attribs);
- if (vis == null) {
- throw new GLException("Unable to find matching visual");
- }
- if (DEBUG) {
- System.err.println("Chosen visual from glXChooseVisual:");
- System.err.println(xvi2GLCapabilities(vis));
- }
- } else {
+ if (!isOffscreen()) {
+ // The visual has already been chosen by the time we get here;
+ // it's specified by the GraphicsConfiguration of the
+ // GLCanvas. Fortunately, the JAWT supplies the visual ID for
+ // the component in a portable fashion, so all we have to do is
+ // use XGetVisualInfo with a VisualIDMask to get the
+ // corresponding XVisualInfo to pass into glXChooseVisual.
int[] count = new int[1];
XVisualInfo template = new XVisualInfo();
- template.screen(screen);
- XVisualInfo[] infos = GLX.XGetVisualInfo(display, GLX.VisualScreenMask, template, count);
- if (infos == null) {
- throw new GLException("Error while enumerating available XVisualInfos");
- }
- GLCapabilities[] caps = new GLCapabilities[infos.length];
- for (int i = 0; i < infos.length; i++) {
- caps[i] = xvi2GLCapabilities(infos[i]);
- }
- int chosen = chooser.chooseCapabilities(capabilities, caps);
- if (chosen < 0 || chosen >= caps.length) {
- throw new GLException("GLCapabilitiesChooser specified invalid index (expected 0.." + (caps.length - 1) + ")");
- }
- if (DEBUG) {
- System.err.println("Chosen visual (" + chosen + "):");
- System.err.println(caps[chosen]);
+ // FIXME: probably not 64-bit clean
+ template.visualid((int) visualID);
+ XVisualInfo[] infos = GLX.XGetVisualInfo(display, GLX.VisualIDMask, template, count);
+ if (infos == null || infos.length == 0) {
+ throw new GLException("Error while getting XVisualInfo for visual ID " + visualID);
}
- vis = infos[chosen];
- if (vis == null) {
- throw new GLException("GLCapabilitiesChooser chose an invalid visual");
+ // FIXME: the storage for the infos array is leaked (should
+ // clean it up somehow when we're done with the visual we're
+ // returning)
+ return infos[0];
+ } else {
+ // It isn't clear to me whether we need this much code to handle
+ // the offscreen case, where we're creating a pixmap into which
+ // to render...this is what we (incorrectly) used to do for the
+ // onscreen case
+
+ int screen = 0; // FIXME: provide way to specify this?
+ XVisualInfo vis = null;
+ if (chooser == null) {
+ // Note: this code path isn't taken any more now that the
+ // DefaultGLCapabilitiesChooser is present. However, it is being
+ // left in place for debugging purposes.
+ int[] attribs = X11GLContextFactory.glCapabilities2AttribList(capabilities);
+ vis = GLX.glXChooseVisual(display, screen, attribs);
+ if (vis == null) {
+ throw new GLException("Unable to find matching visual");
+ }
+ if (DEBUG) {
+ System.err.println("Chosen visual from glXChooseVisual:");
+ System.err.println(X11GLContextFactory.xvi2GLCapabilities(display, vis));
+ }
+ } else {
+ int[] count = new int[1];
+ XVisualInfo template = new XVisualInfo();
+ template.screen(screen);
+ XVisualInfo[] infos = GLX.XGetVisualInfo(display, GLX.VisualScreenMask, template, count);
+ if (infos == null) {
+ throw new GLException("Error while enumerating available XVisualInfos");
+ }
+ GLCapabilities[] caps = new GLCapabilities[infos.length];
+ for (int i = 0; i < infos.length; i++) {
+ caps[i] = X11GLContextFactory.xvi2GLCapabilities(display, infos[i]);
+ }
+ int chosen = chooser.chooseCapabilities(capabilities, caps, -1);
+ if (chosen < 0 || chosen >= caps.length) {
+ throw new GLException("GLCapabilitiesChooser specified invalid index (expected 0.." + (caps.length - 1) + ")");
+ }
+ if (DEBUG) {
+ System.err.println("Chosen visual (" + chosen + "):");
+ System.err.println(caps[chosen]);
+ }
+ vis = infos[chosen];
+ if (vis == null) {
+ throw new GLException("GLCapabilitiesChooser chose an invalid visual");
+ }
+ // FIXME: the storage for the infos array is leaked (should
+ // clean it up somehow when we're done with the visual we're
+ // returning)
}
+ return vis;
}
- return vis;
}
protected long createContext(XVisualInfo vis, boolean onscreen) {
@@ -333,96 +363,4 @@ public abstract class X11GLContext extends GLContext {
protected long getContext() {
return context;
}
-
- protected int[] glCapabilities2AttribList(GLCapabilities caps) {
- int colorDepth = (caps.getRedBits() +
- caps.getGreenBits() +
- caps.getBlueBits());
- if (colorDepth < 15) {
- throw new GLException("Bit depths < 15 (i.e., non-true-color) not supported");
- }
- int[] res = new int[22];
- int idx = 0;
- res[idx++] = GLX.GLX_RGBA;
- if (caps.getDoubleBuffered()) {
- res[idx++] = GLX.GLX_DOUBLEBUFFER;
- }
- if (caps.getStereo()) {
- res[idx++] = GLX.GLX_STEREO;
- }
- res[idx++] = GLX.GLX_RED_SIZE;
- res[idx++] = caps.getRedBits();
- res[idx++] = GLX.GLX_GREEN_SIZE;
- res[idx++] = caps.getGreenBits();
- res[idx++] = GLX.GLX_BLUE_SIZE;
- res[idx++] = caps.getBlueBits();
- res[idx++] = GLX.GLX_ALPHA_SIZE;
- res[idx++] = caps.getAlphaBits();
- res[idx++] = GLX.GLX_DEPTH_SIZE;
- res[idx++] = caps.getDepthBits();
- res[idx++] = GLX.GLX_STENCIL_SIZE;
- res[idx++] = caps.getStencilBits();
- res[idx++] = GLX.GLX_ACCUM_RED_SIZE;
- res[idx++] = caps.getAccumRedBits();
- res[idx++] = GLX.GLX_ACCUM_GREEN_SIZE;
- res[idx++] = caps.getAccumGreenBits();
- res[idx++] = GLX.GLX_ACCUM_BLUE_SIZE;
- res[idx++] = caps.getAccumBlueBits();
- res[idx++] = 0;
- return res;
- }
-
- protected GLCapabilities xvi2GLCapabilities(XVisualInfo info) {
- int[] tmp = new int[1];
- int val = glXGetConfig(info, GLX.GLX_USE_GL, tmp);
- if (val == 0) {
- // Visual does not support OpenGL
- return null;
- }
- val = glXGetConfig(info, GLX.GLX_RGBA, tmp);
- if (val == 0) {
- // Visual does not support RGBA
- return null;
- }
- GLCapabilities res = new GLCapabilities();
- res.setDoubleBuffered(glXGetConfig(info, GLX.GLX_DOUBLEBUFFER, tmp) != 0);
- res.setStereo (glXGetConfig(info, GLX.GLX_STEREO, tmp) != 0);
- // Note: use of hardware acceleration is determined by
- // glXCreateContext, not by the XVisualInfo. Optimistically claim
- // that all GLCapabilities have the capability to be hardware
- // accelerated.
- res.setHardwareAccelerated(true);
- res.setDepthBits (glXGetConfig(info, GLX.GLX_DEPTH_SIZE, tmp));
- res.setStencilBits (glXGetConfig(info, GLX.GLX_STENCIL_SIZE, tmp));
- res.setRedBits (glXGetConfig(info, GLX.GLX_RED_SIZE, tmp));
- res.setGreenBits (glXGetConfig(info, GLX.GLX_GREEN_SIZE, tmp));
- res.setBlueBits (glXGetConfig(info, GLX.GLX_BLUE_SIZE, tmp));
- res.setAlphaBits (glXGetConfig(info, GLX.GLX_ALPHA_SIZE, tmp));
- res.setAccumRedBits (glXGetConfig(info, GLX.GLX_ACCUM_RED_SIZE, tmp));
- res.setAccumGreenBits(glXGetConfig(info, GLX.GLX_ACCUM_GREEN_SIZE, tmp));
- res.setAccumBlueBits (glXGetConfig(info, GLX.GLX_ACCUM_BLUE_SIZE, tmp));
- res.setAccumAlphaBits(glXGetConfig(info, GLX.GLX_ACCUM_ALPHA_SIZE, tmp));
- return res;
- }
-
- protected String glXGetConfigErrorCode(int err) {
- switch (err) {
- case GLX.GLX_NO_EXTENSION: return "GLX_NO_EXTENSION";
- case GLX.GLX_BAD_SCREEN: return "GLX_BAD_SCREEN";
- case GLX.GLX_BAD_ATTRIBUTE: return "GLX_BAD_ATTRIBUTE";
- case GLX.GLX_BAD_VISUAL: return "GLX_BAD_VISUAL";
- default: return "Unknown error code " + err;
- }
- }
-
- protected int glXGetConfig(XVisualInfo info, int attrib, int[] tmp) {
- if (display == 0) {
- throw new GLException("No display connection");
- }
- int res = GLX.glXGetConfig(display, info, attrib, tmp);
- if (res != 0) {
- throw new GLException("glXGetConfig failed: error code " + glXGetConfigErrorCode(res));
- }
- return tmp[0];
- }
}
diff --git a/src/net/java/games/jogl/impl/x11/X11GLContextFactory.java b/src/net/java/games/jogl/impl/x11/X11GLContextFactory.java
index 5a8298753..817a41017 100644
--- a/src/net/java/games/jogl/impl/x11/X11GLContextFactory.java
+++ b/src/net/java/games/jogl/impl/x11/X11GLContextFactory.java
@@ -40,10 +40,75 @@
package net.java.games.jogl.impl.x11;
import java.awt.Component;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
import net.java.games.jogl.*;
import net.java.games.jogl.impl.*;
public class X11GLContextFactory extends GLContextFactory {
+ static {
+ NativeLibLoader.load();
+ }
+
+ public GraphicsConfiguration chooseGraphicsConfiguration(GLCapabilities capabilities,
+ GLCapabilitiesChooser chooser,
+ GraphicsDevice device) {
+ int 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);
+ long display = getDisplayConnection();
+ XVisualInfo recommendedVis = GLX.glXChooseVisual(display, screen, attribs);
+ int recommendedIndex = -1;
+ int[] count = new int[1];
+ XVisualInfo template = new XVisualInfo();
+ template.screen(screen);
+ XVisualInfo[] infos = GLX.XGetVisualInfo(display, GLX.VisualScreenMask, template, count);
+ if (infos == null) {
+ throw new GLException("Error while enumerating available XVisualInfos");
+ }
+ GLCapabilities[] 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;
+ }
+ }
+ 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 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 GLContext createGLContext(Component component,
GLCapabilities capabilities,
GLCapabilitiesChooser chooser,
@@ -54,4 +119,108 @@ public class X11GLContextFactory extends GLContextFactory {
return new X11OffscreenGLContext(capabilities, chooser, shareWith);
}
}
+
+ public static GLCapabilities xvi2GLCapabilities(long display, XVisualInfo info) {
+ int[] tmp = new int[1];
+ int val = glXGetConfig(display, info, GLX.GLX_USE_GL, tmp);
+ if (val == 0) {
+ // Visual does not support OpenGL
+ return null;
+ }
+ val = glXGetConfig(display, info, GLX.GLX_RGBA, tmp);
+ if (val == 0) {
+ // Visual does not support RGBA
+ return null;
+ }
+ GLCapabilities res = new GLCapabilities();
+ res.setDoubleBuffered(glXGetConfig(display, info, GLX.GLX_DOUBLEBUFFER, tmp) != 0);
+ res.setStereo (glXGetConfig(display, info, GLX.GLX_STEREO, tmp) != 0);
+ // Note: use of hardware acceleration is determined by
+ // glXCreateContext, not by the XVisualInfo. Optimistically claim
+ // that all GLCapabilities have the capability to be hardware
+ // accelerated.
+ res.setHardwareAccelerated(true);
+ res.setDepthBits (glXGetConfig(display, info, GLX.GLX_DEPTH_SIZE, tmp));
+ res.setStencilBits (glXGetConfig(display, info, GLX.GLX_STENCIL_SIZE, tmp));
+ res.setRedBits (glXGetConfig(display, info, GLX.GLX_RED_SIZE, tmp));
+ res.setGreenBits (glXGetConfig(display, info, GLX.GLX_GREEN_SIZE, tmp));
+ res.setBlueBits (glXGetConfig(display, info, GLX.GLX_BLUE_SIZE, tmp));
+ res.setAlphaBits (glXGetConfig(display, info, GLX.GLX_ALPHA_SIZE, tmp));
+ res.setAccumRedBits (glXGetConfig(display, info, GLX.GLX_ACCUM_RED_SIZE, tmp));
+ res.setAccumGreenBits(glXGetConfig(display, info, GLX.GLX_ACCUM_GREEN_SIZE, tmp));
+ res.setAccumBlueBits (glXGetConfig(display, info, GLX.GLX_ACCUM_BLUE_SIZE, tmp));
+ res.setAccumAlphaBits(glXGetConfig(display, info, GLX.GLX_ACCUM_ALPHA_SIZE, tmp));
+ return res;
+ }
+
+ public static int[] glCapabilities2AttribList(GLCapabilities caps) {
+ int colorDepth = (caps.getRedBits() +
+ caps.getGreenBits() +
+ caps.getBlueBits());
+ if (colorDepth < 15) {
+ throw new GLException("Bit depths < 15 (i.e., non-true-color) not supported");
+ }
+ int[] res = new int[22];
+ int idx = 0;
+ res[idx++] = GLX.GLX_RGBA;
+ if (caps.getDoubleBuffered()) {
+ res[idx++] = GLX.GLX_DOUBLEBUFFER;
+ }
+ if (caps.getStereo()) {
+ res[idx++] = GLX.GLX_STEREO;
+ }
+ res[idx++] = GLX.GLX_RED_SIZE;
+ res[idx++] = caps.getRedBits();
+ res[idx++] = GLX.GLX_GREEN_SIZE;
+ res[idx++] = caps.getGreenBits();
+ res[idx++] = GLX.GLX_BLUE_SIZE;
+ res[idx++] = caps.getBlueBits();
+ res[idx++] = GLX.GLX_ALPHA_SIZE;
+ res[idx++] = caps.getAlphaBits();
+ res[idx++] = GLX.GLX_DEPTH_SIZE;
+ res[idx++] = caps.getDepthBits();
+ res[idx++] = GLX.GLX_STENCIL_SIZE;
+ res[idx++] = caps.getStencilBits();
+ res[idx++] = GLX.GLX_ACCUM_RED_SIZE;
+ res[idx++] = caps.getAccumRedBits();
+ res[idx++] = GLX.GLX_ACCUM_GREEN_SIZE;
+ res[idx++] = caps.getAccumGreenBits();
+ res[idx++] = GLX.GLX_ACCUM_BLUE_SIZE;
+ res[idx++] = caps.getAccumBlueBits();
+ res[idx++] = 0;
+ return res;
+ }
+
+ // Display connection for use by visual selection algorithm and by all offscreen surfaces
+ private static long staticDisplay;
+ public static long getDisplayConnection() {
+ if (staticDisplay == 0) {
+ staticDisplay = GLX.XOpenDisplay(null);
+ if (staticDisplay == 0) {
+ throw new GLException("Unable to open default display, needed for visual selection and offscreen surface handling");
+ }
+ }
+ return staticDisplay;
+ }
+
+ private static String glXGetConfigErrorCode(int err) {
+ switch (err) {
+ case GLX.GLX_NO_EXTENSION: return "GLX_NO_EXTENSION";
+ case GLX.GLX_BAD_SCREEN: return "GLX_BAD_SCREEN";
+ case GLX.GLX_BAD_ATTRIBUTE: return "GLX_BAD_ATTRIBUTE";
+ case GLX.GLX_BAD_VISUAL: return "GLX_BAD_VISUAL";
+ default: return "Unknown error code " + err;
+ }
+ }
+
+ public static int glXGetConfig(long display, XVisualInfo info, int attrib, int[] tmp) {
+ if (display == 0) {
+ throw new GLException("No display connection");
+ }
+ int res = GLX.glXGetConfig(display, info, attrib, tmp);
+ if (res != 0) {
+ throw new GLException("glXGetConfig failed: error code " + glXGetConfigErrorCode(res));
+ }
+ return tmp[0];
+ }
}
diff --git a/src/net/java/games/jogl/impl/x11/X11OffscreenGLContext.java b/src/net/java/games/jogl/impl/x11/X11OffscreenGLContext.java
index 7890982f3..8c88b0225 100644
--- a/src/net/java/games/jogl/impl/x11/X11OffscreenGLContext.java
+++ b/src/net/java/games/jogl/impl/x11/X11OffscreenGLContext.java
@@ -50,9 +50,6 @@ public class X11OffscreenGLContext extends X11GLContext {
private int width;
private int height;
- // Display connection for use by all offscreen surfaces
- private long staticDisplay;
-
public X11OffscreenGLContext(GLCapabilities capabilities,
GLCapabilitiesChooser chooser,
GLContext shareWith) {
@@ -121,7 +118,7 @@ public class X11OffscreenGLContext extends X11GLContext {
}
protected synchronized boolean makeCurrent(Runnable initAction) throws GLException {
- ensureDisplayOpened();
+ display = X11GLContextFactory.getDisplayConnection();
if (pendingOffscreenResize) {
if (pendingOffscreenWidth != width || pendingOffscreenHeight != height) {
if (context != 0) {
@@ -166,17 +163,7 @@ public class X11OffscreenGLContext extends X11GLContext {
if (context == 0) {
throw new GLException("Unable to create OpenGL context");
}
- isDoubleBuffered = (glXGetConfig(vis, GLX.GLX_DOUBLEBUFFER, new int[1]) != 0);
- }
-
- private void ensureDisplayOpened() {
- if (staticDisplay == 0) {
- staticDisplay = GLX.XOpenDisplay(null);
- if (staticDisplay == 0) {
- throw new GLException("Unable to open default display, needed for offscreen surface handling");
- }
- }
- display = staticDisplay;
+ isDoubleBuffered = (X11GLContextFactory.glXGetConfig(display, vis, GLX.GLX_DOUBLEBUFFER, new int[1]) != 0);
}
private void destroy() {
diff --git a/src/net/java/games/jogl/impl/x11/X11OnscreenGLContext.java b/src/net/java/games/jogl/impl/x11/X11OnscreenGLContext.java
index 0a38e6fc7..911fc3740 100644
--- a/src/net/java/games/jogl/impl/x11/X11OnscreenGLContext.java
+++ b/src/net/java/games/jogl/impl/x11/X11OnscreenGLContext.java
@@ -175,6 +175,7 @@ public class X11OnscreenGLContext extends X11GLContext {
x11dsi = (JAWT_X11DrawingSurfaceInfo) dsi.platformInfo();
display = x11dsi.display();
drawable = x11dsi.drawable();
+ visualID = x11dsi.visualID();
if (display == 0 || drawable == 0) {
// Widget not yet realized
ds.FreeDrawingSurfaceInfo(dsi);
@@ -183,6 +184,9 @@ public class X11OnscreenGLContext extends X11GLContext {
ds = null;
dsi = null;
x11dsi = null;
+ display = 0;
+ drawable = 0;
+ visualID = 0;
return false;
}
return true;
@@ -200,6 +204,7 @@ public class X11OnscreenGLContext extends X11GLContext {
x11dsi = null;
display = 0;
drawable = 0;
+ visualID = 0;
}
protected void create() {