aboutsummaryrefslogtreecommitdiffstats
path: root/src/classes/com/sun/opengl/impl
diff options
context:
space:
mode:
authorKenneth Russel <[email protected]>2006-11-19 20:51:57 +0000
committerKenneth Russel <[email protected]>2006-11-19 20:51:57 +0000
commita303cd13ff62f94a0459978735620e37d72bbb77 (patch)
tree32b580af4e878d479890c12b8eae9c98e10a4874 /src/classes/com/sun/opengl/impl
parentbf82eceb6f78d5ee6e4c0f9f02590d2a58e647d3 (diff)
Fixed Issue 213: Expose GLCaps from GLDrawable
Added getChosenGLCapabilities() to the GLDrawable interface. Implemented on Windows, Unix and Mac OS X platforms with various techniques. Attempts to provide correct answers in all cases, even when the GLCapabilitiesChooser mechanism is not supported. Required addition of new platform-specific Java code in most cases to either re-convert existing PIXELFORMATDESCRIPTORS / XVisualInfos, or to query the pixel format or visual chosen for drawables like pbuffers for which the chooser mechanism is not (yet) implemented. Tested on Windows, Solaris/x86, and Mac OS X with on-screen, off-screen and pbuffer drawables. (Full support for the Java2D/JOGL bridge is not yet in place; the answer returned from the GLJPanel in this case is currently the default GLCapabilities, and it is likely that "external" GLDrawables will return null.) git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/svn-server-sync/jogl/trunk@989 232f8b59-042b-4e1e-8c03-345bb8c30851
Diffstat (limited to 'src/classes/com/sun/opengl/impl')
-rw-r--r--src/classes/com/sun/opengl/impl/GLDrawableImpl.java14
-rw-r--r--src/classes/com/sun/opengl/impl/GLPbufferImpl.java7
-rw-r--r--src/classes/com/sun/opengl/impl/macosx/MacOSXGLContext.java148
-rw-r--r--src/classes/com/sun/opengl/impl/macosx/MacOSXOnscreenGLDrawable.java3
-rw-r--r--src/classes/com/sun/opengl/impl/windows/WindowsGLDrawable.java28
-rw-r--r--src/classes/com/sun/opengl/impl/windows/WindowsGLDrawableFactory.java3
-rw-r--r--src/classes/com/sun/opengl/impl/windows/WindowsOffscreenGLDrawable.java1
-rw-r--r--src/classes/com/sun/opengl/impl/windows/WindowsOnscreenGLDrawable.java1
-rw-r--r--src/classes/com/sun/opengl/impl/windows/WindowsPbufferGLDrawable.java43
-rw-r--r--src/classes/com/sun/opengl/impl/x11/X11GLDrawableFactory.java131
-rw-r--r--src/classes/com/sun/opengl/impl/x11/X11OffscreenGLDrawable.java2
-rw-r--r--src/classes/com/sun/opengl/impl/x11/X11PbufferGLDrawable.java38
12 files changed, 382 insertions, 37 deletions
diff --git a/src/classes/com/sun/opengl/impl/GLDrawableImpl.java b/src/classes/com/sun/opengl/impl/GLDrawableImpl.java
index f93ed9663..df1aab796 100644
--- a/src/classes/com/sun/opengl/impl/GLDrawableImpl.java
+++ b/src/classes/com/sun/opengl/impl/GLDrawableImpl.java
@@ -42,6 +42,8 @@ package com.sun.opengl.impl;
import javax.media.opengl.*;
public abstract class GLDrawableImpl implements GLDrawable {
+ private GLCapabilities chosenCapabilities;
+
/** For offscreen GLDrawables (pbuffers and "pixmap" drawables),
indicates that native resources should be reclaimed. */
public abstract void destroy() throws GLException;
@@ -49,4 +51,16 @@ public abstract class GLDrawableImpl implements GLDrawable {
public static String toHexString(long hex) {
return GLContextImpl.toHexString(hex);
}
+
+ public GLCapabilities getChosenGLCapabilities() {
+ if (chosenCapabilities == null)
+ return null;
+
+ // Must return a new copy to avoid mutation by end user
+ return (GLCapabilities) chosenCapabilities.clone();
+ }
+
+ public void setChosenGLCapabilities(GLCapabilities caps) {
+ chosenCapabilities = caps;
+ }
}
diff --git a/src/classes/com/sun/opengl/impl/GLPbufferImpl.java b/src/classes/com/sun/opengl/impl/GLPbufferImpl.java
index feb9d3512..cf4ae31af 100644
--- a/src/classes/com/sun/opengl/impl/GLPbufferImpl.java
+++ b/src/classes/com/sun/opengl/impl/GLPbufferImpl.java
@@ -142,6 +142,13 @@ public class GLPbufferImpl implements GLPbuffer {
context.releasePbufferFromTexture();
}
+ public GLCapabilities getChosenGLCapabilities() {
+ if (pbufferDrawable == null)
+ return null;
+
+ return pbufferDrawable.getChosenGLCapabilities();
+ }
+
//----------------------------------------------------------------------
// No-ops for ComponentEvents
//
diff --git a/src/classes/com/sun/opengl/impl/macosx/MacOSXGLContext.java b/src/classes/com/sun/opengl/impl/macosx/MacOSXGLContext.java
index e41ad856d..16855efb8 100644
--- a/src/classes/com/sun/opengl/impl/macosx/MacOSXGLContext.java
+++ b/src/classes/com/sun/opengl/impl/macosx/MacOSXGLContext.java
@@ -102,34 +102,130 @@ public abstract class MacOSXGLContext extends GLContextImpl
}
int[] viewNotReady = new int[1];
GLCapabilities capabilities = drawable.getCapabilities();
- nsContext = CGL.createContext(share,
- drawable.getView(),
- capabilities.getDoubleBuffered() ? 1 : 0,
- capabilities.getStereo() ? 1 : 0,
- capabilities.getRedBits(),
- capabilities.getGreenBits(),
- capabilities.getBlueBits(),
- capabilities.getAlphaBits(),
- capabilities.getDepthBits(),
- capabilities.getStencilBits(),
- capabilities.getAccumRedBits(),
- capabilities.getAccumGreenBits(),
- capabilities.getAccumBlueBits(),
- capabilities.getAccumAlphaBits(),
- capabilities.getSampleBuffers() ? 1 : 0,
- capabilities.getNumSamples(),
- (pbuffer ? 1 : 0),
- (floatingPoint ? 1 : 0),
- viewNotReady, 0);
- if (nsContext == 0) {
- if (viewNotReady[0] == 1) {
- if (DEBUG) {
- System.err.println("!!! View not ready for " + getClass().getName());
+ int[] iattribs = new int[128];
+ int[] ivalues = new int[128];
+ int idx = 0;
+ if (pbuffer) {
+ iattribs[idx] = CGL.NSOpenGLPFAPixelBuffer; ivalues[idx] = 1; idx++;
+ }
+ if (floatingPoint) {
+ iattribs[idx] = CGL.kCGLPFAColorFloat; ivalues[idx] = 1; idx++;
+ }
+ iattribs[idx] = CGL.NSOpenGLPFADoubleBuffer; ivalues[idx] = (capabilities.getDoubleBuffered() ? 1 : 0); idx++;
+ iattribs[idx] = CGL.NSOpenGLPFAStereo; ivalues[idx] = (capabilities.getStereo() ? 1 : 0); idx++;
+ iattribs[idx] = CGL.NSOpenGLPFAColorSize; ivalues[idx] = (capabilities.getRedBits() +
+ capabilities.getGreenBits() +
+ capabilities.getBlueBits()); idx++;
+ iattribs[idx] = CGL.NSOpenGLPFAAlphaSize; ivalues[idx] = capabilities.getAlphaBits(); idx++;
+ iattribs[idx] = CGL.NSOpenGLPFADepthSize; ivalues[idx] = capabilities.getDepthBits(); idx++;
+ iattribs[idx] = CGL.NSOpenGLPFAAccumSize; ivalues[idx] = (capabilities.getAccumRedBits() +
+ capabilities.getAccumGreenBits() +
+ capabilities.getAccumBlueBits() +
+ capabilities.getAccumAlphaBits()); idx++;
+ iattribs[idx] = CGL.NSOpenGLPFAStencilSize; ivalues[idx] = capabilities.getStencilBits(); idx++;
+ if (capabilities.getSampleBuffers()) {
+ iattribs[idx] = CGL.NSOpenGLPFASampleBuffers; ivalues[idx] = 1; idx++;
+ iattribs[idx] = CGL.NSOpenGLPFASamples; ivalues[idx] = capabilities.getNumSamples(); idx++;
+ }
+
+ long pixelFormat = CGL.createPixelFormat(iattribs, 0, idx, ivalues, 0);
+ if (pixelFormat == 0) {
+ throw new GLException("Unable to allocate pixel format with requested GLCapabilities");
+ }
+ try {
+ // Try to allocate a context with this
+ nsContext = CGL.createContext(share,
+ drawable.getView(),
+ pixelFormat,
+ viewNotReady, 0);
+ if (nsContext == 0) {
+ if (viewNotReady[0] == 1) {
+ if (DEBUG) {
+ System.err.println("!!! View not ready for " + getClass().getName());
+ }
+ // View not ready at the window system level -- this is OK
+ return false;
+ }
+ throw new GLException("Error creating NSOpenGLContext with requested pixel format");
+ }
+
+ // On this platform the pixel format is associated with the
+ // context and not the drawable. However it's a reasonable
+ // approximation to just store the chosen pixel format up in the
+ // drawable since the public API doesn't provide for a different
+ // GLCapabilities per context.
+ if (drawable.getChosenGLCapabilities() == null) {
+ // Figure out what attributes we really got
+ GLCapabilities caps = new GLCapabilities();
+ CGL.queryPixelFormat(pixelFormat, iattribs, 0, idx, ivalues, 0);
+ for (int i = 0; i < idx; i++) {
+ int attr = iattribs[i];
+ switch (attr) {
+ case CGL.kCGLPFAColorFloat:
+ caps.setPbufferFloatingPointBuffers(ivalues[i] != 0);
+ break;
+
+ case CGL.NSOpenGLPFADoubleBuffer:
+ caps.setDoubleBuffered(ivalues[i] != 0);
+ break;
+
+ case CGL.NSOpenGLPFAStereo:
+ caps.setStereo(ivalues[i] != 0);
+ break;
+
+ case CGL.NSOpenGLPFAColorSize:
+ {
+ int bitSize = ivalues[i];
+ if (bitSize == 32)
+ bitSize = 24;
+ bitSize /= 3;
+ caps.setRedBits(bitSize);
+ caps.setGreenBits(bitSize);
+ caps.setBlueBits(bitSize);
+ }
+ break;
+
+ case CGL.NSOpenGLPFAAlphaSize:
+ caps.setAlphaBits(ivalues[i]);
+ break;
+
+ case CGL.NSOpenGLPFADepthSize:
+ caps.setDepthBits(ivalues[i]);
+ break;
+
+ case CGL.NSOpenGLPFAAccumSize:
+ {
+ int bitSize = ivalues[i] / 4;
+ caps.setAccumRedBits(bitSize);
+ caps.setAccumGreenBits(bitSize);
+ caps.setAccumBlueBits(bitSize);
+ caps.setAccumAlphaBits(bitSize);
+ }
+ break;
+
+ case CGL.NSOpenGLPFAStencilSize:
+ caps.setStencilBits(ivalues[i]);
+ break;
+
+ case CGL.NSOpenGLPFASampleBuffers:
+ caps.setSampleBuffers(ivalues[i] != 0);
+ break;
+
+ case CGL.NSOpenGLPFASamples:
+ caps.setNumSamples(ivalues[i]);
+ break;
+
+ default:
+ break;
+ }
}
- // View not ready at the window system level -- this is OK
- return false;
+
+ drawable.setChosenGLCapabilities(caps);
}
- throw new GLException("Error creating nsContext");
+
+
+ } finally {
+ CGL.deletePixelFormat(pixelFormat);
}
GLContextShareSet.contextCreated(this);
return true;
diff --git a/src/classes/com/sun/opengl/impl/macosx/MacOSXOnscreenGLDrawable.java b/src/classes/com/sun/opengl/impl/macosx/MacOSXOnscreenGLDrawable.java
index 2cb501020..7a42ad37c 100644
--- a/src/classes/com/sun/opengl/impl/macosx/MacOSXOnscreenGLDrawable.java
+++ b/src/classes/com/sun/opengl/impl/macosx/MacOSXOnscreenGLDrawable.java
@@ -102,6 +102,9 @@ public class MacOSXOnscreenGLDrawable extends MacOSXGLDrawable {
public void setRealized(boolean realized) {
this.realized = realized;
+ // Might as well clear out the "chosen" pixel format, though it's
+ // associated with the GLContext on this platform and not the drawable
+ setChosenGLCapabilities(null);
}
public void setSize(int width, int height) {
diff --git a/src/classes/com/sun/opengl/impl/windows/WindowsGLDrawable.java b/src/classes/com/sun/opengl/impl/windows/WindowsGLDrawable.java
index e5b8b6424..1efc1c759 100644
--- a/src/classes/com/sun/opengl/impl/windows/WindowsGLDrawable.java
+++ b/src/classes/com/sun/opengl/impl/windows/WindowsGLDrawable.java
@@ -78,13 +78,20 @@ public abstract class WindowsGLDrawable extends GLDrawableImpl {
PIXELFORMATDESCRIPTOR pfd = null;
int pixelFormat = 0;
if (onscreen) {
- if (WGL.GetPixelFormat(hdc) != 0) {
+ if ((pixelFormat = WGL.GetPixelFormat(hdc)) != 0) {
// The Java2D/OpenGL pipeline probably already set a pixel
// format for this canvas.
if (DEBUG) {
System.err.println("NOTE: pixel format already chosen (by Java2D/OpenGL pipeline?) for window: " +
WGL.GetPixelFormat(hdc));
}
+ pfd = newPixelFormatDescriptor();
+ if (WGL.DescribePixelFormat(hdc, pixelFormat, pfd.size(), pfd) == 0) {
+ // FIXME: should this just be a warning? Not really critical...
+ throw new GLException("Unable to describe pixel format " + pixelFormat +
+ " of window set by Java2D/OpenGL pipeline");
+ }
+ setChosenGLCapabilities(pfd2GLCapabilities(pfd));
pixelFormatChosen = true;
return;
}
@@ -280,6 +287,7 @@ public abstract class WindowsGLDrawable extends GLDrawableImpl {
}
throw new GLException("Unable to set pixel format " + pixelFormat + " for device context " + toHexString(hdc) + ": error code " + lastError);
}
+ setChosenGLCapabilities(pfd2GLCapabilities(pfd));
pixelFormatChosen = true;
}
@@ -518,10 +526,13 @@ public abstract class WindowsGLDrawable extends GLDrawableImpl {
int attr = iattribs[i];
switch (attr) {
case WGLExt.WGL_DRAW_TO_WINDOW_ARB:
- if (iresults[i] != GL.GL_TRUE)
+ if (requireRenderToWindow && iresults[i] != GL.GL_TRUE)
return null;
break;
+ case WGLExt.WGL_DRAW_TO_PBUFFER_ARB:
+ break;
+
case WGLExt.WGL_ACCELERATION_ARB:
res.setHardwareAccelerated(iresults[i] == WGLExt.WGL_FULL_ACCELERATION_ARB);
break;
@@ -548,8 +559,17 @@ public abstract class WindowsGLDrawable extends GLDrawableImpl {
break;
case WGLExt.WGL_PIXEL_TYPE_ARB:
- if (iresults[i] != WGLExt.WGL_TYPE_RGBA_ARB)
- return null;
+ // Fail softly with unknown results here
+ if (iresults[i] == WGLExt.WGL_TYPE_RGBA_ARB ||
+ iresults[i] == WGLExt.WGL_TYPE_RGBA_FLOAT_ATI) {
+ res.setPbufferFloatingPointBuffers(true);
+ }
+ break;
+
+ case WGLExt.WGL_FLOAT_COMPONENTS_NV:
+ if (iresults[i] != 0) {
+ res.setPbufferFloatingPointBuffers(true);
+ }
break;
case WGLExt.WGL_RED_BITS_ARB:
diff --git a/src/classes/com/sun/opengl/impl/windows/WindowsGLDrawableFactory.java b/src/classes/com/sun/opengl/impl/windows/WindowsGLDrawableFactory.java
index 1c77d5b04..6e1b4ca99 100644
--- a/src/classes/com/sun/opengl/impl/windows/WindowsGLDrawableFactory.java
+++ b/src/classes/com/sun/opengl/impl/windows/WindowsGLDrawableFactory.java
@@ -118,6 +118,9 @@ public class WindowsGLDrawableFactory extends GLDrawableFactoryImpl {
};
maybeDoSingleThreadedWorkaround(r);
}
+ if (DEBUG) {
+ System.err.println("WindowsGLDrawableFactory.canCreateGLPbuffer() = " + canCreateGLPbuffer);
+ }
return canCreateGLPbuffer;
}
diff --git a/src/classes/com/sun/opengl/impl/windows/WindowsOffscreenGLDrawable.java b/src/classes/com/sun/opengl/impl/windows/WindowsOffscreenGLDrawable.java
index 4fe9c93b2..474c71598 100644
--- a/src/classes/com/sun/opengl/impl/windows/WindowsOffscreenGLDrawable.java
+++ b/src/classes/com/sun/opengl/impl/windows/WindowsOffscreenGLDrawable.java
@@ -128,6 +128,7 @@ public class WindowsOffscreenGLDrawable extends WindowsGLDrawable {
origbitmap = 0;
hbitmap = 0;
hdc = 0;
+ setChosenGLCapabilities(null);
}
}
}
diff --git a/src/classes/com/sun/opengl/impl/windows/WindowsOnscreenGLDrawable.java b/src/classes/com/sun/opengl/impl/windows/WindowsOnscreenGLDrawable.java
index 41f959482..5f74998e5 100644
--- a/src/classes/com/sun/opengl/impl/windows/WindowsOnscreenGLDrawable.java
+++ b/src/classes/com/sun/opengl/impl/windows/WindowsOnscreenGLDrawable.java
@@ -96,6 +96,7 @@ public class WindowsOnscreenGLDrawable extends WindowsGLDrawable {
this.realized = realized;
if (!realized) {
// Assume heavyweight widget was destroyed
+ setChosenGLCapabilities(null);
pixelFormatChosen = false;
}
}
diff --git a/src/classes/com/sun/opengl/impl/windows/WindowsPbufferGLDrawable.java b/src/classes/com/sun/opengl/impl/windows/WindowsPbufferGLDrawable.java
index 0dddddddd..4f87eaecf 100644
--- a/src/classes/com/sun/opengl/impl/windows/WindowsPbufferGLDrawable.java
+++ b/src/classes/com/sun/opengl/impl/windows/WindowsPbufferGLDrawable.java
@@ -96,6 +96,7 @@ public class WindowsPbufferGLDrawable extends WindowsGLDrawable {
throw new GLException("Error destroying pbuffer: error code " + WGL.GetLastError());
}
buffer = 0;
+ setChosenGLCapabilities(null);
}
}
@@ -198,8 +199,8 @@ public class WindowsPbufferGLDrawable extends WindowsGLDrawable {
iattributes[3] = WGLExt.WGL_ALPHA_BITS_ARB;
iattributes[4] = WGLExt.WGL_DEPTH_BITS_ARB;
iattributes[5] = (useFloat ? (ati ? WGLExt.WGL_PIXEL_TYPE_ARB : WGLExt.WGL_FLOAT_COMPONENTS_NV) : WGLExt.WGL_RED_BITS_ARB);
- iattributes[6] = WGLExt.WGL_SAMPLE_BUFFERS_EXT;
- iattributes[7] = WGLExt.WGL_SAMPLES_EXT;
+ iattributes[6] = WGLExt.WGL_SAMPLE_BUFFERS_ARB;
+ iattributes[7] = WGLExt.WGL_SAMPLES_ARB;
iattributes[8] = WGLExt.WGL_DRAW_TO_PBUFFER_ARB;
int[] ivalues = new int[9];
for (int i = 0; i < nformats; i++) {
@@ -237,9 +238,9 @@ public class WindowsPbufferGLDrawable extends WindowsGLDrawable {
}
long tmpBuffer = 0;
- int whichFormat = 0;
+ int whichFormat = -1;
// Loop is a workaround for bugs in NVidia's recent drivers
- do {
+ for (whichFormat = 0; whichFormat < nformats; whichFormat++) {
int format = pformats[whichFormat];
// Create the p-buffer.
@@ -266,8 +267,11 @@ public class WindowsPbufferGLDrawable extends WindowsGLDrawable {
iattributes[niattribs++] = 0;
tmpBuffer = wglExt.wglCreatePbufferARB(parentHdc, format, initWidth, initHeight, iattributes, 0);
- ++whichFormat;
- } while ((tmpBuffer == 0) && (whichFormat < nformats));
+ if (tmpBuffer != 0) {
+ // Done
+ break;
+ }
+ }
if (tmpBuffer == 0) {
throw new GLException("pbuffer creation error: wglCreatePbufferARB() failed: tried " + nformats +
@@ -285,6 +289,33 @@ public class WindowsPbufferGLDrawable extends WindowsGLDrawable {
hdc = tmpHdc;
cachedWGLExt = wglExt;
+ // Re-query chosen pixel format
+ {
+ niattribs = 0;
+ iattributes[niattribs++] = WGLExt.WGL_ACCELERATION_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_RED_BITS_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_GREEN_BITS_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_BLUE_BITS_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_ALPHA_BITS_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_DEPTH_BITS_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_STENCIL_BITS_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_DOUBLE_BUFFER_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_STEREO_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_ACCUM_RED_BITS_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_ACCUM_GREEN_BITS_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_ACCUM_BLUE_BITS_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_ACCUM_ALPHA_BITS_ARB;
+ iattributes[niattribs++] = (useFloat ? (ati ? WGLExt.WGL_PIXEL_TYPE_ARB : WGLExt.WGL_FLOAT_COMPONENTS_NV) : WGLExt.WGL_RED_BITS_ARB);
+ iattributes[niattribs++] = WGLExt.WGL_SAMPLE_BUFFERS_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_SAMPLES_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_PBUFFER_ARB;
+ int[] ivalues = new int[niattribs];
+ // FIXME: usually prefer to throw exceptions, but failure here is not critical
+ if (wglExt.wglGetPixelFormatAttribivARB(parentHdc, pformats[whichFormat], 0, niattribs, iattributes, 0, ivalues, 0)) {
+ setChosenGLCapabilities(iattributes2GLCapabilities(iattributes, niattribs, ivalues, false));
+ }
+ }
+
// Determine the actual width and height we were able to create.
int[] tmp = new int[1];
wglExt.wglQueryPbufferARB( buffer, WGLExt.WGL_PBUFFER_WIDTH_ARB, tmp, 0 );
diff --git a/src/classes/com/sun/opengl/impl/x11/X11GLDrawableFactory.java b/src/classes/com/sun/opengl/impl/x11/X11GLDrawableFactory.java
index b1863d41c..4f92681d0 100644
--- a/src/classes/com/sun/opengl/impl/x11/X11GLDrawableFactory.java
+++ b/src/classes/com/sun/opengl/impl/x11/X11GLDrawableFactory.java
@@ -62,6 +62,38 @@ public class X11GLDrawableFactory extends GLDrawableFactoryImpl {
// in this case
private static boolean isVendorATI;
+ // Map for rediscovering the GLCapabilities associated with a
+ // particular screen and visualID after the fact
+ private static Map visualToGLCapsMap = Collections.synchronizedMap(new HashMap());
+
+ static class ScreenAndVisualIDKey {
+ private int screen;
+ private long visualID;
+
+ ScreenAndVisualIDKey(int screen,
+ long visualID) {
+ this.screen = screen;
+ this.visualID = visualID;
+ }
+
+ public int hashCode() {
+ return (int) (screen + 13 * visualID);
+ }
+
+ public boolean equals(Object obj) {
+ if ((obj == null) || (!(obj instanceof ScreenAndVisualIDKey))) {
+ return false;
+ }
+
+ ScreenAndVisualIDKey key = (ScreenAndVisualIDKey) obj;
+ return (screen == key.screen &&
+ visualID == key.visualID);
+ }
+
+ int screen() { return screen; }
+ long visualID() { return visualID; }
+ }
+
static {
// See DRIHack.java for an explanation of why this is necessary
DRIHack.begin();
@@ -157,6 +189,11 @@ public class X11GLDrawableFactory extends GLDrawableFactoryImpl {
} finally {
unlockToolkit();
}
+ // Store these away for later
+ for (int i = 0; i < infos.length; i++) {
+ 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) + ")");
@@ -200,7 +237,22 @@ public class X11GLDrawableFactory extends GLDrawableFactoryImpl {
throw new IllegalArgumentException("GLDrawables not supported for objects of type " +
target.getClass().getName() + " (only Components are supported in this implementation)");
}
- return new X11OnscreenGLDrawable((Component) target);
+ Component comp = (Component) target;
+ X11OnscreenGLDrawable drawable = new X11OnscreenGLDrawable(comp);
+ // Figure out the GLCapabilities of this component
+ GraphicsConfiguration config = comp.getGraphicsConfiguration();
+ if (config == null) {
+ throw new IllegalArgumentException("GLDrawableFactory.chooseGraphicsConfiguration() was not used when creating this Component");
+ }
+ int visualID = X11SunJDKReflection.graphicsConfigurationGetVisualID(config);
+ int screen;
+ if (isXineramaEnabled()) {
+ screen = 0;
+ } else {
+ screen = X11SunJDKReflection.graphicsDeviceGetScreen(config.getDevice());
+ }
+ drawable.setChosenGLCapabilities((GLCapabilities) visualToGLCapsMap.get(new ScreenAndVisualIDKey(screen, visualID)));
+ return drawable;
}
public GLDrawableImpl createOffscreenDrawable(GLCapabilities capabilities,
@@ -431,6 +483,83 @@ public class X11GLDrawableFactory extends GLDrawableFactoryImpl {
return res;
}
+ public static GLCapabilities attribList2GLCapabilities(int[] iattribs,
+ int niattribs,
+ int[] ivalues,
+ boolean pbuffer) {
+ GLCapabilities caps = new GLCapabilities();
+
+ for (int i = 0; i < niattribs; i++) {
+ int attr = iattribs[i];
+ switch (attr) {
+ case GLX.GLX_DOUBLEBUFFER:
+ caps.setDoubleBuffered(ivalues[i] != GL.GL_FALSE);
+ break;
+
+ case GLX.GLX_STEREO:
+ caps.setStereo(ivalues[i] != GL.GL_FALSE);
+ break;
+
+ case GLX.GLX_RED_SIZE:
+ caps.setRedBits(ivalues[i]);
+ break;
+
+ case GLX.GLX_GREEN_SIZE:
+ caps.setGreenBits(ivalues[i]);
+ break;
+
+ case GLX.GLX_BLUE_SIZE:
+ caps.setBlueBits(ivalues[i]);
+ break;
+
+ case GLX.GLX_ALPHA_SIZE:
+ caps.setAlphaBits(ivalues[i]);
+ break;
+
+ case GLX.GLX_DEPTH_SIZE:
+ caps.setDepthBits(ivalues[i]);
+ break;
+
+ case GLX.GLX_STENCIL_SIZE:
+ caps.setStencilBits(ivalues[i]);
+ break;
+
+ case GLX.GLX_ACCUM_RED_SIZE:
+ caps.setAccumRedBits(ivalues[i]);
+ break;
+
+ case GLX.GLX_ACCUM_GREEN_SIZE:
+ caps.setAccumGreenBits(ivalues[i]);
+ break;
+
+ case GLX.GLX_ACCUM_BLUE_SIZE:
+ caps.setAccumBlueBits(ivalues[i]);
+ break;
+
+ case GLX.GLX_ACCUM_ALPHA_SIZE:
+ caps.setAccumAlphaBits(ivalues[i]);
+ break;
+
+ case GLXExt.GLX_SAMPLE_BUFFERS_ARB:
+ caps.setSampleBuffers(ivalues[i] != GL.GL_FALSE);
+ break;
+
+ case GLXExt.GLX_SAMPLES_ARB:
+ caps.setNumSamples(ivalues[i]);
+ break;
+
+ case GLX.GLX_FLOAT_COMPONENTS_NV:
+ caps.setPbufferFloatingPointBuffers(ivalues[i] != GL.GL_FALSE);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return caps;
+ }
+
public void lockToolkit() {
if (!Java2D.isOGLPipelineActive() || !Java2D.isQueueFlusherThread()) {
JAWT.getJAWT().Lock();
diff --git a/src/classes/com/sun/opengl/impl/x11/X11OffscreenGLDrawable.java b/src/classes/com/sun/opengl/impl/x11/X11OffscreenGLDrawable.java
index 3b3879b8e..d70c79334 100644
--- a/src/classes/com/sun/opengl/impl/x11/X11OffscreenGLDrawable.java
+++ b/src/classes/com/sun/opengl/impl/x11/X11OffscreenGLDrawable.java
@@ -99,6 +99,7 @@ public class X11OffscreenGLDrawable extends X11GLDrawable {
", GLXPixmap " + toHexString(drawable) +
", display " + toHexString(display));
}
+ setChosenGLCapabilities(X11GLDrawableFactory.xvi2GLCapabilities(display, vis));
} finally {
unlockToolkit();
}
@@ -134,6 +135,7 @@ public class X11OffscreenGLDrawable extends X11GLDrawable {
drawable = 0;
pixmap = 0;
display = 0;
+ setChosenGLCapabilities(null);
}
}
diff --git a/src/classes/com/sun/opengl/impl/x11/X11PbufferGLDrawable.java b/src/classes/com/sun/opengl/impl/x11/X11PbufferGLDrawable.java
index 27abdf5b6..b03fdde03 100644
--- a/src/classes/com/sun/opengl/impl/x11/X11PbufferGLDrawable.java
+++ b/src/classes/com/sun/opengl/impl/x11/X11PbufferGLDrawable.java
@@ -166,6 +166,34 @@ public class X11PbufferGLDrawable extends X11GLDrawable {
this.display = display;
drawable = tmpBuffer;
this.fbConfig = fbConfig;
+
+ // Pick innocent query values if multisampling or floating point buffers not available
+ int sbAttrib = X11GLDrawableFactory.isMultisampleAvailable() ? GLXExt.GLX_SAMPLE_BUFFERS_ARB : GLX.GLX_RED_SIZE;
+ int samplesAttrib = X11GLDrawableFactory.isMultisampleAvailable() ? GLXExt.GLX_SAMPLES_ARB : GLX.GLX_RED_SIZE;
+ int floatNV = capabilities.getPbufferFloatingPointBuffers() ? GLX.GLX_FLOAT_COMPONENTS_NV : GLX.GLX_RED_SIZE;
+
+ // Query the fbconfig to determine its GLCapabilities
+ int[] iattribs = {
+ GLX.GLX_DOUBLEBUFFER,
+ GLX.GLX_STEREO,
+ GLX.GLX_RED_SIZE,
+ GLX.GLX_GREEN_SIZE,
+ GLX.GLX_BLUE_SIZE,
+ GLX.GLX_ALPHA_SIZE,
+ GLX.GLX_DEPTH_SIZE,
+ GLX.GLX_STENCIL_SIZE,
+ GLX.GLX_ACCUM_RED_SIZE,
+ GLX.GLX_ACCUM_GREEN_SIZE,
+ GLX.GLX_ACCUM_BLUE_SIZE,
+ GLX.GLX_ACCUM_ALPHA_SIZE,
+ sbAttrib,
+ samplesAttrib,
+ floatNV
+ };
+
+ int[] ivalues = new int[iattribs.length];
+ queryFBConfig(display, fbConfig, iattribs, iattribs.length, ivalues);
+ setChosenGLCapabilities(X11GLDrawableFactory.attribList2GLCapabilities(iattribs, iattribs.length, ivalues, true));
// Determine the actual width and height we were able to create.
int[] tmp = new int[1];
@@ -198,4 +226,14 @@ public class X11PbufferGLDrawable extends X11GLDrawable {
}
return tmp[0];
}
+
+ private void queryFBConfig(long display, GLXFBConfig fbConfig, int[] attribs, int nattribs, int[] values) {
+ int[] tmp = new int[1];
+ for (int i = 0; i < nattribs; i++) {
+ if (GLX.glXGetFBConfigAttrib(display, fbConfig, attribs[i], tmp, 0) != 0) {
+ throw new GLException("glXGetFBConfigAttrib failed");
+ }
+ values[i] = tmp[0];
+ }
+ }
}