diff options
author | Kenneth Russel <[email protected]> | 2006-11-19 20:51:57 +0000 |
---|---|---|
committer | Kenneth Russel <[email protected]> | 2006-11-19 20:51:57 +0000 |
commit | a303cd13ff62f94a0459978735620e37d72bbb77 (patch) | |
tree | 32b580af4e878d479890c12b8eae9c98e10a4874 /src/classes/com/sun/opengl/impl/x11 | |
parent | bf82eceb6f78d5ee6e4c0f9f02590d2a58e647d3 (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/x11')
3 files changed, 170 insertions, 1 deletions
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]; + } + } } |