diff options
author | Sven Gothel <[email protected]> | 2010-11-14 09:04:45 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2010-11-14 09:04:45 +0100 |
commit | 83d3a3f2ea8dc328e621b3abbe671f46379c7e65 (patch) | |
tree | b7fafe2ef1610a6be0723316ae5bf5938b9f222d /src/jogl/classes/com/jogamp/opengl/impl/windows/wgl | |
parent | c3bfb82614e9fa0f8ea7169cd412a6f0c71973e0 (diff) |
JOGL: Complete eager and lazy mapping of GLProfiles in respect to multiple device.
AbstractGraphicsDevice's 'connection' and 'type' attribute is used as a unique key
to map GLProfiles and GLContext's major/profile -> major/minor/profile mapping.
Eager initialiaztion as well as lazy is supported to maintain a simple API.
This is currently tested on X11, where one app display NEWT/GL window and content
on the local and remote device.
See TestRemoteWindow01NEWT.java and TestRemoteGLWindows01NEWT.java
Diffstat (limited to 'src/jogl/classes/com/jogamp/opengl/impl/windows/wgl')
4 files changed, 193 insertions, 86 deletions
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 c9a12c85b..7be597dcc 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 @@ -49,12 +49,12 @@ import com.jogamp.gluegen.runtime.ProcAddressTable; import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver; public class WindowsWGLContext extends GLContextImpl { + private static final Map/*<String, String>*/ functionNameMap; + private static final Map/*<String, String>*/ extensionNameMap; private boolean wglGetExtensionsStringEXTInitialized; private boolean wglGetExtensionsStringEXTAvailable; private boolean wglMakeContextCurrentInitialized; private boolean wglMakeContextCurrentAvailable; - private static final Map/*<String, String>*/ functionNameMap; - private static final Map/*<String, String>*/ extensionNameMap; private WGLExt wglExt; // Table that holds the addresses of the native C-language entry points for // WGL extension functions. @@ -80,6 +80,15 @@ public class WindowsWGLContext extends GLContextImpl { GLContext shareWith) { this(drawable, null, shareWith); } + + protected void resetState() { + wglGetExtensionsStringEXTInitialized=false; + wglGetExtensionsStringEXTAvailable=false; + wglMakeContextCurrentInitialized=false; + wglMakeContextCurrentAvailable=false; + // no inner state wglExt=null; + wglExtProcAddressTable=null; + } public Object getPlatformGLExtensions() { return getWGLExt(); @@ -120,17 +129,20 @@ public class WindowsWGLContext extends GLContextImpl { protected Map/*<String, String>*/ getExtensionNameMap() { return extensionNameMap; } protected void destroyContextARBImpl(long context) { - WGL.wglMakeCurrent(0, 0); + wglMakeContextCurrent(0, 0, 0); WGL.wglDeleteContext(context); } protected long createContextARBImpl(long share, boolean direct, int ctp, int major, int minor) { WindowsWGLDrawableFactory factory = (WindowsWGLDrawableFactory)drawable.getFactoryImpl(); + AbstractGraphicsConfiguration config = drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + AbstractGraphicsDevice device = config.getScreen().getDevice(); + WindowsWGLContext sharedContext = (WindowsWGLContext) factory.getOrCreateSharedContextImpl(device); WGLExt wglExt; - if(null==factory.getSharedContext()) { + if(null==sharedContext) { wglExt = getWGLExt(); } else { - wglExt = ((WindowsWGLContext)factory.getSharedContext()).getWGLExt(); + wglExt = sharedContext.getWGLExt(); } boolean ctBwdCompat = 0 != ( CTX_PROFILE_COMPAT & ctp ) ; @@ -171,22 +183,32 @@ public class WindowsWGLContext extends GLContextImpl { } } - ctx = wglExt.wglCreateContextAttribsARB(drawable.getHandle(), share, attribs, 0); - if(DEBUG) { - System.err.println("WindowsWGLContext.createContextARB success: "+(0!=ctx)+" - "+getGLVersion(major, minor, ctp, "@creation")+", bwdCompat "+ctBwdCompat+", fwdCompat "+ctFwdCompat); + try { + ctx = wglExt.wglCreateContextAttribsARB(drawable.getHandle(), share, attribs, 0); + } catch (RuntimeException re) { + if(DEBUG) { + Throwable t = new Throwable("Info: WindowWGLContext.createContextARBImpl wglCreateContextAttribsARB failed with "+getGLVersion(major, minor, ctp, "@creation"), re); + t.printStackTrace(); + } } + if(0!=ctx) { - // In contrast to GLX no verification with a drawable binding, ie default framebuffer, is necessary, - // if no 3.2 is available creation fails already! - // Nevertheless .. we do it .. - if (!WGL.wglMakeCurrent(drawable.getHandle(), ctx)) { + if (!wglMakeContextCurrent(drawable.getHandle(), drawableRead.getHandle(), ctx)) { if(DEBUG) { System.err.println("WindowsWGLContext.createContextARB couldn't make current "+getGLVersion(major, minor, ctp, "@creation")); } WGL.wglMakeCurrent(0, 0); WGL.wglDeleteContext(ctx); ctx = 0; + } else { + if (DEBUG) { + System.err.println(getThreadName() + ": createContextARBImpl: OK "+getGLVersion(major, minor, ctp, "@creation")+", share "+share+", direct "+direct+", hasSharedContext "+(null!=sharedContext)); + } + // the following is issued by the caller 'GLContextImpl.createContextARB()' + // setGLFunctionAvailability(true, major, minor, ctp); } + } else if (DEBUG) { + System.err.println(getThreadName() + ": createContextARBImpl: NO "+getGLVersion(major, minor, ctp, "@creation")); } return ctx; } @@ -197,6 +219,9 @@ public class WindowsWGLContext extends GLContextImpl { */ protected boolean createImpl() { WindowsWGLDrawableFactory factory = (WindowsWGLDrawableFactory)drawable.getFactoryImpl(); + AbstractGraphicsConfiguration config = drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + AbstractGraphicsDevice device = config.getScreen().getDevice(); + WindowsWGLContext sharedContext = (WindowsWGLContext) factory.getOrCreateSharedContextImpl(device); GLCapabilities glCaps = drawable.getChosenGLCapabilities(); // Windows can set up sharing of display lists after creation time @@ -215,7 +240,7 @@ public class WindowsWGLContext extends GLContextImpl { boolean createContextARBTried = false; // utilize the shared context's GLXExt in case it was using the ARB method and it already exists - if( null!=factory.getSharedContext() && factory.getSharedContext().isCreatedWithARBMethod() ) { + if( null!=sharedContext && sharedContext.isCreatedWithARBMethod() ) { contextHandle = createContextARB(share, true, major, minor, ctp); createContextARBTried = true; if (DEBUG && 0!=contextHandle) { @@ -235,16 +260,24 @@ public class WindowsWGLContext extends GLContextImpl { throw new GLException("Error making temp context current: 0x" + toHexString(temp_ctx) + ", werr: 0x"+Integer.toHexString(GDI.GetLastError())); } setGLFunctionAvailability(true, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY); // use GL_VERSION + boolean isCreateContextAttribsARBAvailable = isFunctionAvailable("wglCreateContextAttribsARB"); WGL.wglMakeCurrent(0, 0); // release temp context - if( !createContextARBTried && - isFunctionAvailable("wglCreateContextAttribsARB") && - isExtensionAvailable("WGL_ARB_create_context") ) { - // initial ARB context creation - contextHandle = createContextARB(share, true, major, minor, ctp); - createContextARBTried=true; - if (DEBUG && 0!=contextHandle) { - System.err.println(getThreadName() + ": createImpl: OK (ARB, initial) share "+share); + if( !createContextARBTried) { + if(isCreateContextAttribsARBAvailable && + isExtensionAvailable("WGL_ARB_create_context") ) { + // initial ARB context creation + contextHandle = createContextARB(share, true, major, minor, ctp); + createContextARBTried=true; + if (DEBUG) { + if(0!=contextHandle) { + System.err.println(getThreadName() + ": createContextImpl: OK (ARB, initial) share "+share); + } else { + System.err.println(getThreadName() + ": createContextImpl: NOT OK (ARB, initial) - creation failed - share "+share); + } + } + } else if (DEBUG) { + System.err.println(getThreadName() + ": createContextImpl: NOT OK (ARB, initial) - extension not available - share "+share); } } } @@ -328,7 +361,7 @@ public class WindowsWGLContext extends GLContextImpl { } } - protected void updateGLProcAddressTable(int major, int minor, int ctp) { + protected final void updateGLXProcAddressTable(int major, int minor, int ctp) { if (DEBUG) { System.err.println(getThreadName() + ": !!! Initializing WGL extension address table for " + this); } @@ -337,15 +370,14 @@ public class WindowsWGLContext extends GLContextImpl { wglMakeContextCurrentInitialized=false; wglMakeContextCurrentAvailable=false; - int key = compose8bit(major, minor, ctp, 0); WGLExtProcAddressTable table = null; - synchronized(mappedProcAddressLock) { - table = (WGLExtProcAddressTable) mappedGLXProcAddress.get( key ); + synchronized(mappedContextTypeObjectLock) { + table = (WGLExtProcAddressTable) mappedGLXProcAddress.get( contextFQN ); } if(null != table) { wglExtProcAddressTable = table; if(DEBUG) { - System.err.println(getThreadName() + ": !!! GLContext WGL ProcAddressTable reusing key("+major+","+minor+","+ctp+") -> "+table.hashCode()); + System.err.println(getThreadName() + ": !!! GLContext WGL ProcAddressTable reusing key("+contextFQN+") -> "+table.hashCode()); } } else { if (wglExtProcAddressTable == null) { @@ -354,14 +386,13 @@ public class WindowsWGLContext extends GLContextImpl { wglExtProcAddressTable = new WGLExtProcAddressTable(new GLProcAddressResolver()); } resetProcAddressTable(getWGLExtProcAddressTable()); - synchronized(mappedProcAddressLock) { - mappedGLXProcAddress.put(key, getWGLExtProcAddressTable()); + synchronized(mappedContextTypeObjectLock) { + mappedGLXProcAddress.put(contextFQN, getWGLExtProcAddressTable()); if(DEBUG) { - System.err.println(getThreadName() + ": !!! GLContext WGL ProcAddressTable mapping key("+major+","+minor+","+ctp+") -> "+getWGLExtProcAddressTable().hashCode()); + System.err.println(getThreadName() + ": !!! GLContext WGL ProcAddressTable mapping key("+contextFQN+") -> "+getWGLExtProcAddressTable().hashCode()); } } } - super.updateGLProcAddressTable(major, minor, ctp); } public String getPlatformExtensionsString() { 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 cea176b1f..f8405961f 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 @@ -48,6 +48,7 @@ import com.jogamp.common.JogampRuntimeException; import com.jogamp.common.util.*; import com.jogamp.opengl.impl.*; import com.jogamp.nativewindow.impl.ProxySurface; +import javax.media.nativewindow.windows.WindowsGraphicsDevice; public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { private static final boolean VERBOSE = Debug.verbose(); @@ -86,57 +87,112 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { } catch (JogampRuntimeException jre) { /* n/a .. */ } } - NativeWindowFactory.getDefaultToolkitLock().lock(); // OK - try { - sharedDrawable = new WindowsDummyWGLDrawable(this, null); - WindowsWGLContext ctx = (WindowsWGLContext) sharedDrawable.createContext(null); - ctx.makeCurrent(); - canCreateGLPbuffer = ctx.getGL().isExtensionAvailable("GL_ARB_pbuffer"); - ctx.release(); - sharedContext = ctx; - } catch (Throwable t) { - throw new GLException("WindowsWGLDrawableFactory - Could not initialize shared resources", t); - } finally { - NativeWindowFactory.getDefaultToolkitLock().unlock(); // OK - } - if(null==sharedContext) { - throw new GLException("WindowsWGLDrawableFactory - Shared Context is null"); - } - if (DEBUG) { - System.err.println("!!! SharedContext: "+sharedContext+", pbuffer supported "+canCreateGLPbuffer); - } + /** FIXME: + * find out the Windows semantics of a device connection {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection()} + * to actually use multiple devices. + */ + defaultDevice = new WindowsGraphicsDevice(AbstractGraphicsDevice.DEFAULT_CONNECTION); } - WindowsDummyWGLDrawable sharedDrawable=null; - WindowsWGLContext sharedContext=null; - boolean canCreateGLPbuffer = false; + static class SharedResource { + private WindowsDummyWGLDrawable drawable; + private WindowsWGLContext context; + private boolean canCreateGLPbuffer; + + SharedResource(WindowsDummyWGLDrawable draw, WindowsWGLContext ctx, boolean canPbuffer) { + drawable = draw; + context = ctx; + canCreateGLPbuffer = canPbuffer; + } + } + HashMap/*<connection, SharedResource>*/ sharedMap = new HashMap(); + WindowsGraphicsDevice defaultDevice; + + public final AbstractGraphicsDevice getDefaultDevice() { + return defaultDevice; + } - protected final GLDrawableImpl getSharedDrawable() { - return sharedDrawable; + public final boolean getIsDeviceCompatible(AbstractGraphicsDevice device) { + if(device instanceof WindowsGraphicsDevice) { + return true; + } + return false; } - protected final GLContextImpl getSharedContext() { - return sharedContext; + HashSet devicesTried = new HashSet(); + private final boolean getDeviceTried(String connection) { + synchronized(devicesTried) { + return devicesTried.contains(connection); + } + } + private final void addDeviceTried(String connection) { + synchronized(devicesTried) { + devicesTried.add(connection); + } + } + + protected final GLContext getOrCreateSharedContextImpl(AbstractGraphicsDevice device) { + String connection = device.getConnection(); + SharedResource sr; + synchronized(sharedMap) { + sr = (SharedResource) sharedMap.get(connection); + } + if(null==sr && !getDeviceTried(connection)) { + addDeviceTried(connection); + NativeWindowFactory.getDefaultToolkitLock().lock(); // OK + try { + WindowsDummyWGLDrawable sharedDrawable = new WindowsDummyWGLDrawable(this, null); + WindowsWGLContext ctx = (WindowsWGLContext) sharedDrawable.createContext(null); + ctx.makeCurrent(); + boolean canCreateGLPbuffer = ctx.getGL().isExtensionAvailable("GL_ARB_pbuffer"); + ctx.release(); + sr = new SharedResource(sharedDrawable, ctx, canCreateGLPbuffer); + synchronized(sharedMap) { + sharedMap.put(device.getConnection(), sr); + } + if (DEBUG) { + System.err.println("!!! SharedContext: "+ctx+", pbuffer supported "+canCreateGLPbuffer); + } + + } catch (Throwable t) { + throw new GLException("WindowsWGLDrawableFactory - Could not initialize shared resources", t); + } finally { + NativeWindowFactory.getDefaultToolkitLock().unlock(); // OK + } + } + if(null!=sr) { + return sr.context; + } + return null; } protected void shutdownInstance() { - if (DEBUG) { + if (DEBUG) { + Exception e = new Exception("Debug"); + e.printStackTrace(); + } + Collection/*<SharedResource>*/ sharedResources = sharedMap.values(); + for(Iterator iter=sharedResources.iterator(); iter.hasNext(); ) { + SharedResource sr = (SharedResource) iter.next(); + + if (DEBUG) { System.err.println("!!! Shutdown Shared:"); - System.err.println("!!! CTX : "+sharedContext); - System.err.println("!!! Drawable: "+sharedDrawable); - Exception e = new Exception("Debug"); - e.printStackTrace(); - } - // don't free native resources from this point on, - // since we might be in a critical shutdown hook sequence - if(null!=sharedContext) { - // may cause deadlock: sharedContext.destroy(); // implies release, if current - sharedContext=null; - } - if(null!=sharedDrawable) { - // may cause deadlock: sharedDrawable.destroy(); - sharedDrawable=null; - } + System.err.println("!!! Drawable: "+sr.drawable); + System.err.println("!!! CTX : "+sr.context); + } + + if (null != sr.context) { + // may cause JVM SIGSEGV: sharedContext.destroy(); + sr.context = null; + } + + if (null != sr.drawable) { + // may cause JVM SIGSEGV: sharedDrawable.destroy(); + sr.drawable = null; + } + + } + sharedMap.clear(); } protected GLDrawableImpl createOnscreenDrawableImpl(NativeSurface target) { @@ -154,13 +210,29 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { } public boolean canCreateGLPbuffer(AbstractGraphicsDevice device) { - return canCreateGLPbuffer; + SharedResource sr; + synchronized(sharedMap) { + sr = (SharedResource) sharedMap.get(device.getConnection()); + } + if(null!=sr) { + return sr.canCreateGLPbuffer; + } + return false; } protected GLDrawableImpl createGLPbufferDrawableImpl(final NativeSurface target) { if (target == null) { throw new IllegalArgumentException("Null target"); } + final AbstractGraphicsDevice device = target.getGraphicsConfiguration().getNativeGraphicsConfiguration().getScreen().getDevice(); + + final SharedResource sr; + synchronized(sharedMap) { + sr = (SharedResource) sharedMap.get(device.getConnection()); + } + if(null==sr) { + return null; + } final List returnList = new ArrayList(); Runnable r = new Runnable() { public void run() { @@ -168,16 +240,16 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { if (lastContext != null) { lastContext.release(); } - synchronized(WindowsWGLDrawableFactory.this.sharedContext) { - WindowsWGLDrawableFactory.this.sharedContext.makeCurrent(); + synchronized(sr.context) { + sr.context.makeCurrent(); try { - WGLExt wglExt = WindowsWGLDrawableFactory.this.sharedContext.getWGLExt(); + WGLExt wglExt = sr.context.getWGLExt(); GLDrawableImpl pbufferDrawable = new WindowsPbufferWGLDrawable(WindowsWGLDrawableFactory.this, target, - WindowsWGLDrawableFactory.this.sharedDrawable, + sr.drawable, wglExt); returnList.add(pbufferDrawable); } finally { - WindowsWGLDrawableFactory.this.sharedContext.release(); + sr.context.release(); if (lastContext != null) { lastContext.makeCurrent(); } 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 8744b7a37..619034da4 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 @@ -65,7 +65,7 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio throw new GLException("Invalid pixelformat id "+pfdID); } if(null==glp) { - glp = GLProfile.getDefault(); + glp = GLProfile.getDefault(screen.getDevice()); } PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor(); if (GDI.DescribePixelFormat(hdc, pfdID, pfd.size(), pfd) == 0) { 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 317751725..d34467fb1 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 @@ -98,8 +98,13 @@ public class WindowsWGLGraphicsConfigurationFactory extends GraphicsConfiguratio throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilitiesChooser objects"); } - boolean choosenBywGLPixelFormat = false; 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); + } + boolean choosenBywGLPixelFormat = false; GLCapabilities capabilities = (GLCapabilities) config.getRequestedCapabilities(); boolean onscreen = capabilities.isOnscreen(); boolean usePBuffer = capabilities.isPBuffer(); @@ -138,12 +143,11 @@ public class WindowsWGLGraphicsConfigurationFactory extends GraphicsConfiguratio // 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(factory.sharedContext) { - factory.sharedContext.makeCurrent(); + boolean gotAvailableCaps = false; + synchronized(sharedContext) { + sharedContext.makeCurrent(); try { - WGLExt wglExt = factory.sharedContext.getWGLExt(); - + WGLExt wglExt = sharedContext.getWGLExt(); boolean haveWGLChoosePixelFormatARB = false; if (wglExt != null) { haveWGLChoosePixelFormatARB = wglExt.isExtensionAvailable("WGL_ARB_pixel_format"); @@ -198,7 +202,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GraphicsConfiguratio } } } finally { - factory.sharedContext.release(); + sharedContext.release(); } } // synchronized(factory.sharedContext) |