diff options
author | Sven Gothel <[email protected]> | 2011-03-21 07:13:45 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2011-03-21 07:13:45 +0100 |
commit | ab93183b90e83b9aebc29031c7b88b9a3dc58ff5 (patch) | |
tree | 3b5276e51236137d3c43cb3fba0a5a3eb1658d71 /src/jogl/classes/jogamp/opengl/windows | |
parent | 41fc808eff8d145c37d10a98eb4d8a86bda6f018 (diff) |
Fix Bug #480 (attempt) - ATI + WinXP: make context current for ARB PFD queries/selection
TODO: Validate if bug is actually relates to the 'old' ATI Windows driver for old GPU's like X300 etc
and unrelated to the actual Windows version !
Also ensure that the no pixelformat is being set on external context/HDC.
Diffstat (limited to 'src/jogl/classes/jogamp/opengl/windows')
5 files changed, 169 insertions, 57 deletions
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java index 0e2575bd9..632b373af 100644 --- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java +++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java @@ -92,11 +92,12 @@ public class WindowsExternalWGLContext extends WindowsWGLContext { // Workaround: Use a fake default configuration final int werr = GDI.GetLastError(); cfg = WindowsWGLGraphicsConfigurationFactory.createDefaultGraphicsConfiguration(new GLCapabilities(GLProfile.getDefault()), aScreen); + cfg.markExternal(); if(DEBUG) { System.err.println("WindowsExternalWGLContext invalid hdc/pfd werr "+werr+", using default cfg: " + cfg); } } else { - cfg = WindowsWGLGraphicsConfiguration.createFromCurrent(factory, hdc, pfdID, glp, aScreen, true); + cfg = WindowsWGLGraphicsConfiguration.createFromExternal(factory, hdc, pfdID, glp, aScreen, true); if(DEBUG) { System.err.println("WindowsExternalWGLContext valid hdc/pfd, retrieved cfg: " + cfg); } diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLDrawable.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLDrawable.java index 7666ae350..ede504735 100644 --- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLDrawable.java +++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLDrawable.java @@ -69,7 +69,7 @@ public class WindowsExternalWGLDrawable extends WindowsWGLDrawable { } AbstractGraphicsScreen aScreen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_WINDOWS); - WindowsWGLGraphicsConfiguration cfg = WindowsWGLGraphicsConfiguration.createFromCurrent(factory, hdc, pfdID, glp, aScreen, true); + WindowsWGLGraphicsConfiguration cfg = WindowsWGLGraphicsConfiguration.createFromExternal(factory, hdc, pfdID, glp, aScreen, true); return new WindowsExternalWGLDrawable(factory, new WrappedSurface(cfg, hdc)); } diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java index c5e1eac0b..248dfa482 100644 --- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java +++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java @@ -55,6 +55,7 @@ import javax.media.nativewindow.ProxySurface; import javax.media.nativewindow.NativeWindowFactory; import javax.media.nativewindow.windows.WindowsGraphicsDevice; import javax.media.nativewindow.AbstractGraphicsConfiguration; +import javax.media.opengl.GL; import javax.media.opengl.GLCapabilitiesImmutable; import javax.media.opengl.GLCapabilitiesChooser; import javax.media.opengl.GLContext; @@ -64,7 +65,10 @@ import javax.media.opengl.GLProfile; import com.jogamp.common.JogampRuntimeException; import com.jogamp.common.nio.PointerBuffer; +import com.jogamp.common.os.Platform; import com.jogamp.common.util.ReflectionUtil; +import com.jogamp.common.util.VersionNumber; + import jogamp.nativewindow.WrappedSurface; import jogamp.nativewindow.windows.GDI; import jogamp.nativewindow.windows.GDISurface; @@ -163,6 +167,12 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { } } + /** + * http://msdn.microsoft.com/en-us/library/ms724832%28v=vs.85%29.aspx + * Windows XP 5.1 + */ + static final VersionNumber winXPVersionNumber = new VersionNumber ( 5, 1, 0); + static class SharedResource implements SharedResourceRunner.Resource { private WindowsGraphicsDevice device; private AbstractGraphicsScreen screen; @@ -172,9 +182,13 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { private boolean hasARBMultisample; private boolean hasARBPBuffer; private boolean hasARBReadDrawable; + private String vendor; + private boolean isVendorATI; + private boolean isVendorNVIDIA; + private boolean needsCurrenContext4ARBPFDQueries; SharedResource(WindowsGraphicsDevice dev, AbstractGraphicsScreen scrn, WindowsDummyWGLDrawable draw, WindowsWGLContext ctx, - boolean arbPixelFormat, boolean arbMultisample, boolean arbPBuffer, boolean arbReadDrawable) { + boolean arbPixelFormat, boolean arbMultisample, boolean arbPBuffer, boolean arbReadDrawable, String glVendor) { device = dev; screen = scrn; drawable = draw; @@ -183,7 +197,27 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { hasARBMultisample = arbMultisample; hasARBPBuffer = arbPBuffer; hasARBReadDrawable = arbReadDrawable; + vendor = glVendor; + if(null != vendor) { + isVendorNVIDIA = vendor.startsWith("NVIDIA") ; + isVendorATI = vendor.startsWith("ATI") ; + } + + if ( isVendorATI() ) { + final VersionNumber winVersion = new VersionNumber(Platform.getOSVersion(), "."); + final boolean isWinXPOrLess = winVersion.compareTo(winXPVersionNumber) <= 0; + if(DEBUG) { + System.err.println("needsCurrenContext4ARBPFDQueries: "+winVersion+" <= "+winXPVersionNumber+" = "+isWinXPOrLess+" - "+Platform.getOSVersion()); + } + needsCurrenContext4ARBPFDQueries = isWinXPOrLess; + } else { + if(DEBUG) { + System.err.println("needsCurrenContext4ARBPFDQueries: false"); + } + needsCurrenContext4ARBPFDQueries = false; + } } + final public AbstractGraphicsDevice getDevice() { return device; } final public AbstractGraphicsScreen getScreen() { return screen; } final public WindowsWGLDrawable getDrawable() { return drawable; } @@ -193,6 +227,20 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { final boolean hasARBMultisample() { return hasARBMultisample; } final boolean hasARBPBuffer() { return hasARBPBuffer; } final boolean hasReadDrawable() { return hasARBReadDrawable; } + + final String vendor() { return vendor; } + final boolean isVendorATI() { return isVendorATI; } + final boolean isVendorNVIDIA() { return isVendorNVIDIA; } + + /** + * Solves bug #480 + * + * TODO: Validate if bug is actually relates to the 'old' ATI Windows driver for old GPU's like X300 etc + * and unrelated to the actual Windows version ! + * + * @return true if GL_VENDOR is ATI _and_ platform is Windows version XP or less! + */ + final boolean needsCurrentContext4ARBPFDQueries() { return needsCurrenContext4ARBPFDQueries; } } class SharedResourceImplementation implements SharedResourceRunner.Implementation { @@ -244,6 +292,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { boolean hasARBMultisample; boolean hasARBPBuffer; boolean hasARBReadDrawableAvailable; + String vendor; sharedContext.makeCurrent(); try { hasARBPixelFormat = sharedContext.isExtensionAvailable(WGL_ARB_pixel_format); @@ -251,6 +300,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { hasARBPBuffer = sharedContext.isExtensionAvailable(GL_ARB_pbuffer); hasARBReadDrawableAvailable = sharedContext.isExtensionAvailable(WGL_ARB_make_current_read) && sharedContext.isFunctionAvailable(wglMakeContextCurrent); + vendor = sharedContext.getGL().glGetString(GL.GL_VENDOR); } finally { sharedContext.release(); } @@ -262,10 +312,11 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { System.err.println("!!! multisample: " + hasARBMultisample); System.err.println("!!! pbuffer: " + hasARBPBuffer); System.err.println("!!! readDrawable: " + hasARBReadDrawableAvailable); + System.err.println("!!! vendor: " + vendor); } return new SharedResource(sharedDevice, absScreen, sharedDrawable, sharedContext, hasARBPixelFormat, hasARBMultisample, - hasARBPBuffer, hasARBReadDrawableAvailable); + hasARBPBuffer, hasARBReadDrawableAvailable, vendor); } catch (Throwable t) { throw new GLException("WindowsWGLDrawableFactory - Could not initialize shared resources for "+connection, t); } finally { diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java index c500135f6..1899f5212 100644 --- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java +++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java @@ -60,14 +60,15 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio protected static final int MAX_ATTRIBS = 256; private GLCapabilitiesChooser chooser; - private boolean isChosen = false; + private boolean isDetermined = false; + private boolean isExternal = false; WindowsWGLGraphicsConfiguration(AbstractGraphicsScreen screen, GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser) { super(screen, capsChosen, capsRequested); this.chooser=chooser; - this.isChosen = false; + this.isDetermined = false; } WindowsWGLGraphicsConfiguration(AbstractGraphicsScreen screen, @@ -78,7 +79,7 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio } - static WindowsWGLGraphicsConfiguration createFromCurrent(GLDrawableFactory _factory, long hdc, int pfdID, + static WindowsWGLGraphicsConfiguration createFromExternal(GLDrawableFactory _factory, long hdc, int pfdID, GLProfile glp, AbstractGraphicsScreen screen, boolean onscreen) { if(_factory==null) { @@ -110,7 +111,9 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio ", pfdID "+pfdID+", onscreen "+onscreen+", hasARB "+hasARB); } - return new WindowsWGLGraphicsConfiguration(screen, caps, caps); + WindowsWGLGraphicsConfiguration cfg = new WindowsWGLGraphicsConfiguration(screen, caps, caps); + cfg.markExternal(); + return cfg; } public Object clone() { @@ -127,6 +130,7 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio * @param pfIDs optional pool of preselected PixelFormat IDs, maybe null for unrestricted selection * * @see #isDetermined() + * @see #isExternal() */ public final void updateGraphicsConfiguration(GLDrawableFactory factory, NativeSurface ns, int[] pfIDs) { WindowsWGLGraphicsConfigurationFactory.updateGraphicsConfiguration(chooser, factory, ns, pfIDs); @@ -147,18 +151,58 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio WindowsWGLGraphicsConfigurationFactory.preselectGraphicsConfiguration(chooser, factory, device, this, pfdIDs); } + /** + * Sets the hdc's PixelFormat, this configuration's capabilities and marks it as determined. + */ + final void setPixelFormat(long hdc, WGLGLCapabilities caps) { + if (0 == hdc) { + throw new GLException("Error: HDC is null"); + } + + if (!GDI.SetPixelFormat(hdc, caps.getPFDID(), caps.getPFD())) { + throw new GLException("Unable to set pixel format " + caps + + " for device context " + toHexString(hdc) + + ": error code " + GDI.GetLastError()); + } + if (DEBUG) { + System.err.println("!!! setPixelFormat (ARB): hdc "+toHexString(hdc) +", "+caps); + } + setCapsPFD(caps); + } + + /** + * Only sets this configuration's capabilities and marks it as determined, + * the actual pixelformat is not set. + */ final void setCapsPFD(WGLGLCapabilities caps) { setChosenCapabilities(caps); - this.isChosen=true; + this.isDetermined = true; if (DEBUG) { System.err.println("*** setCapsPFD: "+caps); } } - public final boolean isDetermined() { return isChosen; } - public final PIXELFORMATDESCRIPTOR getPixelFormat() { return isChosen ? ((WGLGLCapabilities)capabilitiesChosen).getPFD() : null; } - public final int getPixelFormatID() { return isChosen ? ((WGLGLCapabilities)capabilitiesChosen).getPFDID() : 0; } - public final boolean isChoosenByARB() { return isChosen ? ((WGLGLCapabilities)capabilitiesChosen).isSetByARB() : false; } + /** + * External configuration's HDC pixelformat shall not be modified + */ + public final boolean isExternal() { return isExternal; } + + final void markExternal() { + this.isExternal=true; + } + + /** + * Determined configuration states set target capabilties via {@link #setCapsPFD(WGLGLCapabilities)}, + * but does not imply a set pixelformat. + * + * @see #setPixelFormat(long, WGLGLCapabilities) + * @see #setCapsPFD(WGLGLCapabilities) + */ + public final boolean isDetermined() { return isDetermined; } + + public final PIXELFORMATDESCRIPTOR getPixelFormat() { return isDetermined ? ((WGLGLCapabilities)capabilitiesChosen).getPFD() : null; } + public final int getPixelFormatID() { return isDetermined ? ((WGLGLCapabilities)capabilitiesChosen).getPFDID() : 0; } + public final boolean isChoosenByARB() { return isDetermined ? ((WGLGLCapabilities)capabilitiesChosen).isSetByARB() : false; } static int fillAttribsForGeneralWGLARBQuery(WindowsWGLDrawableFactory.SharedResource sharedResource, int[] iattributes) { int niattribs = 0; diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java index f74c2e90d..8c1f5e87c 100644 --- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java +++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java @@ -44,6 +44,7 @@ import javax.media.nativewindow.NativeSurface; import javax.media.nativewindow.NativeWindowFactory; import javax.media.opengl.GLCapabilitiesImmutable; import javax.media.opengl.GLCapabilitiesChooser; +import javax.media.opengl.GLContext; import javax.media.opengl.GLDrawableFactory; import javax.media.opengl.GLException; import javax.media.opengl.GLProfile; @@ -111,9 +112,16 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat } WindowsWGLDrawable sharedDrawable = sharedResource.getDrawable(); GLCapabilitiesImmutable capsChosen = sharedDrawable.getChosenGLCapabilities(); + WindowsWGLContext sharedContext = sharedResource.getContext(); List availableCaps = null; - - sharedDrawable.lockSurface(); + + if ( sharedResource.needsCurrentContext4ARBPFDQueries() ) { + if(GLContext.CONTEXT_NOT_CURRENT == sharedContext.makeCurrent()) { + throw new GLException("Could not make Shared Context current: "+device); + } + } else { + sharedDrawable.lockSurface(); + } try { long hdc = sharedDrawable.getHandle(); if (0 == hdc) { @@ -126,7 +134,11 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat availableCaps = getAvailableGLCapabilitiesGDI(hdc, capsChosen.getGLProfile()); } } finally { - sharedDrawable.unlockSurface(); + if ( sharedResource.needsCurrentContext4ARBPFDQueries() ) { + sharedContext.release(); + } else { + sharedDrawable.unlockSurface(); + } } if( null != availableCaps && availableCaps.size() > 1 ) { @@ -179,25 +191,26 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat } WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration) ns.getGraphicsConfiguration().getNativeGraphicsConfiguration(); - if(!config.isDetermined()) { - updateGraphicsConfiguration(config, chooser, factory, hdc, false, pfdIDs); - } else { - // set PFD if not set yet - int pfdID = -1; - boolean set = false; - if ( 1 > ( pfdID = GDI.GetPixelFormat(hdc) ) ) { - if (!GDI.SetPixelFormat(hdc, config.getPixelFormatID(), config.getPixelFormat())) { - throw new GLException("Unable to set pixel format " + config.getPixelFormatID() + - " for device context " + toHexString(hdc) + - ": error code " + GDI.GetLastError()); - } - set = true; - pfdID = config.getPixelFormatID(); - } - if (DEBUG) { - System.err.println("!!! setPixelFormat (post): hdc "+toHexString(hdc) +", "+config.getPixelFormatID()+" -> "+pfdID+", set: "+set); - Thread.dumpStack(); - } + if( !config.isExternal() ) { + if( !config.isDetermined() ) { + updateGraphicsConfiguration(config, chooser, factory, hdc, false, pfdIDs); + } else { + // set PFD if not set yet + int pfdID = -1; + boolean set = false; + if ( 1 > ( pfdID = GDI.GetPixelFormat(hdc) ) ) { + if (!GDI.SetPixelFormat(hdc, config.getPixelFormatID(), config.getPixelFormat())) { + throw new GLException("Unable to set pixel format " + config.getPixelFormatID() + + " for device context " + toHexString(hdc) + + ": error code " + GDI.GetLastError()); + } + set = true; + } + if (DEBUG) { + System.err.println("!!! setPixelFormat (post): hdc "+toHexString(hdc) +", "+pfdID+" -> "+config.getPixelFormatID()+", set: "+set); + Thread.dumpStack(); + } + } } } finally { ns.unlockSurface(); @@ -246,8 +259,23 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat } System.err.println("!!! user chosen caps " + config.getChosenCapabilities()); } - if( !updateGraphicsConfigurationARB(hdc, extHDC, config, chooser, (WindowsWGLDrawableFactory)factory, pfdIDs) ) { - updateGraphicsConfigurationGDI(hdc, extHDC, config, chooser, pfdIDs); + AbstractGraphicsDevice device = config.getScreen().getDevice(); + WindowsWGLDrawableFactory.SharedResource sharedResource = ((WindowsWGLDrawableFactory)factory).getOrCreateSharedResource(device); + WindowsWGLContext sharedContext = null; + if (null != sharedResource && sharedResource.needsCurrentContext4ARBPFDQueries()) { + sharedContext = sharedResource.getContext(); + if(GLContext.CONTEXT_NOT_CURRENT == sharedContext.makeCurrent()) { + throw new GLException("Could not make Shared Context current: "+device); + } + } + try { + if( !updateGraphicsConfigurationARB(hdc, extHDC, config, chooser, (WindowsWGLDrawableFactory)factory, pfdIDs) ) { + updateGraphicsConfigurationGDI(hdc, extHDC, config, chooser, pfdIDs); + } + } finally { + if (null != sharedContext) { + sharedContext.release(); + } } } @@ -372,16 +400,10 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat } if ( !extHDC && !pixelFormatSet ) { - if (!GDI.SetPixelFormat(hdc, pixelFormatCaps.getPFDID(), pixelFormatCaps.getPFD())) { - throw new GLException("Unable to set pixel format " + pixelFormatCaps.getPFDID() + - " for device context " + toHexString(hdc) + - ": error code " + GDI.GetLastError()); - } - if (DEBUG) { - System.err.println("!!! setPixelFormat (ARB): hdc "+toHexString(hdc) +", "+config.getPixelFormatID()+" -> "+pixelFormatCaps.getPFDID()); - } + config.setPixelFormat(hdc, pixelFormatCaps); + } else { + config.setCapsPFD(pixelFormatCaps); } - config.setCapsPFD(pixelFormatCaps); return true; } @@ -397,7 +419,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat boolean onscreen = capsChosen.isOnscreen(); GLProfile glProfile = capsChosen.getGLProfile(); - ArrayList/*<WGLGLCapabilities>*/ availableCaps = new ArrayList(); + ArrayList<WGLGLCapabilities> availableCaps = new ArrayList<WGLGLCapabilities>(); int pfdID; // chosen or preset PFD ID WGLGLCapabilities pixelFormatCaps = null; // chosen or preset PFD ID's caps boolean pixelFormatSet = false; // indicates a preset PFD ID [caps] @@ -446,7 +468,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat } return false; } - pixelFormatCaps = (WGLGLCapabilities) availableCaps.get(chosenIndex); + pixelFormatCaps = availableCaps.get(chosenIndex); if (DEBUG) { System.err.println("!!! chosen pfdID (GDI): native recommended "+ (recommendedIndex+1) + ", caps " + pixelFormatCaps); @@ -454,16 +476,10 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat } if ( !extHDC && !pixelFormatSet ) { - if (!GDI.SetPixelFormat(hdc, pixelFormatCaps.getPFDID(), pixelFormatCaps.getPFD())) { - throw new GLException("Unable to set pixel format " + pixelFormatCaps.getPFDID() + - " for device context " + toHexString(hdc) + - ": error code " + GDI.GetLastError()); - } - if (DEBUG) { - System.err.println("!!! setPixelFormat (GDI): hdc "+toHexString(hdc) +", "+config.getPixelFormatID()+" -> " + pixelFormatCaps.getPFDID()); - } + config.setPixelFormat(hdc, pixelFormatCaps); + } else { + config.setCapsPFD(pixelFormatCaps); } - config.setCapsPFD(pixelFormatCaps); return true; } } |