From 7262641429b542929efc699e392f410f1dee2187 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Tue, 23 Nov 2010 01:54:44 +0100 Subject: X11/WGL: Unify GraphicsConfiguration Selection - Fixes WGL Bugs 397, 410, 429, 428 and 405 Fixes bugs WGL pixelformat related bugs: http://jogamp.org/bugzilla/show_bug.cgi?id=397 http://jogamp.org/bugzilla/show_bug.cgi?id=410 http://jogamp.org/bugzilla/show_bug.cgi?id=429 http://jogamp.org/bugzilla/show_bug.cgi?id=428 http://jogamp.org/bugzilla/show_bug.cgi?id=405 Tested on Window7-x86 (amd/nvidia), WinXP-x32-VirtualBox. Solution: Cleaned up X11/GLX code to use it as a correct boilerplate for the new WGL selection, which now duplicates the same behavior. X11/GLX and WGL follow the common logic: - 1st try: - get GLCapabilities based on users GLCapabilities - setting recommendedIndex as preferred choice - 2nd try: - get all GLCapabilities available - no preferred recommendedIndex available If no recommendedIndex has been selected and no chooser has been passed, we use the DefaultGLCapabilitiesChooser. Choose the GLCapabilities if a chooser is given (or see above). --- .../windows/wgl/WindowsExternalWGLContext.java | 4 +- .../windows/wgl/WindowsPbufferWGLDrawable.java | 24 +- .../opengl/impl/windows/wgl/WindowsWGLContext.java | 6 - .../windows/wgl/WindowsWGLDrawableFactory.java | 3 + .../wgl/WindowsWGLGraphicsConfiguration.java | 263 ++++++++---- .../WindowsWGLGraphicsConfigurationFactory.java | 450 ++++++++++++--------- .../glx/X11GLXGraphicsConfigurationFactory.java | 148 ++++--- 7 files changed, 539 insertions(+), 359 deletions(-) (limited to 'src/jogl/classes/com/jogamp/opengl/impl') diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLContext.java index f50b1a716..173109db9 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLContext.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLContext.java @@ -66,7 +66,9 @@ public class WindowsExternalWGLContext extends WindowsWGLContext { } GLContextShareSet.contextCreated(this); setGLFunctionAvailability(false, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY); - cfg.updateCapabilitiesByWGL(this); + WindowsWGLGraphicsConfiguration config = + (WindowsWGLGraphicsConfiguration)drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + config.updateGraphicsConfiguration(drawable.getFactory(), drawable.getNativeSurface()); getGLStateTracker().setEnabled(false); // external context usage can't track state in Java } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java index 842096e55..47b33dd6b 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java @@ -51,7 +51,6 @@ import javax.media.opengl.GLProfile; import com.jogamp.nativewindow.impl.windows.GDI; import com.jogamp.nativewindow.impl.windows.PIXELFORMATDESCRIPTOR; -import com.jogamp.opengl.impl.GLContextImpl; import javax.media.opengl.GLCapabilitiesImmutable; public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable { @@ -145,10 +144,7 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable { } if(!WindowsWGLGraphicsConfiguration.GLCapabilities2AttribList(capabilities, - iattributes, - sharedCtx, - true, - floatModeTmp)){ + iattributes, sharedCtx, -1, true, floatModeTmp)){ throw new GLException("Pbuffer-related extensions not supported"); } @@ -166,11 +162,11 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable { int nformats; int[] nformatsTmp = new int[1]; if (!wglExt.wglChoosePixelFormatARB(parentHdc, - iattributes, 0, - fattributes, 0, - WindowsWGLGraphicsConfiguration.MAX_PFORMATS, - pformats, 0, - nformatsTmp, 0)) { + iattributes, 0, + fattributes, 0, + WindowsWGLGraphicsConfiguration.MAX_PFORMATS, + pformats, 0, + nformatsTmp, 0)) { throw new GLException("pbuffer creation error: wglChoosePixelFormat() failed"); } nformats = nformatsTmp[0]; @@ -304,16 +300,16 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable { iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_PBUFFER_ARB; int[] ivalues = new int[niattribs]; if (wglExt.wglGetPixelFormatAttribivARB(parentHdc, pformats[whichFormat], 0, niattribs, iattributes, 0, ivalues, 0)) { - GLCapabilitiesImmutable newCaps = WindowsWGLGraphicsConfiguration.AttribList2GLCapabilities(glProfile, iattributes, niattribs, ivalues, true, false, true); + GLCapabilitiesImmutable newCaps = WindowsWGLGraphicsConfiguration.AttribList2GLCapabilities(glProfile, iattributes, niattribs, ivalues, false, true); + if(null == newCaps|| newCaps.isOnscreen() || !newCaps.isPBuffer()) { + throw new GLException("Error: Selected Onscreen Caps for PBuffer: "+newCaps); + } PIXELFORMATDESCRIPTOR pfd = WindowsWGLGraphicsConfiguration.createPixelFormatDescriptor(); if (GDI.DescribePixelFormat(parentHdc, pformats[whichFormat], pfd.size(), pfd) == 0) { if (DEBUG) { System.err.println("Unable to describe pixel format (Continue: true) " + whichFormat + "/" + nformats + " pfdID " + pformats[whichFormat]+":\n\t"+newCaps); } } - if(newCaps.isOnscreen()) { - throw new GLException("Error: Selected Onscreen Caps for PBuffer: "+newCaps+"\n\t"+newCaps); - } config.setCapsPFD(newCaps, pfd, pformats[whichFormat], true); } else { PIXELFORMATDESCRIPTOR pfd = WindowsWGLGraphicsConfiguration.createPixelFormatDescriptor(); diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java index 816532262..c0bab78b0 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java @@ -344,12 +344,6 @@ public class WindowsWGLContext extends GLContextImpl { } } } - - if (newCreated) { - WindowsWGLGraphicsConfiguration config = - (WindowsWGLGraphicsConfiguration)drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration(); - config.updateCapabilitiesByWGL(this); - } } protected void releaseImpl() throws GLException { diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java index 2e29e9c83..80261114f 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java @@ -213,6 +213,9 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { } sharedMap.clear(); + if (DEBUG) { + System.err.println("!!! Shutdown Shared Finished"); + } } protected final GLDrawableImpl createOnscreenDrawableImpl(NativeSurface target) { diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java index c01072a6f..13df54d0e 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java @@ -101,30 +101,10 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio return super.clone(); } - /** Update config - before having a valid context */ protected void updateGraphicsConfiguration(GLDrawableFactory factory, NativeSurface ns) { WindowsWGLGraphicsConfigurationFactory.updateGraphicsConfiguration(chooser, factory, ns); } - /** Update config - after having a valid and current context */ - protected void updateCapabilitiesByWGL(WindowsWGLContext context) { - if(choosenByWGLPixelFormat) return; // already done .. - - GLCapabilitiesImmutable capabilities = (GLCapabilitiesImmutable) getRequestedCapabilities(); - boolean onscreen = capabilities.isOnscreen(); - boolean usePBuffer = capabilities.isPBuffer(); - GLProfile glp = capabilities.getGLProfile(); - - GLDrawable drawable = context.getGLDrawable(); - NativeSurface ns = drawable.getNativeSurface(); - long hdc = ns.getSurfaceHandle(); - - GLCapabilitiesImmutable[] caps = HDC2GLCapabilities(context, hdc, getPixelFormatID(), glp, true, onscreen, usePBuffer); - if(null!=caps && null!=caps[0]) { - setCapsPFD(caps[0], getPixelFormat(), getPixelFormatID(), true); - } - } - protected void setCapsPFD(GLCapabilitiesImmutable caps, PIXELFORMATDESCRIPTOR pfd, int pfdID, boolean choosenByWGLPixelFormat) { this.pixelfmt = pfd; this.pixelfmtID = pfdID; @@ -144,19 +124,158 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio public int getPixelFormatID() { return pixelfmtID; } public boolean isChoosenByWGL() { return choosenByWGLPixelFormat; } - public static GLCapabilitiesImmutable[] HDC2GLCapabilities(WindowsWGLContext sharedCtx, long hdc, int pfdIDOnly, - GLProfile glp, boolean relaxed, boolean onscreen, boolean usePBuffer) { - + private static int fillAttribsForGeneralWGLARBQuery(boolean haveWGLARBMultisample, int[] iattributes) { + int niattribs = 0; + iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_WINDOW_ARB; + iattributes[niattribs++] = WGLExt.WGL_ACCELERATION_ARB; + iattributes[niattribs++] = WGLExt.WGL_SUPPORT_OPENGL_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_PIXEL_TYPE_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_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; + if (haveWGLARBMultisample) { + iattributes[niattribs++] = WGLExt.WGL_SAMPLE_BUFFERS_ARB; + iattributes[niattribs++] = WGLExt.WGL_SAMPLES_ARB; + } + return niattribs; + } + + public static boolean wglARBPFIDValid(WindowsWGLContext sharedCtx, long hdc, int pfdID) { + int[] in = new int[1]; + int[] out = new int[1]; + in[0] = WGLExt.WGL_COLOR_BITS_ARB; + if (!sharedCtx.getWGLExt().wglGetPixelFormatAttribivARB(hdc, pfdID, 0, 1, in, 0, out, 0)) { + // Intel Extreme graphics 'fails' with a zero error code + return GDI.GetLastError() == 0 ; + } + return true; + } + + public static GLCapabilitiesImmutable wglARBPFID2GLCapabilities(WindowsWGLContext sharedCtx, long hdc, int pfdID, + GLProfile glp, boolean onscreen, boolean usePBuffer) { boolean haveWGLChoosePixelFormatARB = sharedCtx.isExtensionAvailable("WGL_ARB_pixel_format"); + if (!haveWGLChoosePixelFormatARB) { + return null; + } boolean haveWGLARBMultisample = sharedCtx.isExtensionAvailable("WGL_ARB_multisample"); - if(DEBUG) { - System.err.println("HDC2GLCapabilities: ARB_pixel_format: "+haveWGLChoosePixelFormatARB); - System.err.println("HDC2GLCapabilities: ARB_multisample : "+haveWGLARBMultisample); + + int[] iattributes = new int [2*MAX_ATTRIBS]; + int[] iresults = new int [2*MAX_ATTRIBS]; + + iattributes[0] = WGLExt.WGL_NUMBER_PIXEL_FORMATS_ARB; + if (sharedCtx.getWGLExt().wglGetPixelFormatAttribivARB(hdc, 0, 0, 1, iattributes, 0, iresults, 0)) { + if(iresults[0] > 0 ) { + int niattribs = fillAttribsForGeneralWGLARBQuery(haveWGLARBMultisample, iattributes); + if (!sharedCtx.getWGLExt().wglGetPixelFormatAttribivARB(hdc, pfdID, 0, niattribs, iattributes, 0, iresults, 0)) { + throw new GLException("wglARBPFID2GLCapabilities: Error getting pixel format attributes for pixel format " + pfdID + " of device context"); + } + return AttribList2GLCapabilities(glp, iattributes, niattribs, iresults, + onscreen, usePBuffer); + } + } + long lastErr = GDI.GetLastError(); + // Intel Extreme graphics fails with a zero error code + if (lastErr != 0) { + throw new GLException("wglARBPFID2GLCapabilities: Unable to enumerate pixel formats of window using wglGetPixelFormatAttribivARB: error code " + GDI.GetLastError()); } + return null; + } + protected static int wglChoosePixelFormatARB(long hdc, WindowsWGLContext sharedContext, + GLCapabilitiesImmutable capabilities, + int[] iattributes, int accelerationMode, float[] fattributes, + int[] pformats) + { + int numFormats = -1; + + if(WindowsWGLGraphicsConfiguration.GLCapabilities2AttribList(capabilities, + iattributes, + sharedContext, + accelerationMode, + false, + null)) { + int[] numFormatsTmp = new int[1]; + if (sharedContext.getWGLExt().wglChoosePixelFormatARB(hdc, + iattributes, 0, + fattributes, 0, + WindowsWGLGraphicsConfiguration.MAX_PFORMATS, + pformats, 0, + numFormatsTmp, 0)) { + numFormats = numFormatsTmp[0]; + if (DEBUG) { + System.err.println("wglChoosePixelFormatARB1: NumFormats (wglChoosePixelFormatARB) accelMode 0x" + + Integer.toHexString(accelerationMode) + ": " + numFormats + " / " + WindowsWGLGraphicsConfiguration.MAX_PFORMATS); + } + } else { + if (DEBUG) { + System.err.println("wglChoosePixelFormatARB1: wglChoosePixelFormatARB failed: " + GDI.GetLastError() ); + Thread.dumpStack(); + } + } + } else { + if (DEBUG) { + System.err.println("wglChoosePixelFormatARB1: GLCapabilities2AttribList failed: " + GDI.GetLastError() ); + Thread.dumpStack(); + } + } + return numFormats; + } + + public static GLCapabilitiesImmutable[] wglARBPFIDs2GLCapabilities(WindowsWGLContext sharedCtx, long hdc, int[] pfdIDs, int numFormats, + GLProfile glp, boolean onscreen, boolean usePBuffer) { + boolean haveWGLChoosePixelFormatARB = sharedCtx.isExtensionAvailable("WGL_ARB_pixel_format"); + if (!haveWGLChoosePixelFormatARB) { + return null; + } + boolean haveWGLARBMultisample = sharedCtx.isExtensionAvailable("WGL_ARB_multisample"); + + GLCapabilitiesImmutable[] caps = new GLCapabilitiesImmutable[numFormats]; + + int[] iattributes = new int [2*MAX_ATTRIBS]; + int[] iresults = new int [2*MAX_ATTRIBS]; + int niattribs = fillAttribsForGeneralWGLARBQuery(haveWGLARBMultisample, iattributes); + + for(int i = 0; i= 1 && + sharedCtx.getWGLExt().wglGetPixelFormatAttribivARB(hdc, pfdIDs[i], 0, niattribs, iattributes, 0, iresults, 0) ) { + caps[i] = AttribList2GLCapabilities(glp, iattributes, niattribs, iresults, onscreen, usePBuffer); + } else { + if (DEBUG) { + System.err.println("wglARBPFIDs2GLCapabilities: Cannot get pixel format attributes for pixel format " + + i + "/" + numFormats + ": " + pfdIDs[i]); + } + caps[i] = null; + } + } + return caps; + } + + /** + * + * @param sharedCtx + * @param hdc + * @param glp + * @param onscreen + * @param usePBuffer + * @param pfIDs stores the PIXELFORMAT ID for the GLCapabilitiesImmutable[] + * @return the resulting GLCapabilitiesImmutable[] + */ + public static GLCapabilitiesImmutable[] wglARBAllPFIDs2GLCapabilities(WindowsWGLContext sharedCtx, long hdc, + GLProfile glp, boolean onscreen, boolean usePBuffer, int[] pfIDs) { + boolean haveWGLChoosePixelFormatARB = sharedCtx.isExtensionAvailable("WGL_ARB_pixel_format"); if (!haveWGLChoosePixelFormatARB) { return null; } + boolean haveWGLARBMultisample = sharedCtx.isExtensionAvailable("WGL_ARB_multisample"); // Produce a list of GLCapabilities to give to the // GLCapabilitiesChooser. @@ -170,70 +289,36 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio GLCapabilitiesImmutable[] availableCaps = null; int numFormats = 0; int niattribs = 0; - int[] iattributes = new int [2*MAX_ATTRIBS]; - int[] iresults = new int [2*MAX_ATTRIBS]; + int[] iattributes = new int[2 * MAX_ATTRIBS]; + int[] iresults = new int[2 * MAX_ATTRIBS]; WGLExt wglExt = sharedCtx.getWGLExt(); iattributes[0] = WGLExt.WGL_NUMBER_PIXEL_FORMATS_ARB; if (wglExt.wglGetPixelFormatAttribivARB(hdc, 0, 0, 1, iattributes, 0, iresults, 0)) { - numFormats = iresults[0]; - - if (DEBUG) { - System.err.println("wglGetPixelFormatAttribivARB reported WGL_NUMBER_PIXEL_FORMATS = " + numFormats); - } - - if(pfdIDOnly>0 && pfdIDOnly>numFormats) { - throw new GLException("Invalid pixelformat ID " + pfdIDOnly + " (should be between 1 and " + numFormats + ")"); - } + numFormats = iresults[0]; + if (DEBUG) { + System.err.println("wglARBAllPFIDs2GLCapabilities: wglGetPixelFormatAttribivARB reported WGL_NUMBER_PIXEL_FORMATS = " + numFormats + ", pfIDs sz "+pfIDs.length); + } + if (numFormats > pfIDs.length) { + numFormats = pfIDs.length; + } - // Should we be filtering out the pixel formats which aren't - // applicable, as we are doing here? - // We don't have enough information in the GLCapabilities to - // represent those that aren't... - iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_WINDOW_ARB; - iattributes[niattribs++] = WGLExt.WGL_ACCELERATION_ARB; - iattributes[niattribs++] = WGLExt.WGL_SUPPORT_OPENGL_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_PIXEL_TYPE_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_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; - if (haveWGLARBMultisample) { - iattributes[niattribs++] = WGLExt.WGL_SAMPLE_BUFFERS_ARB; - iattributes[niattribs++] = WGLExt.WGL_SAMPLES_ARB; - } + niattribs = fillAttribsForGeneralWGLARBQuery(haveWGLARBMultisample, iattributes); - if(pfdIDOnly>0) { - availableCaps = new GLCapabilitiesImmutable[1]; - if (!wglExt.wglGetPixelFormatAttribivARB(hdc, pfdIDOnly, 0, niattribs, iattributes, 0, iresults, 0)) { - throw new GLException("Error getting pixel format attributes for pixel format " + pfdIDOnly + " of device context"); - } - availableCaps[0] = AttribList2GLCapabilities(glp, iattributes, niattribs, iresults, - relaxed, onscreen, usePBuffer); - } else { - availableCaps = new GLCapabilitiesImmutable[numFormats]; - for (int i = 0; i < numFormats; i++) { - if (!wglExt.wglGetPixelFormatAttribivARB(hdc, i+1, 0, niattribs, iattributes, 0, iresults, 0)) { - throw new GLException("Error getting pixel format attributes for pixel format " + (i + 1) + " of device context"); + availableCaps = new GLCapabilitiesImmutable[numFormats]; + for (int i = 0; i < numFormats; i++) { + pfIDs[i] = i + 1; + if (!wglExt.wglGetPixelFormatAttribivARB(hdc, pfIDs[i], 0, niattribs, iattributes, 0, iresults, 0)) { + throw new GLException("wglARBAllPFIDs2GLCapabilities: Error getting pixel format attributes for pixel format " + pfIDs[i]); } - availableCaps[i] = AttribList2GLCapabilities(glp, iattributes, niattribs, iresults, - relaxed, onscreen, usePBuffer); - } - } + availableCaps[i] = AttribList2GLCapabilities(glp, iattributes, niattribs, iresults, onscreen, usePBuffer); + } } else { - long lastErr = GDI.GetLastError(); - // Intel Extreme graphics fails with a zero error code - if (lastErr != 0) { - throw new GLException("Unable to enumerate pixel formats of window using wglGetPixelFormatAttribivARB: error code " + GDI.GetLastError()); - } + long lastErr = GDI.GetLastError(); + // Intel Extreme graphics fails with a zero error code + if (lastErr != 0) { + throw new GLException("wglARBAllPFIDs2GLCapabilities: Unable to enumerate pixel formats of window using wglGetPixelFormatAttribivARB: error code " + GDI.GetLastError()); + } } return availableCaps; } @@ -241,6 +326,7 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio public static boolean GLCapabilities2AttribList(GLCapabilitiesImmutable caps, int[] iattributes, GLContextImpl sharedCtx, + int accellerationValue, boolean pbuffer, int[] floatMode) throws GLException { boolean haveWGLChoosePixelFormatARB = sharedCtx.isExtensionAvailable("WGL_ARB_pixel_format"); @@ -258,6 +344,10 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio iattributes[niattribs++] = WGLExt.WGL_SUPPORT_OPENGL_ARB; iattributes[niattribs++] = GL.GL_TRUE; + if(accellerationValue>0) { + iattributes[niattribs++] = WGLExt.WGL_ACCELERATION_ARB; + iattributes[niattribs++] = accellerationValue; + } if (pbuffer) { iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_PBUFFER_ARB; iattributes[niattribs++] = GL.GL_TRUE; @@ -445,15 +535,12 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio GLProfile glp, int[] iattribs, int niattribs, int[] iresults, - boolean relaxed, boolean onscreen, boolean usePBuffer) { + boolean onscreen, boolean usePBuffer) { GLCapabilities res = new GLCapabilities(glp); int drawableTypeBits = WGLConfig2DrawableTypeBits(iattribs, niattribs, iresults); if(WGLConfigDrawableTypeVerify(drawableTypeBits, onscreen, usePBuffer)) { res.setOnscreen(onscreen); res.setPBuffer(usePBuffer); - } else if(relaxed) { - res.setOnscreen( 0 != (drawableTypeBits & WINDOW_BIT) ); - res.setPBuffer ( 0 != (drawableTypeBits & PBUFFER_BIT) ); } else { if(DEBUG) { System.err.println("WGL DrawableType does not match: req(onscrn "+onscreen+", pbuffer "+usePBuffer+"), got(onscreen "+( 0 != (drawableTypeBits & WINDOW_BIT) )+", pbuffer "+( 0 != (drawableTypeBits & PBUFFER_BIT) )+", pixmap "+( 0 != (drawableTypeBits & BITMAP_BIT))+")"); @@ -575,8 +662,8 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio res.setStencilBits (pfd.getCStencilBits()); res.setDoubleBuffered((pfd.getDwFlags() & GDI.PFD_DOUBLEBUFFER) != 0); res.setStereo ((pfd.getDwFlags() & GDI.PFD_STEREO) != 0); - res.setHardwareAccelerated( ((pfd.getDwFlags() & GDI.PFD_GENERIC_FORMAT) == 0) || - ((pfd.getDwFlags() & GDI.PFD_GENERIC_ACCELERATED) != 0) ); + res.setHardwareAccelerated( (pfd.getDwFlags() & GDI.PFD_GENERIC_FORMAT) == 0 || + (pfd.getDwFlags() & GDI.PFD_GENERIC_ACCELERATED) != 0 ); res.setOnscreen ( onscreen && ((pfd.getDwFlags() & GDI.PFD_DRAW_TO_WINDOW) != 0) ); res.setPBuffer ( usePBuffer ); /* FIXME: Missing ?? diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java index 4989d86a2..6228a80a9 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java @@ -51,6 +51,7 @@ import javax.media.opengl.GLProfile; import com.jogamp.nativewindow.impl.windows.GDI; import com.jogamp.nativewindow.impl.windows.PIXELFORMATDESCRIPTOR; import javax.media.nativewindow.CapabilitiesImmutable; +import javax.media.opengl.DefaultGLCapabilitiesChooser; import javax.media.opengl.GLCapabilitiesImmutable; /** Subclass of GraphicsConfigurationFactory used when non-AWT tookits @@ -109,226 +110,309 @@ public class WindowsWGLGraphicsConfigurationFactory extends GraphicsConfiguratio protected static void updateGraphicsConfiguration(CapabilitiesChooser chooser, GLDrawableFactory _factory, NativeSurface ns) { - WindowsWGLDrawableFactory factory = (WindowsWGLDrawableFactory) _factory; if (ns == null) { throw new IllegalArgumentException("NativeSurface is null"); } - - if (chooser != null && - !(chooser instanceof GLCapabilitiesChooser)) { + long hdc = ns.getSurfaceHandle(); + if (0 == hdc) { + throw new GLException("Error: HDC is null"); + } + WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration) ns.getGraphicsConfiguration().getNativeGraphicsConfiguration(); + if (chooser != null && !(chooser instanceof GLCapabilitiesChooser)) { throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilitiesChooser objects"); } - WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration) ns.getGraphicsConfiguration().getNativeGraphicsConfiguration(); - AbstractGraphicsDevice device = config.getScreen().getDevice(); - WindowsWGLContext sharedContext = (WindowsWGLContext) factory.getOrCreateSharedContextImpl(device); - if(null==sharedContext) { - throw new InternalError("SharedContext is null: "+device); + if (DEBUG) { + System.err.println("updateGraphicsConfiguration: hdc "+toHexString(hdc)); + System.err.println("!!! user chosen caps " + config.getChosenCapabilities()); } - boolean choosenBywGLPixelFormat = false; - GLCapabilitiesImmutable capabilities = (GLCapabilitiesImmutable) config.getChosenCapabilities(); - boolean onscreen = capabilities.isOnscreen(); - boolean usePBuffer = capabilities.isPBuffer(); - GLProfile glProfile = capabilities.getGLProfile(); - long hdc = ns.getSurfaceHandle(); - if(0==hdc) { - throw new GLException("Error: HDC is null "+toHexString(hdc)); + if( !updateGraphicsConfigurationARB(hdc, config, chooser, (WindowsWGLDrawableFactory) _factory) ) { + updateGraphicsConfigurationGDI(hdc, config, chooser, (WindowsWGLDrawableFactory) _factory); } - if(DEBUG) { - Exception ex = new Exception("Info: WindowsWGLGraphicsConfigurationFactory got HDC "+toHexString(hdc)); - ex.printStackTrace(); + } + + protected static boolean updateGraphicsConfigurationARB(long hdc, WindowsWGLGraphicsConfiguration config, + CapabilitiesChooser chooser, WindowsWGLDrawableFactory factory) { + AbstractGraphicsDevice device = config.getScreen().getDevice(); + WindowsWGLContext sharedContext = (WindowsWGLContext) factory.getOrCreateSharedContextImpl(device); + if (null == sharedContext) { + throw new InternalError("SharedContext is null: " + device); } + GLCapabilitiesImmutable capsChosen = (GLCapabilitiesImmutable) config.getChosenCapabilities(); + boolean onscreen = capsChosen.isOnscreen(); + boolean usePBuffer = capsChosen.isPBuffer(); + GLProfile glProfile = capsChosen.getGLProfile(); + + int pixelFormatSet = -1; // 1-based pixel format + GLCapabilitiesImmutable pixelFormatCaps = null; - PIXELFORMATDESCRIPTOR pfd = null; - int pixelFormat = -1; // 1-based pixel format - boolean pixelFormatSet = false; - GLCapabilitiesImmutable chosenCaps = null; + GLCapabilitiesImmutable[] availableCaps = null; + int[] pformats = null; // if != null, then index matches availableCaps + int numFormats = -1; + int recommendedIndex = -1; - if (onscreen) { - if ((pixelFormat = GDI.GetPixelFormat(hdc)) != 0) { + if ((pixelFormatSet = GDI.GetPixelFormat(hdc)) != 0) { // Pixelformat already set by either // - a previous updateGraphicsConfiguration() call on the same HDC, // - the graphics driver, copying the HDC's pixelformat to the new one, // - or the Java2D/OpenGL pipeline's configuration if (DEBUG) { - System.err.println("!!!! NOTE: pixel format already chosen for HDC: " + toHexString(hdc)+ - ", pixelformat "+pixelFormat); + System.err.println("updateGraphicsConfigurationARB: Pixel format already chosen for HDC: " + toHexString(hdc) + + ", pixelformat " + pixelFormatSet); } - pixelFormatSet = true; - } - - GLCapabilitiesImmutable[] availableCaps = null; - int numFormats = 0; - pfd = WindowsWGLGraphicsConfiguration.createPixelFormatDescriptor(); - // Produce a recommended pixel format selection for the GLCapabilitiesChooser. - // Use wglChoosePixelFormatARB if user requested multisampling and if we have it available - int recommendedPixelFormat = pixelFormat; // 1-based pixel format - boolean gotAvailableCaps = false; - synchronized(sharedContext) { - sharedContext.makeCurrent(); - try { - WGLExt wglExt = sharedContext.getWGLExt(); - boolean haveWGLChoosePixelFormatARB = false; - if (wglExt != null) { - haveWGLChoosePixelFormatARB = wglExt.isExtensionAvailable("WGL_ARB_pixel_format"); - if (haveWGLChoosePixelFormatARB) { - if(pixelFormat<=0) { - int[] iattributes = new int [2*WindowsWGLGraphicsConfiguration.MAX_ATTRIBS]; - float[] fattributes = new float[1]; - - if(WindowsWGLGraphicsConfiguration.GLCapabilities2AttribList(capabilities, - iattributes, - sharedContext, - false, - null)) { - int[] pformats = new int[WindowsWGLGraphicsConfiguration.MAX_PFORMATS]; - int[] numFormatsTmp = new int[1]; - if (wglExt.wglChoosePixelFormatARB(hdc, - iattributes, 0, - fattributes, 0, - WindowsWGLGraphicsConfiguration.MAX_PFORMATS, - pformats, 0, - numFormatsTmp, 0)) { - numFormats = numFormatsTmp[0]; - if (DEBUG) { - System.err.println(getThreadName() + ": NumFormats (wglChoosePixelFormatARB) " + numFormats); - } - if (recommendedPixelFormat<=0 && numFormats > 0) { - recommendedPixelFormat = pformats[0]; - if (DEBUG) { - System.err.println(getThreadName() + ": Used wglChoosePixelFormatARB to recommend pixel format " + recommendedPixelFormat); - } - } - } else { - if (DEBUG) { - System.err.println(getThreadName() + ": wglChoosePixelFormatARB failed: " + GDI.GetLastError() ); - Thread.dumpStack(); - } - } + } + + synchronized (sharedContext) { + sharedContext.makeCurrent(); + try { + if (!sharedContext.isExtensionAvailable("WGL_ARB_pixel_format")) { + if (DEBUG) { + System.err.println("updateGraphicsConfigurationARB: wglChoosePixelFormatARB not available"); + } + return false; + } + if (pixelFormatSet >= 1) { + // only fetch the specific one .. + pixelFormatCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedContext, hdc, pixelFormatSet, + glProfile, onscreen, usePBuffer); + } else { + int[] iattributes = new int[2 * WindowsWGLGraphicsConfiguration.MAX_ATTRIBS]; + float[] fattributes = new float[1]; + pformats = new int[WindowsWGLGraphicsConfiguration.MAX_PFORMATS]; + + // 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice + numFormats = WindowsWGLGraphicsConfiguration.wglChoosePixelFormatARB(hdc, sharedContext, capsChosen, + iattributes, -1, fattributes, pformats); + if (0 < numFormats) { + availableCaps = WindowsWGLGraphicsConfiguration.wglARBPFIDs2GLCapabilities(sharedContext, hdc, pformats, numFormats, + glProfile, onscreen, usePBuffer); + if (null != availableCaps) { + recommendedIndex = 0; + pixelFormatCaps = availableCaps[0]; if (DEBUG) { - if (recommendedPixelFormat <= 0) { - System.err.print(getThreadName() + ": wglChoosePixelFormatARB didn't recommend a pixel format: "+GDI.GetLastError()); - if (capabilities.getSampleBuffers()) { - System.err.print(" for multisampled GLCapabilities"); - } - System.err.println(); - } + System.err.println("updateGraphicsConfigurationARB: NumFormats (wglChoosePixelFormatARB) " + numFormats + " / " + WindowsWGLGraphicsConfiguration.MAX_PFORMATS); + System.err.println("updateGraphicsConfigurationARB: Used wglChoosePixelFormatARB to recommend pixel format " + pformats[recommendedIndex] + ", idx " + recommendedIndex); + System.err.println("!!! recommended caps " + pixelFormatCaps); } - } } + } - availableCaps = WindowsWGLGraphicsConfiguration.HDC2GLCapabilities(sharedContext, hdc, -1, glProfile, pixelFormatSet, onscreen, usePBuffer); - gotAvailableCaps = null!=availableCaps ; - choosenBywGLPixelFormat = gotAvailableCaps ; - } else if (DEBUG) { - System.err.println(getThreadName() + ": wglChoosePixelFormatARB not available"); - } - } - } finally { - sharedContext.release(); - } - } // synchronized(factory.sharedContext) - - if (!gotAvailableCaps) { - if (DEBUG) { - System.err.println(getThreadName() + ": Using ChoosePixelFormat ... (LastError: "+GDI.GetLastError()+")"); + // 2nd choice: get all GLCapabilities available, no preferred recommendedIndex available + if (null == availableCaps) { + if (DEBUG) { + System.err.println("updateGraphicsConfigurationARB: wglChoosePixelFormatARB failed (Query all formats without recommendation): " + GDI.GetLastError()); + } + availableCaps = WindowsWGLGraphicsConfiguration.wglARBAllPFIDs2GLCapabilities(sharedContext, hdc, + glProfile, onscreen, usePBuffer, pformats); + if (null != availableCaps) { + numFormats = availableCaps.length; + } + } + } + } finally { + sharedContext.release(); } - pfd = WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(capabilities); - recommendedPixelFormat = GDI.ChoosePixelFormat(hdc, pfd); + } // synchronized(factory.sharedContext) + + if (pixelFormatSet <= 0 && null == availableCaps) { if (DEBUG) { - System.err.println(getThreadName() + ": ChoosePixelFormat(HDC "+toHexString(hdc)+") = " + recommendedPixelFormat + " (LastError: "+GDI.GetLastError()+")"); - System.err.println(getThreadName() + ": Used " + capabilities); + System.err.println("updateGraphicsConfigurationARB: No PixelFormat chosen via ARB ... (LastError: " + GDI.GetLastError() + ")"); } + return false; + } + + int pfdID; + + if (pixelFormatSet <= 0) { + if (null == pixelFormatCaps && null == chooser) { + chooser = new DefaultGLCapabilitiesChooser(); + } + + int chosenIndex = recommendedIndex; + try { + if (null != chooser) { + chosenIndex = chooser.chooseCapabilities(capsChosen, availableCaps, recommendedIndex); + pixelFormatCaps = availableCaps[chosenIndex]; + if (DEBUG) { + System.err.println("updateGraphicsConfigurationARB: chooser: idx " + chosenIndex); + System.err.println("!!! chosen caps " + pixelFormatCaps); + } + } + } catch (NativeWindowException e) { + if (DEBUG) { + e.printStackTrace(); + } + } + + if (chosenIndex < 0) { + // keep on going .. + // seek first available one .. + for (chosenIndex = 0; chosenIndex < availableCaps.length && availableCaps[chosenIndex] == null; chosenIndex++) { + // nop + } + if (chosenIndex == availableCaps.length) { + // give up .. + if (DEBUG) { + System.err.println("updateGraphicsConfigurationARB: Failed .. nothing available, bail out"); + } + return false; + } + pixelFormatCaps = availableCaps[chosenIndex]; + if (DEBUG) { + System.err.println("updateGraphicsConfigurationARB: Failed .. unable to choose config, using first available idx: " + chosenIndex); + System.err.println("!!! fallback caps " + pixelFormatCaps); + } + } + pfdID = pformats[chosenIndex]; + } else { + pfdID = pixelFormatSet; + } + if (DEBUG) { + System.err.println("updateGraphicsConfigurationARB: using pfdID "+pfdID); + } + + PIXELFORMATDESCRIPTOR pfd = WindowsWGLGraphicsConfiguration.createPixelFormatDescriptor(); - numFormats = GDI.DescribePixelFormat(hdc, 1, 0, null); - if (numFormats == 0) { - throw new GLException("Unable to enumerate pixel formats of window " + - toHexString(hdc) + " for GLCapabilitiesChooser (LastError: "+GDI.GetLastError()+")"); + if (GDI.DescribePixelFormat(hdc, pfdID, pfd.size(), pfd) == 0) { + throw new GLException("updateGraphicsConfigurationARB: Error describing the chosen pixel format: " + pfdID + ", " + GDI.GetLastError()); + } + + if (pixelFormatSet <= 0) { + if (!GDI.SetPixelFormat(hdc, pfdID, pfd)) { + long lastError = GDI.GetLastError(); + throw new GLException("Unable to set pixel format " + pfdID + " for device context " + toHexString(hdc) + ": error code " + lastError); } + } + + config.setCapsPFD(pixelFormatCaps, pfd, pfdID, true); + return true; + } + + protected static boolean updateGraphicsConfigurationGDI(long hdc, WindowsWGLGraphicsConfiguration config, + CapabilitiesChooser chooser, WindowsWGLDrawableFactory factory) { + AbstractGraphicsDevice device = config.getScreen().getDevice(); + WindowsWGLContext sharedContext = (WindowsWGLContext) factory.getOrCreateSharedContextImpl(device); + if (null == sharedContext) { + throw new InternalError("SharedContext is null: " + device); + } + GLCapabilitiesImmutable capsChosen = (GLCapabilitiesImmutable) config.getChosenCapabilities(); + boolean onscreen = capsChosen.isOnscreen(); + boolean usePBuffer = capsChosen.isPBuffer(); + GLProfile glProfile = capsChosen.getGLProfile(); + + int pixelFormatSet = -1; // 1-based pixel format + GLCapabilitiesImmutable pixelFormatCaps = null; + + GLCapabilitiesImmutable[] availableCaps = null; + int numFormats = -1; + int recommendedIndex = -1; + + if ((pixelFormatSet = GDI.GetPixelFormat(hdc)) != 0) { + // Pixelformat already set by either + // - a previous updateGraphicsConfiguration() call on the same HDC, + // - the graphics driver, copying the HDC's pixelformat to the new one, + // - or the Java2D/OpenGL pipeline's configuration if (DEBUG) { - System.err.println(getThreadName() + ": NumFormats (DescribePixelFormat) " + numFormats); + System.err.println("updateGraphicsConfigurationGDI: NOTE: pixel format already chosen for HDC: " + toHexString(hdc) + + ", pixelformat " + pixelFormatSet); } + } + + int recommendedPixelFormat = pixelFormatSet; - availableCaps = new GLCapabilitiesImmutable[numFormats]; - for (int i = 0; i < numFormats; i++) { - if (GDI.DescribePixelFormat(hdc, 1 + i, pfd.size(), pfd) == 0) { + numFormats = GDI.DescribePixelFormat(hdc, 1, 0, null); + if (numFormats == 0) { + throw new GLException("Unable to enumerate pixel formats of window " + + toHexString(hdc) + " for GLCapabilitiesChooser (LastError: " + GDI.GetLastError() + ")"); + } + if (DEBUG) { + System.err.println("updateGraphicsConfigurationGDI: NumFormats (DescribePixelFormat) " + numFormats); + } + + PIXELFORMATDESCRIPTOR pfd = WindowsWGLGraphicsConfiguration.createPixelFormatDescriptor(); + availableCaps = new GLCapabilitiesImmutable[numFormats]; + for (int i = 0; i < numFormats; i++) { + if (GDI.DescribePixelFormat(hdc, 1 + i, pfd.size(), pfd) == 0) { throw new GLException("Error describing pixel format " + (1 + i) + " of device context"); - } - availableCaps[i] = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, pfd, onscreen, usePBuffer); } - } - - // NOTE: officially, should make a copy of all of these - // GLCapabilities to avoid mutation by the end user during the - // chooseCapabilities call, but for the time being, assume they - // won't be changed - - if(pixelFormat<=0) { - if(null!=chooser) { - // Supply information to chooser - try { - pixelFormat = chooser.chooseCapabilities(capabilities, availableCaps, recommendedPixelFormat) + 1; - } catch (NativeWindowException e) { - if(DEBUG) { - e.printStackTrace(); + availableCaps[i] = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, pfd, onscreen, usePBuffer); + } + + int pfdID; + + if (pixelFormatSet <= 0) { + pfd = WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(capsChosen); + recommendedPixelFormat = GDI.ChoosePixelFormat(hdc, pfd); + recommendedIndex = recommendedPixelFormat - 1; + pixelFormatCaps = availableCaps[recommendedIndex]; + if (DEBUG) { + System.err.println("updateGraphicsConfigurationGDI: ChoosePixelFormat(HDC " + toHexString(hdc) + ") = " + recommendedPixelFormat + " (LastError: " + GDI.GetLastError() + ")"); + System.err.println("!!! recommended caps " + pixelFormatCaps); + } + + int chosenIndex = recommendedIndex; + try { + if (null != chooser) { + chosenIndex = chooser.chooseCapabilities(capsChosen, availableCaps, recommendedIndex); + pixelFormatCaps = availableCaps[chosenIndex]; + if (DEBUG) { + System.err.println("updateGraphicsConfigurationGDI: chooser: idx " + chosenIndex); + System.err.println("!!! chosen caps " + pixelFormatCaps); } - pixelFormat = -1; - } - } else { - pixelFormat = recommendedPixelFormat; - } - if (pixelFormat <= 0) { - // keep on going .. - if(DEBUG) { - System.err.println("WindowsWGLGraphicsConfigurationFactory.updateGraphicsConfiguration .. unable to choose config, using first"); - } - pixelFormat = 1; // default .. - } else if ( pixelFormat > numFormats ) { - // keep on going .. - if(DEBUG) { - System.err.println("GLCapabilitiesChooser specified invalid index (expected 1.." + numFormats + ", got "+pixelFormat+")"); - } - pixelFormat = 1; // default .. - } - } - chosenCaps = availableCaps[pixelFormat-1]; - if (DEBUG) { - System.err.println(getThreadName() + ": Chosen pixel format (" + pixelFormat + "):"); - System.err.println(chosenCaps); - } - if (GDI.DescribePixelFormat(hdc, pixelFormat, pfd.size(), pfd) == 0) { - throw new GLException("Error re-describing the chosen pixel format: " + GDI.GetLastError()); - } + } + } catch (NativeWindowException e) { + if (DEBUG) { + e.printStackTrace(); + } + } + + if (chosenIndex < 0) { + // keep on going .. + // seek first available one .. + for (chosenIndex = 0; chosenIndex < availableCaps.length && availableCaps[chosenIndex] == null; chosenIndex++) { + // nop + } + if (chosenIndex == availableCaps.length) { + // give up .. + if (DEBUG) { + System.err.println("updateGraphicsConfigurationGDI: Failed .. nothing available, bail out"); + } + return false; + } + pixelFormatCaps = availableCaps[chosenIndex]; + if (DEBUG) { + System.err.println("updateGraphicsConfigurationGDI: Failed .. unable to choose config, using first available idx: " + chosenIndex); + System.err.println("!!! fallback caps " + pixelFormatCaps); + } + } + pfdID = chosenIndex + 1; } else { - // For now, use ChoosePixelFormat for offscreen surfaces until - // we figure out how to properly choose an offscreen- - // compatible pixel format - pfd = WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(capabilities); - pixelFormat = GDI.ChoosePixelFormat(hdc, pfd); - } - if(!pixelFormatSet) { - if (!GDI.SetPixelFormat(hdc, pixelFormat, pfd)) { - long lastError = GDI.GetLastError(); - if (DEBUG) { - System.err.println(getThreadName() + ": SetPixelFormat failed: current context = " + WGL.wglGetCurrentContext() + - ", current DC = " + WGL.wglGetCurrentDC()); - System.err.println(getThreadName() + ": GetPixelFormat(hdc " + toHexString(hdc) + ") returns " + GDI.GetPixelFormat(hdc)); - } - throw new GLException("Unable to set pixel format " + pixelFormat + " for device context " + toHexString(hdc) + ": error code " + lastError); + pfdID = pixelFormatSet; + pixelFormatCaps = availableCaps[pixelFormatSet-1]; + if (DEBUG) { + System.err.println("updateGraphicsConfigurationGDI: Using preset PFID: " + pixelFormatSet); + System.err.println("!!! preset caps " + pixelFormatCaps); } - pixelFormatSet=true; } - // Reuse the previously-constructed GLCapabilities because it - // turns out that using DescribePixelFormat on some pixel formats - // (which, for example, support full-scene antialiasing) for some - // reason return that they are not OpenGL-capable - if (chosenCaps != null) { - capabilities = chosenCaps; - } else { - capabilities = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, pfd, onscreen, usePBuffer); + if (DEBUG) { + System.err.println("updateGraphicsConfigurationGDI: using pfdID "+pfdID); } - config.setCapsPFD(capabilities, pfd, pixelFormat, choosenBywGLPixelFormat); + + if (GDI.DescribePixelFormat(hdc, pfdID, pfd.size(), pfd) == 0) { + throw new GLException("Error describing the chosen pixel format: " + pfdID + ", " + GDI.GetLastError()); + } + + if (pixelFormatSet <= 0) { + if (!GDI.SetPixelFormat(hdc, pfdID, pfd)) { + long lastError = GDI.GetLastError(); + throw new GLException("Unable to set pixel format " + pfdID + " for device context " + toHexString(hdc) + ": error code " + lastError); + } + } + + config.setCapsPFD(pixelFormatCaps, pfd, pfdID, true); + return true; + } protected static String getThreadName() { diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java index d3f9f378f..b2f493932 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java @@ -99,7 +99,7 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac X11GraphicsScreen x11Screen = (X11GraphicsScreen)absScreen; GLProfile glProfile = GLProfile.getDefault(); - GLCapabilities caps=null; + GLCapabilities availableCaps=null; XVisualInfo xvis=null; long fbcfg = 0; int fbid = -1; @@ -115,13 +115,13 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac long visID = X11Util.DefaultVisualID(display, x11Screen.getIndex()); xvis = X11GLXGraphicsConfiguration.XVisualID2XVisualInfo(display, visID); - caps = X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(glProfile, display, xvis, onscreen, usePBuffer, isMultisampleAvailable); + availableCaps = X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(glProfile, display, xvis, onscreen, usePBuffer, isMultisampleAvailable); - int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(caps, true, isMultisampleAvailable, display, screen); + int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(availableCaps, true, isMultisampleAvailable, display, screen); int[] count = { -1 }; PointerBuffer fbcfgsL = GLX.glXChooseFBConfig(display, screen, attribs, 0, count, 0); if (fbcfgsL == null || fbcfgsL.limit()<1) { - throw new Exception("Could not fetch FBConfig for "+caps); + throw new Exception("Could not fetch FBConfig for "+availableCaps); } fbcfg = fbcfgsL.get(0); capsFB = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glProfile, display, fbcfg, true, onscreen, usePBuffer, isMultisampleAvailable); @@ -135,7 +135,7 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac } catch (Throwable t) { } - return new X11GLXGraphicsConfiguration(x11Screen, (null!=capsFB)?capsFB:caps, caps, null, xvis, fbcfg, fbid); + return new X11GLXGraphicsConfiguration(x11Screen, (null!=capsFB)?capsFB:availableCaps, availableCaps, null, xvis, fbcfg, fbid); } */ protected static X11GLXGraphicsConfiguration chooseGraphicsConfigurationStatic(GLCapabilitiesImmutable capsChosen, @@ -202,12 +202,11 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac GLCapabilitiesImmutable capsReq, GLCapabilitiesChooser chooser, X11GraphicsScreen x11Screen) { - long recommendedFBConfig = 0; + long recommendedFBConfig = -1; int recommendedIndex = -1; - GLCapabilitiesImmutable[] caps = null; - PointerBuffer fbcfgsL = null; - int chosen=-1; int retFBID=-1; + GLCapabilitiesImmutable[] availableCaps = null; + PointerBuffer fbcfgsL = null; XVisualInfo retXVisualInfo = null; GLProfile glProfile = capsChosen.getGLProfile(); boolean onscreen = capsChosen.isOnscreen(); @@ -223,103 +222,118 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capsChosen, true, isMultisampleAvailable, display, screen); int[] count = { -1 }; - // determine the recommended FBConfig .. + // 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice fbcfgsL = GLX.glXChooseFBConfig(display, screen, attribs, 0, count, 0); - if (fbcfgsL == null || fbcfgsL.limit()<1) { - if(DEBUG) { - System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed glXChooseFBConfig ("+x11Screen+","+capsChosen+"): "+fbcfgsL+", "+count[0]); - } - } else if( !X11GLXGraphicsConfiguration.GLXFBConfigValid( display, fbcfgsL.get(0) ) ) { - if(DEBUG) { - System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed - GLX FBConfig invalid: ("+x11Screen+","+capsChosen+"): "+fbcfgsL+", fbcfg: "+toHexString(fbcfgsL.get(0))); + if (fbcfgsL != null && fbcfgsL.limit()>0) { + availableCaps = new GLCapabilitiesImmutable[fbcfgsL.limit()]; + for (int i = 0; i < fbcfgsL.limit(); i++) { + if( !X11GLXGraphicsConfiguration.GLXFBConfigValid( display, fbcfgsL.get(i) ) ) { + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: FBConfig invalid (1): ("+x11Screen+","+capsChosen+"): fbcfg: "+toHexString(fbcfgsL.get(i))); + } + } else { + availableCaps[i] = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glProfile, display, fbcfgsL.get(i), + false, onscreen, usePBuffer, isMultisampleAvailable); + } } - } else { - recommendedFBConfig = fbcfgsL.get(0); - } - - // get all, glXChooseFBConfig(.. attribs==null ..) == glXGetFBConfig(..) - fbcfgsL = GLX.glXChooseFBConfig(display, screen, null, 0, count, 0); - if (fbcfgsL == null || fbcfgsL.limit()<1) { - if(DEBUG) { - System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed glXGetFBConfig ("+x11Screen+"): "+fbcfgsL+", "+count[0]); + if(availableCaps[0]!=null) { + recommendedFBConfig = fbcfgsL.get(0); + recommendedIndex=0; + if (DEBUG) { + System.err.println("!!! glXChooseFBConfig recommended fbcfg " + toHexString(recommendedFBConfig) + ", idx " + recommendedIndex); + System.err.println("!!! user caps " + capsChosen); + System.err.println("!!! fbcfg caps " + availableCaps[recommendedIndex]); + } + } else { + if (DEBUG) { + System.err.println("!!! glXChooseFBConfig no caps for recommended fbcfg " + toHexString(recommendedFBConfig)); + System.err.println("!!! user caps " + capsChosen); + } } - return null; } - // make GLCapabilities and seek the recommendedIndex - caps = new GLCapabilitiesImmutable[fbcfgsL.limit()]; - for (int i = 0; i < fbcfgsL.limit(); i++) { - if( !X11GLXGraphicsConfiguration.GLXFBConfigValid( display, fbcfgsL.get(i) ) ) { + // 2nd choice: get all GLCapabilities available, no preferred recommendedIndex available + if(null == availableCaps) { + fbcfgsL = GLX.glXChooseFBConfig(display, screen, null, 0, count, 0); + if (fbcfgsL == null || fbcfgsL.limit()<=0) { if(DEBUG) { - System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: FBConfig invalid: ("+x11Screen+","+capsChosen+"): fbcfg: "+toHexString(fbcfgsL.get(i))); + System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed glXChooseFBConfig ("+x11Screen+","+capsChosen+"): "+fbcfgsL+", "+count[0]); } - } else { - caps[i] = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glProfile, display, fbcfgsL.get(i), - false, onscreen, usePBuffer, isMultisampleAvailable); - if(caps[i]!=null && recommendedFBConfig==fbcfgsL.get(i)) { - recommendedIndex=i; - if (DEBUG) { - System.err.println("!!! glXChooseFBConfig recommended "+i+", "+caps[i]); + return null; + } + + availableCaps = new GLCapabilitiesImmutable[fbcfgsL.limit()]; + for (int i = 0; i < fbcfgsL.limit(); i++) { + if( !X11GLXGraphicsConfiguration.GLXFBConfigValid( display, fbcfgsL.get(i) ) ) { + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: FBConfig invalid (2): ("+x11Screen+"): fbcfg: "+toHexString(fbcfgsL.get(i))); } + } else { + availableCaps[i] = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glProfile, display, fbcfgsL.get(i), + false, onscreen, usePBuffer, isMultisampleAvailable); } } } - if(null==chooser) { - chosen = recommendedIndex; // may still be -1 in case nothing was recommended (-1) + if( recommendedIndex < 1 && null==chooser) { + chooser = new DefaultGLCapabilitiesChooser(); } - if (chosen < 0) { - if(null==chooser) { - // nothing recommended .. so use our default implementation - chooser = new DefaultGLCapabilitiesChooser(); - } - try { - chosen = chooser.chooseCapabilities(capsChosen, caps, recommendedIndex); - } catch (NativeWindowException e) { - if(DEBUG) { - e.printStackTrace(); - } - chosen = -1; + int chosenIndex = recommendedIndex; + try { + if(null != chooser) { + chosenIndex = chooser.chooseCapabilities(capsChosen, availableCaps, recommendedIndex); + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig chooser: idx "+chosenIndex); + System.err.println("!!! user caps " + capsChosen); + System.err.println("!!! chosen caps " + availableCaps[chosenIndex]); } - } - if (chosen < 0) { - // keep on going .. + } + } catch (NativeWindowException e) { if(DEBUG) { - System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig Failed .. unable to choose config, using first"); + e.printStackTrace(); } + } + + if (chosenIndex < 0) { + // keep on going .. // seek first available one .. - for(chosen = 0; chosen < caps.length && caps[chosen]==null; chosen++) { + for(chosenIndex = 0; chosenIndex < availableCaps.length && availableCaps[chosenIndex]==null; chosenIndex++) { // nop } - if(chosen==caps.length) { + if(chosenIndex==availableCaps.length) { // give up .. if(DEBUG) { System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig Failed .. nothing available, bail out"); } return null; } - } else if (chosen >= caps.length) { + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig Failed .. unable to choose config, using first available idx: "+chosenIndex); + System.err.println("!!! user caps " + capsChosen); + System.err.println("!!! fallback caps " + availableCaps[chosenIndex]); + } + } else if (chosenIndex >= availableCaps.length) { if(DEBUG) { - System.err.println("GLCapabilitiesChooser specified invalid index (expected 0.." + (caps.length - 1) + ", got "+chosen+")"); + System.err.println("GLCapabilitiesChooser specified invalid index (expected 0.." + (availableCaps.length - 1) + ", got "+chosenIndex+")"); } return null; } - retFBID = X11GLXGraphicsConfiguration.glXFBConfig2FBConfigID(display, fbcfgsL.get(chosen)); + retFBID = X11GLXGraphicsConfiguration.glXFBConfig2FBConfigID(display, fbcfgsL.get(chosenIndex)); - retXVisualInfo = GLX.glXGetVisualFromFBConfig(display, fbcfgsL.get(chosen)); + retXVisualInfo = GLX.glXGetVisualFromFBConfig(display, fbcfgsL.get(chosenIndex)); if (retXVisualInfo==null) { if(DEBUG) { - System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed glXGetVisualFromFBConfig ("+x11Screen+", "+fbcfgsL.get(chosen) +" (Continue: "+(false==caps[chosen].isOnscreen())+"):\n\t"+caps[chosen]); + System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed glXGetVisualFromFBConfig ("+x11Screen+", "+fbcfgsL.get(chosenIndex) +" (Continue: "+(false==availableCaps[chosenIndex].isOnscreen())+"):\n\t"+availableCaps[chosenIndex]); } - if(caps[chosen].isOnscreen()) { + if(availableCaps[chosenIndex].isOnscreen()) { // Onscreen drawables shall have a XVisual .. return null; } } - return new X11GLXGraphicsConfiguration(x11Screen, caps[chosen], capsReq, chooser, retXVisualInfo, fbcfgsL.get(chosen), retFBID); + return new X11GLXGraphicsConfiguration(x11Screen, availableCaps[chosenIndex], capsReq, chooser, retXVisualInfo, fbcfgsL.get(chosenIndex), retFBID); } private static X11GLXGraphicsConfiguration chooseGraphicsConfigurationXVisual(GLCapabilitiesImmutable capsChosen, @@ -368,7 +382,7 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac caps = new GLCapabilitiesImmutable[infos.length]; for (int i = 0; i < infos.length; i++) { caps[i] = X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(glProfile, display, infos[i], onscreen, false, isMultisampleAvailable); - // Attempt to find the visual chosen by glXChooseVisual + // Attempt to find the visual chosenIndex by glXChooseVisual if (recommendedVis != null && recommendedVis.getVisualid() == infos[i].getVisualid()) { recommendedIndex = i; } -- cgit v1.2.3