diff options
author | Sven Gothel <[email protected]> | 2010-12-10 05:24:32 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2010-12-10 05:24:32 +0100 |
commit | 0a6a592c04a85d8124aa9d38b67f0caa1d739b75 (patch) | |
tree | 73f40c3dae6b1c25e8afc8f84259fa52de4dfa1e /src | |
parent | 7753e1c5a50700771b1e0be4bc99c2585398e3ce (diff) |
Cleanup GLGraphicsConfiguration[Factory] implementations (X11/WGL)
- AWT/WGL:
- Using sun.awt.Win32GraphicsConfig via reflection, if supported, else we may fail.
- Preselection of PFD as follows:
- 1st choice is to create our own AWT GraphicsConfig (GC) based on PFD/GLCaps,
ignoring WGL_SUPPORT_GDI_ARB, PFD_SUPPORT_GDI
- 2nd choice is to use AWT PFD pool of GC's
- else we fail -> use NewtCanvasAWT instead (TODO: Other JDK/AWT implementations ?)
- Set PFD will be performed at setRealized(..)
- SharedContext (X11/WGL) is synchronized to allow multithreaded access, if required
- Simplified and unified (X11/WGL) GraphicsConfigurationFactory
- WGL 'external' drawables will be determined with given arguments right away
Diffstat (limited to 'src')
20 files changed, 717 insertions, 465 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableImpl.java index d7d2836aa..5459d886c 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableImpl.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableImpl.java @@ -146,7 +146,7 @@ public abstract class GLDrawableImpl implements GLDrawable { AbstractGraphicsDevice aDevice = surface.getGraphicsConfiguration().getScreen().getDevice(); if(realizedArg) { if(NativeSurface.LOCK_SURFACE_NOT_READY >= lockSurface()) { - throw new GLException("X11GLXDrawable.setRealized(true): already realized, but surface not ready (lockSurface)"); + throw new GLException("GLDrawableImpl.setRealized(true): already realized, but surface not ready (lockSurface)"); } } else { aDevice.lock(); diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLGraphicsConfigurationFactoryImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLGraphicsConfigurationFactoryImpl.java new file mode 100644 index 000000000..4dae603c7 --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/impl/GLGraphicsConfigurationFactoryImpl.java @@ -0,0 +1,86 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.opengl.impl; + +import javax.media.nativewindow.CapabilitiesChooser; +import javax.media.nativewindow.CapabilitiesImmutable; +import javax.media.nativewindow.GraphicsConfigurationFactory; +import javax.media.nativewindow.NativeWindowException; +import javax.media.opengl.DefaultGLCapabilitiesChooser; + +public abstract class GLGraphicsConfigurationFactoryImpl extends GraphicsConfigurationFactory { + + protected static int chooseCapabilities(CapabilitiesChooser chooser, + CapabilitiesImmutable capsRequested, CapabilitiesImmutable[] availableCaps, int recommendedIndex) { + if(null == chooser && 0 <= recommendedIndex) { + if (DEBUG) { + System.err.println("chooseCapabilities: Using recommendedIndex: idx " + recommendedIndex); + } + return recommendedIndex; + } + int chosenIndex = recommendedIndex; + + if (null == chooser) { + chooser = new DefaultGLCapabilitiesChooser(); + } + + try { + chosenIndex = chooser.chooseCapabilities(capsRequested, availableCaps, recommendedIndex); + if(0 <= chosenIndex) { + if (DEBUG) { + System.err.println("chooseCapabilities: Chosen idx " + chosenIndex); + } + return chosenIndex; + } + } catch (NativeWindowException e) { + if (DEBUG) { + e.printStackTrace(); + } + } + + // 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("chooseCapabilities: Failed .. nothing available, bail out"); + } + return -1; + } + if (DEBUG) { + System.err.println("chooseCapabilities: Fall back to 1st available idx " + chosenIndex); + } + + return chosenIndex; + } + +} diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfigurationFactory.java index fc2416cb9..ff6e025a8 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfigurationFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfigurationFactory.java @@ -52,6 +52,7 @@ import javax.media.opengl.GLException; import javax.media.opengl.GLProfile; import com.jogamp.common.nio.PointerBuffer; +import com.jogamp.opengl.impl.GLGraphicsConfigurationFactoryImpl; /** Subclass of GraphicsConfigurationFactory used when non-AWT tookits @@ -59,7 +60,7 @@ import com.jogamp.common.nio.PointerBuffer; to this one to change the accepted and returned types of the GraphicsDevice and GraphicsConfiguration abstractions. */ -public class EGLGraphicsConfigurationFactory extends GraphicsConfigurationFactory { +public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactoryImpl { protected static final boolean DEBUG = GraphicsConfigurationFactory.DEBUG || com.jogamp.opengl.impl.Debug.debug("EGL"); EGLGraphicsConfigurationFactory() { diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java index 5d7a0375b..f12f5d31a 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java @@ -33,6 +33,7 @@ package com.jogamp.opengl.impl.macosx.cgl; +import com.jogamp.opengl.impl.GLGraphicsConfigurationFactoryImpl; import javax.media.nativewindow.AbstractGraphicsConfiguration; import javax.media.nativewindow.AbstractGraphicsScreen; import javax.media.nativewindow.CapabilitiesChooser; @@ -47,7 +48,7 @@ import javax.media.opengl.GLCapabilitiesImmutable; to this one to change the accepted and returned types of the GraphicsDevice and GraphicsConfiguration abstractions. */ -public class MacOSXCGLGraphicsConfigurationFactory extends GraphicsConfigurationFactory { +public class MacOSXCGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactoryImpl { protected static final boolean DEBUG = com.jogamp.opengl.impl.Debug.debug("GraphicsConfiguration"); MacOSXCGLGraphicsConfigurationFactory() { diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLGraphicsConfigurationFactory.java index 702d66fce..e4249f9c8 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLGraphicsConfigurationFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLGraphicsConfigurationFactory.java @@ -33,6 +33,7 @@ package com.jogamp.opengl.impl.macosx.cgl.awt; +import com.jogamp.opengl.impl.GLGraphicsConfigurationFactoryImpl; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; @@ -54,7 +55,7 @@ import javax.media.opengl.GLException; import com.jogamp.opengl.impl.macosx.cgl.MacOSXCGLGraphicsConfiguration; -public class MacOSXAWTCGLGraphicsConfigurationFactory extends GraphicsConfigurationFactory { +public class MacOSXAWTCGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactoryImpl { protected static final boolean DEBUG = com.jogamp.opengl.impl.Debug.debug("GraphicsConfiguration"); public MacOSXAWTCGLGraphicsConfigurationFactory() { diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsBitmapWGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsBitmapWGLDrawable.java index 0d360b339..8780af7b3 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsBitmapWGLDrawable.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsBitmapWGLDrawable.java @@ -120,7 +120,7 @@ public class WindowsBitmapWGLDrawable extends WindowsWGLDrawable { hdc = 0; throw new GLException("Error selecting bitmap into new device context"); } - config.updateGraphicsConfiguration(getFactory(), ns); + config.updateGraphicsConfiguration(getFactory(), ns, null); } protected void destroyImpl() { 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 fd70842ac..d8d410d39 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,9 +66,6 @@ public class WindowsExternalWGLContext extends WindowsWGLContext { } GLContextShareSet.contextCreated(this); setGLFunctionAvailability(false, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY); - 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 } @@ -87,12 +84,8 @@ public class WindowsExternalWGLContext extends WindowsWGLContext { } AbstractGraphicsScreen aScreen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_WINDOWS); - WindowsWGLGraphicsConfiguration cfg = WindowsWGLGraphicsConfiguration.create(hdc, pfdID, glp, aScreen, true, true); - - ProxySurface ns = new ProxySurface(cfg); - ns.setSurfaceHandle(hdc); - - return new WindowsExternalWGLContext(new Drawable(factory, ns), ctx, cfg); + WindowsWGLGraphicsConfiguration cfg = WindowsWGLGraphicsConfiguration.create(factory, hdc, pfdID, glp, aScreen, true, true); + return new WindowsExternalWGLContext(new Drawable(factory, new ProxySurface(cfg, hdc)), ctx, cfg); } public int makeCurrent() throws GLException { diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLDrawable.java index 66a5c80a4..f3329b73b 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLDrawable.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLDrawable.java @@ -69,14 +69,8 @@ public class WindowsExternalWGLDrawable extends WindowsWGLDrawable { } AbstractGraphicsScreen aScreen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_WINDOWS); - WindowsWGLGraphicsConfiguration cfg = WindowsWGLGraphicsConfiguration.create(hdc, pfdID, glp, aScreen, true, true); - - ProxySurface ns = new ProxySurface(cfg); - ns.setSurfaceHandle(hdc); - - cfg.updateGraphicsConfiguration(factory, ns); - - return new WindowsExternalWGLDrawable(factory, ns); + WindowsWGLGraphicsConfiguration cfg = WindowsWGLGraphicsConfiguration.create(factory, hdc, pfdID, glp, aScreen, true, true); + return new WindowsExternalWGLDrawable(factory, new ProxySurface(cfg, hdc)); } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawable.java index a98366f58..83b52fbcb 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawable.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawable.java @@ -68,7 +68,7 @@ public abstract class WindowsWGLDrawable extends GLDrawableImpl { NativeSurface ns = getNativeSurface(); WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration)ns.getGraphicsConfiguration().getNativeGraphicsConfiguration(); - config.updateGraphicsConfiguration(getFactory(), ns); + config.updateGraphicsConfiguration(getFactory(), ns, null); if (DEBUG) { System.err.println("!!! WindowsWGLDrawable.setRealized(true): "+config); } 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 903e1af81..84636f539 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 @@ -126,6 +126,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { readDrawableAvailable = readBufferAvail; } WindowsGraphicsDevice getDevice() { return device; } + WindowsWGLDrawable getDrawable() { return drawable; } WindowsWGLContext getContext() { return context; } boolean canCreateGLPbuffer() { return canCreateGLPbuffer; } boolean isReadDrawableAvailable() { return readDrawableAvailable; } @@ -176,20 +177,20 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { AbstractGraphicsScreen absScreen = new DefaultGraphicsScreen(sharedDevice, 0); WindowsDummyWGLDrawable sharedDrawable = WindowsDummyWGLDrawable.create(this, glp, absScreen); WindowsWGLContext ctx = (WindowsWGLContext) sharedDrawable.createContext(null); + ctx.setSynchronized(true); ctx.makeCurrent(); boolean canCreateGLPbuffer = ctx.getGL().isExtensionAvailable(GL_ARB_pbuffer); boolean readDrawableAvailable = ctx.isExtensionAvailable(WGL_ARB_make_current_read) && - ctx.isFunctionAvailable(wglMakeContextCurrent); + ctx.isFunctionAvailable(wglMakeContextCurrent); + if (DEBUG) { + System.err.println("!!! SharedContext: "+ctx+", pbuffer supported "+canCreateGLPbuffer+ + ", readDrawable supported "+readDrawableAvailable); + } ctx.release(); sr = new SharedResource(sharedDevice, sharedDrawable, ctx, readDrawableAvailable, canCreateGLPbuffer); synchronized(sharedMap) { sharedMap.put(connection, sr); } - if (DEBUG) { - System.err.println("!!! SharedContext: "+ctx+", pbuffer supported "+canCreateGLPbuffer+ - ", readDrawable supported "+readDrawableAvailable); - } - } catch (Throwable t) { throw new GLException("WindowsWGLDrawableFactory - Could not initialize shared resources", t); } finally { @@ -215,6 +216,14 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { return null; } + protected WindowsWGLDrawable getSharedDrawable(AbstractGraphicsDevice device) { + SharedResource sr = getOrCreateShared(device); + if(null!=sr) { + return sr.getDrawable(); + } + return null; + } + protected final void shutdownInstance() { if (DEBUG) { Exception e = new Exception("Debug"); 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 aa1b1b70d..3db69be50 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 @@ -36,7 +36,6 @@ package com.jogamp.opengl.impl.windows.wgl; import javax.media.nativewindow.AbstractGraphicsScreen; import javax.media.nativewindow.DefaultGraphicsConfiguration; import javax.media.nativewindow.NativeSurface; -import javax.media.opengl.DefaultGLCapabilitiesChooser; import javax.media.opengl.GL; import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLCapabilitiesChooser; @@ -48,80 +47,141 @@ 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.nativewindow.AbstractGraphicsDevice; import javax.media.opengl.GLCapabilitiesImmutable; public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguration implements Cloneable { // Keep this under the same debug flag as the drawable factory for convenience protected static final boolean DEBUG = com.jogamp.opengl.impl.Debug.debug("GraphicsConfiguration"); + final static String WGL_ARB_pixel_format = "WGL_ARB_pixel_format"; + final static String WGL_ARB_multisample = "WGL_ARB_multisample"; + protected static final int MAX_PFORMATS = 256; protected static final int MAX_ATTRIBS = 256; private PIXELFORMATDESCRIPTOR pixelfmt; private int pixelfmtID; - private boolean isChosen = false; private GLCapabilitiesChooser chooser; - private boolean choosenByWGLPixelFormat=false; + private boolean isChosen = false; + private boolean choosenByARBPixelFormat=false; WindowsWGLGraphicsConfiguration(AbstractGraphicsScreen screen, GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, - PIXELFORMATDESCRIPTOR pixelfmt, int pixelfmtID, GLCapabilitiesChooser chooser) { + GLCapabilitiesChooser chooser) { super(screen, capsChosen, capsRequested); + this.pixelfmt = null; + this.pixelfmtID = -1; this.chooser=chooser; - this.pixelfmt = pixelfmt; - this.pixelfmtID = pixelfmtID; + isChosen = false; + choosenByARBPixelFormat=false; + } + + WindowsWGLGraphicsConfiguration(AbstractGraphicsScreen screen, + GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, + PIXELFORMATDESCRIPTOR pixelfmt, int pixelfmtID, boolean choosenByARBPixelFormat) { + super(screen, capsChosen, capsRequested); + setCapsPFD(capsChosen, pixelfmt, pixelfmtID, choosenByARBPixelFormat); + this.chooser=null; } - static WindowsWGLGraphicsConfiguration create(long hdc, int pfdID, + + static WindowsWGLGraphicsConfiguration create(GLDrawableFactory _factory, long hdc, int pfdID, GLProfile glp, AbstractGraphicsScreen screen, boolean onscreen, boolean usePBuffer) { + if(_factory==null) { + throw new GLException("Null factory"); + } + if(hdc==0) { + throw new GLException("Null HDC"); + } if(pfdID<=0) { throw new GLException("Invalid pixelformat id "+pfdID); } if(null==glp) { glp = GLProfile.getDefault(screen.getDevice()); } - PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor(); - if (GDI.DescribePixelFormat(hdc, pfdID, pfd.size(), pfd) == 0) { - throw new GLException("Unable to describe pixel format " + pfdID); + WindowsWGLDrawableFactory factory = (WindowsWGLDrawableFactory) _factory; + AbstractGraphicsDevice device = screen.getDevice(); + WindowsWGLContext sharedContext = (WindowsWGLContext) factory.getOrCreateSharedContextImpl(device); + boolean hasARB = null != sharedContext && sharedContext.isExtensionAvailable(WGL_ARB_pixel_format) ; + + GLCapabilitiesImmutable caps = null; + PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor(); // PFD storage + + if(hasARB) { + sharedContext.makeCurrent(); + try { + caps = wglARBPFID2GLCapabilities(sharedContext, hdc, pfdID, glp, onscreen, usePBuffer); + } finally { + sharedContext.release(); + } + } else { + caps = PFD2GLCapabilities(glp, hdc, pfdID, onscreen, usePBuffer, pfd); } - - GLCapabilitiesImmutable caps = PFD2GLCapabilities(glp, pfd, onscreen, usePBuffer); if(null==caps) { - throw new GLException("Couldn't choose Capabilities by: HDC 0x"+Long.toHexString(hdc)+", pfdID "+pfdID); + throw new GLException("Couldn't choose Capabilities by: HDC 0x"+Long.toHexString(hdc)+", pfdID "+pfdID+", hasARB "+hasARB); + } + + if (GDI.DescribePixelFormat(hdc, pfdID, pfd.size(), pfd) == 0) { + throw new GLException("Unable to describe pixel format " + pfdID); } - WindowsWGLGraphicsConfiguration cfg = new WindowsWGLGraphicsConfiguration(screen, caps, caps, pfd, pfdID, new DefaultGLCapabilitiesChooser()); - cfg.setCapsPFD(caps, pfd, pfdID, false); - return cfg; + return new WindowsWGLGraphicsConfiguration(screen, caps, caps, pfd, pfdID, hasARB); } public Object clone() { return super.clone(); } - final void updateGraphicsConfiguration(GLDrawableFactory factory, NativeSurface ns) { - WindowsWGLGraphicsConfigurationFactory.updateGraphicsConfiguration(chooser, factory, ns); + /** + * Updates the graphics configuration in case it has been determined yet.<br> + * Uses the NativeSurface's HDC.<br> + * Ensures that a PIXELFORMAT is set. + * + * @param factory + * @param ns + * @param pfIDs optional pool of preselected PixelFormat IDs, maybe null for unrestricted selection + * + * @see #isDetermined() + */ + public final void updateGraphicsConfiguration(GLDrawableFactory factory, NativeSurface ns, int[] pfIDs) { + WindowsWGLGraphicsConfigurationFactory.updateGraphicsConfiguration(chooser, factory, ns, pfIDs); + } + + /** + * Preselect the graphics configuration in case it has been determined yet.<br> + * Uses a shared device's HDC and the given pfdIDs to preselect the pfd. + * No PIXELFORMAT is set. + * + * @param factory + * @param pfIDs optional pool of preselected PixelFormat IDs, maybe null for unrestricted selection + * + * @see #isDetermined() + */ + public final void preselectGraphicsConfiguration(GLDrawableFactory factory, int[] pfdIDs) { + AbstractGraphicsDevice device = getNativeGraphicsConfiguration().getScreen().getDevice(); + WindowsWGLGraphicsConfigurationFactory.preselectGraphicsConfiguration(chooser, factory, device, this, pfdIDs); } - void setCapsPFD(GLCapabilitiesImmutable caps, PIXELFORMATDESCRIPTOR pfd, int pfdID, boolean choosenByWGLPixelFormat) { + final void setCapsPFD(GLCapabilitiesImmutable caps, PIXELFORMATDESCRIPTOR pfd, int pfdID, boolean choosenByARBPixelFormat) { this.pixelfmt = pfd; this.pixelfmtID = pfdID; setChosenCapabilities(caps); this.isChosen=true; - this.choosenByWGLPixelFormat=choosenByWGLPixelFormat; + this.choosenByARBPixelFormat=choosenByARBPixelFormat; if (DEBUG) { - System.err.println("*** setCapsPFD: WGL-Choosen "+choosenByWGLPixelFormat+", pfdID "+pfdID+", "+caps); + System.err.println("*** setCapsPFD: ARB-Choosen "+choosenByARBPixelFormat+", pfdID "+pfdID+", "+caps); } } - public boolean getCapabilitiesChosen() { + public final boolean isDetermined() { return isChosen; } - public PIXELFORMATDESCRIPTOR getPixelFormat() { return pixelfmt; } - public int getPixelFormatID() { return pixelfmtID; } - public boolean isChoosenByWGL() { return choosenByWGLPixelFormat; } + public final PIXELFORMATDESCRIPTOR getPixelFormat() { return pixelfmt; } + public final int getPixelFormatID() { return pixelfmtID; } + public final boolean isChoosenByWGL() { return choosenByARBPixelFormat; } static int fillAttribsForGeneralWGLARBQuery(boolean haveWGLARBMultisample, int[] iattributes) { int niattribs = 0; @@ -159,84 +219,102 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio return true; } + static int[] wglAllARBPFIDs(WindowsWGLContext sharedCtx, long hdc) { + int[] iattributes = new int[1]; + int[] iresults = new int[1]; + + WGLExt wglExt = sharedCtx.getWGLExt(); + iattributes[0] = WGLExt.WGL_NUMBER_PIXEL_FORMATS_ARB; + if (!wglExt.wglGetPixelFormatAttribivARB(hdc, 0, 0, 1, iattributes, 0, iresults, 0)) { + if(DEBUG) { + System.err.println("GetPixelFormatAttribivARB: Failed - HDC 0x" + Long.toHexString(hdc) + + ", LastError: " + GDI.GetLastError()); + Thread.dumpStack(); + } + return null; + } + int numFormats = iresults[0]; + if(0 == numFormats) { + if(DEBUG) { + System.err.println("GetPixelFormatAttribivARB: No formats - HDC 0x" + Long.toHexString(hdc) + + ", LastError: " + GDI.GetLastError()); + Thread.dumpStack(); + } + return null; + } + int[] pfdIDs = new int[numFormats]; + for (int i = 0; i < numFormats; i++) { + pfdIDs[i] = 1 + i; + } + return pfdIDs; + } + static GLCapabilitiesImmutable wglARBPFID2GLCapabilities(WindowsWGLContext sharedCtx, long hdc, int pfdID, - GLProfile glp, boolean onscreen, boolean usePBuffer) { - boolean haveWGLChoosePixelFormatARB = sharedCtx.isExtensionAvailable("WGL_ARB_pixel_format"); + 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"); + boolean haveWGLARBMultisample = sharedCtx.isExtensionAvailable(WGL_ARB_multisample); 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)) { + 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; + return AttribList2GLCapabilities(glp, iattributes, niattribs, iresults, + onscreen, usePBuffer); } - static int wglChoosePixelFormatARB(long hdc, WindowsWGLContext sharedContext, - GLCapabilitiesImmutable capabilities, - int[] iattributes, int accelerationMode, float[] fattributes, - int[] pformats) + static int[] wglChoosePixelFormatARB(long hdc, WindowsWGLContext sharedContext, + GLCapabilitiesImmutable capabilities, + int[] iattributes, int accelerationMode, float[] fattributes) { - int numFormats = -1; - - if(WindowsWGLGraphicsConfiguration.GLCapabilities2AttribList(capabilities, - iattributes, - sharedContext, - accelerationMode, - false, - null)) { + + if ( !WindowsWGLGraphicsConfiguration.GLCapabilities2AttribList(capabilities, + iattributes, sharedContext, accelerationMode, false, null)) + { + if (DEBUG) { + System.err.println("wglChoosePixelFormatARB1: GLCapabilities2AttribList failed: " + GDI.GetLastError()); + Thread.dumpStack(); + } + return null; + } + + int[] pformatsTmp = new int[WindowsWGLGraphicsConfiguration.MAX_PFORMATS]; 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(); - } + if ( !sharedContext.getWGLExt().wglChoosePixelFormatARB(hdc, iattributes, 0, + fattributes, 0, + WindowsWGLGraphicsConfiguration.MAX_PFORMATS, + pformatsTmp, 0, numFormatsTmp, 0)) + { + if (DEBUG) { + System.err.println("wglChoosePixelFormatARB1: wglChoosePixelFormatARB failed: " + GDI.GetLastError()); + Thread.dumpStack(); + } + return null; } - } else { - if (DEBUG) { - System.err.println("wglChoosePixelFormatARB1: GLCapabilities2AttribList failed: " + GDI.GetLastError() ); - Thread.dumpStack(); - } - } - return numFormats; + int numFormats = numFormatsTmp[0]; + int[] pformats = new int[numFormats]; + System.arraycopy(pformatsTmp, 0, pformats, 0, numFormats); + if (DEBUG) { + System.err.println("wglChoosePixelFormatARB1: NumFormats (wglChoosePixelFormatARB) accelMode 0x" + + Integer.toHexString(accelerationMode) + ": " + numFormats); + } + return pformats; } - static GLCapabilitiesImmutable[] wglARBPFIDs2GLCapabilities(WindowsWGLContext sharedCtx, long hdc, int[] pfdIDs, int numFormats, + static GLCapabilitiesImmutable[] wglARBPFIDs2GLCapabilities(WindowsWGLContext sharedCtx, long hdc, int[] pfdIDs, GLProfile glp, boolean onscreen, boolean usePBuffer) { - boolean haveWGLChoosePixelFormatARB = sharedCtx.isExtensionAvailable("WGL_ARB_pixel_format"); + boolean haveWGLChoosePixelFormatARB = sharedCtx.isExtensionAvailable(WGL_ARB_pixel_format); if (!haveWGLChoosePixelFormatARB) { return null; } - boolean haveWGLARBMultisample = sharedCtx.isExtensionAvailable("WGL_ARB_multisample"); - + boolean haveWGLARBMultisample = sharedCtx.isExtensionAvailable(WGL_ARB_multisample); + final int numFormats = pfdIDs.length; GLCapabilitiesImmutable[] caps = new GLCapabilitiesImmutable[numFormats]; int[] iattributes = new int [2*MAX_ATTRIBS]; @@ -270,11 +348,11 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio */ static GLCapabilitiesImmutable[] wglARBAllPFIDs2GLCapabilities(WindowsWGLContext sharedCtx, long hdc, GLProfile glp, boolean onscreen, boolean usePBuffer, int[] pfIDs) { - boolean haveWGLChoosePixelFormatARB = sharedCtx.isExtensionAvailable("WGL_ARB_pixel_format"); + boolean haveWGLChoosePixelFormatARB = sharedCtx.isExtensionAvailable(WGL_ARB_pixel_format); if (!haveWGLChoosePixelFormatARB) { return null; } - boolean haveWGLARBMultisample = sharedCtx.isExtensionAvailable("WGL_ARB_multisample"); + boolean haveWGLARBMultisample = sharedCtx.isExtensionAvailable(WGL_ARB_multisample); // Produce a list of GLCapabilities to give to the // GLCapabilitiesChooser. @@ -328,8 +406,8 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio int accellerationValue, boolean pbuffer, int[] floatMode) throws GLException { - boolean haveWGLChoosePixelFormatARB = sharedCtx.isExtensionAvailable("WGL_ARB_pixel_format"); - boolean haveWGLARBMultisample = sharedCtx.isExtensionAvailable("WGL_ARB_multisample"); + boolean haveWGLChoosePixelFormatARB = sharedCtx.isExtensionAvailable(WGL_ARB_pixel_format); + boolean haveWGLARBMultisample = sharedCtx.isExtensionAvailable(WGL_ARB_multisample); if(DEBUG) { System.err.println("HDC2GLCapabilities: ARB_pixel_format: "+haveWGLChoosePixelFormatARB); System.err.println("HDC2GLCapabilities: ARB_multisample : "+haveWGLARBMultisample); @@ -642,7 +720,29 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio return res; } - // PIXELFORMAT + // + // GDI PIXELFORMAT + // + + static int[] wglAllGDIPFIDs(long hdc) { + int numFormats = GDI.DescribePixelFormat(hdc, 1, 0, null); + if (numFormats == 0) { + throw new GLException("DescribePixelFormat: No formats - HDC 0x" + Long.toHexString(hdc) + + ", LastError: " + GDI.GetLastError()); + } + int[] pfdIDs = new int[numFormats]; + for (int i = 0; i < numFormats; i++) { + pfdIDs[i] = 1 + i; + } + return pfdIDs; + } + + static GLCapabilitiesImmutable PFD2GLCapabilities(GLProfile glp, long hdc, int pfdID, boolean onscreen, boolean usePBuffer, PIXELFORMATDESCRIPTOR pfd) { + if (GDI.DescribePixelFormat(hdc, pfdID, pfd.size(), pfd) == 0) { + throw new GLException("Error describing pixel format " + pfdID + " of device context"); + } + return PFD2GLCapabilities(glp, pfd, onscreen, usePBuffer); + } static GLCapabilitiesImmutable PFD2GLCapabilities(GLProfile glp, PIXELFORMATDESCRIPTOR pfd, boolean onscreen, boolean usePBuffer) { if ((pfd.getDwFlags() & GDI.PFD_SUPPORT_OPENGL) == 0) { @@ -665,27 +765,20 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio (pfd.getDwFlags() & GDI.PFD_GENERIC_ACCELERATED) != 0 ); res.setOnscreen ( onscreen && ((pfd.getDwFlags() & GDI.PFD_DRAW_TO_WINDOW) != 0) ); res.setPBuffer ( usePBuffer ); - /* FIXME: Missing ?? - if (GLXUtil.isMultisampleAvailable()) { - res.setSampleBuffers(glXGetFBConfig(display, fbcfg, GLX.GLX_SAMPLE_BUFFERS, tmp, 0) != 0); - res.setNumSamples (glXGetFBConfig(display, fbcfg, GLX.GLX_SAMPLES, tmp, 0)); - } - res.setBackgroundOpaque(glXGetFBConfig(display, fbcfg, GLX.GLX_TRANSPARENT_TYPE, tmp, 0) != GLX.GLX_NONE); - try { - res.setPbufferFloatingPointBuffers(glXGetFBConfig(display, fbcfg, GLXExt.GLX_FLOAT_COMPONENTS_NV, tmp, 0) != GL.GL_FALSE); - } catch (Exception e) {} - */ + // n/a with non ARB/GDI method: + // multisample + // opaque + // pbuffer return res; } - static PIXELFORMATDESCRIPTOR GLCapabilities2PFD(GLCapabilitiesImmutable caps) { + static PIXELFORMATDESCRIPTOR GLCapabilities2PFD(GLCapabilitiesImmutable caps, PIXELFORMATDESCRIPTOR pfd) { int colorDepth = (caps.getRedBits() + caps.getGreenBits() + caps.getBlueBits()); if (colorDepth < 15) { throw new GLException("Bit depths < 15 (i.e., non-true-color) not supported"); } - PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor(); int pfdFlags = (GDI.PFD_SUPPORT_OPENGL | GDI.PFD_GENERIC_ACCELERATED); if (caps.getDoubleBuffered()) { @@ -718,15 +811,10 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio pfd.setCStencilBits((byte) caps.getStencilBits()); pfd.setILayerType((byte) GDI.PFD_MAIN_PLANE); - /* FIXME: Missing: - caps.getSampleBuffers() - caps.getNumSamples () - } - caps.getBackgroundOpaque() - try { - caps.getPbufferFloatingPointBuffers() - } catch (Exception e) {} - */ + // n/a with non ARB/GDI method: + // multisample + // opaque + // pbuffer return pfd; } @@ -738,7 +826,7 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio } public String toString() { - return "WindowsWGLGraphicsConfiguration["+getScreen()+", pfdID " + pixelfmtID + ", wglChoosen "+choosenByWGLPixelFormat+ + return "WindowsWGLGraphicsConfiguration["+getScreen()+", pfdID " + pixelfmtID + ", ARB-Choosen "+choosenByARBPixelFormat+ ",\n\trequested " + getRequestedCapabilities() + ",\n\tchosen " + getChosenCapabilities() + "]"; 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 87bbec018..051dc5bad 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 @@ -39,9 +39,10 @@ import javax.media.nativewindow.AbstractGraphicsScreen; import javax.media.nativewindow.CapabilitiesChooser; import javax.media.nativewindow.DefaultGraphicsScreen; import javax.media.nativewindow.GraphicsConfigurationFactory; +import javax.media.nativewindow.CapabilitiesImmutable; import javax.media.nativewindow.NativeSurface; -import javax.media.nativewindow.NativeWindowException; import javax.media.nativewindow.NativeWindowFactory; +import javax.media.opengl.GLCapabilitiesImmutable; import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLCapabilitiesChooser; import javax.media.opengl.GLDrawableFactory; @@ -50,16 +51,14 @@ 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; +import com.jogamp.opengl.impl.GLGraphicsConfigurationFactoryImpl; /** Subclass of GraphicsConfigurationFactory used when non-AWT tookits are used on Windows platforms. Toolkits will likely need to delegate to this one to change the accepted and returned types of the GraphicsDevice and GraphicsConfiguration abstractions. */ -public class WindowsWGLGraphicsConfigurationFactory extends GraphicsConfigurationFactory { +public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactoryImpl { protected static final boolean DEBUG = com.jogamp.opengl.impl.Debug.debug("GraphicsConfiguration"); WindowsWGLGraphicsConfigurationFactory() { @@ -82,10 +81,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GraphicsConfiguratio static WindowsWGLGraphicsConfiguration createDefaultGraphicsConfiguration(GLCapabilitiesImmutable caps, AbstractGraphicsScreen absScreen) { - if(null==absScreen) { - absScreen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_WINDOWS); - } - return new WindowsWGLGraphicsConfiguration(absScreen, caps, caps, WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(caps), -1, null); + return chooseGraphicsConfigurationStatic(caps, caps, null, absScreen); } static WindowsWGLGraphicsConfiguration chooseGraphicsConfigurationStatic(GLCapabilitiesImmutable capsChosen, @@ -103,13 +99,24 @@ public class WindowsWGLGraphicsConfigurationFactory extends GraphicsConfiguratio capsChosen = caps2; } - return new WindowsWGLGraphicsConfiguration(absScreen, capsChosen, capsReq, - WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(capsChosen), -1, - (GLCapabilitiesChooser)chooser); + return new WindowsWGLGraphicsConfiguration( absScreen, capsChosen, capsReq, (GLCapabilitiesChooser)chooser ); } + /** + * + * @param chooser + * @param _factory + * @param ns + * @param pfIDs optional pool of preselected PixelFormat IDs, maybe null for unrestricted selection + */ static void updateGraphicsConfiguration(CapabilitiesChooser chooser, - GLDrawableFactory _factory, NativeSurface ns) { + GLDrawableFactory factory, NativeSurface ns, int[] pfdIDs) { + if (chooser != null && !(chooser instanceof GLCapabilitiesChooser)) { + throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilitiesChooser objects"); + } + if (factory == null) { + throw new IllegalArgumentException("GLDrawableFactory is null"); + } if (ns == null) { throw new IllegalArgumentException("NativeSurface is null"); } @@ -118,22 +125,75 @@ public class WindowsWGLGraphicsConfigurationFactory extends GraphicsConfiguratio throw new GLException("Error: HDC is null"); } 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(); + } + } + } + + static void preselectGraphicsConfiguration(CapabilitiesChooser chooser, + GLDrawableFactory _factory, AbstractGraphicsDevice device, + WindowsWGLGraphicsConfiguration config, int[] pfdIDs) { if (chooser != null && !(chooser instanceof GLCapabilitiesChooser)) { throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilitiesChooser objects"); } + if (_factory == null) { + throw new IllegalArgumentException("GLDrawableFactory is null"); + } + if (config == null) { + throw new IllegalArgumentException("WindowsWGLGraphicsConfiguration is null"); + } + WindowsWGLDrawableFactory factory = (WindowsWGLDrawableFactory) _factory; + WindowsWGLDrawable sharedDrawable = factory.getSharedDrawable(device); + if(null == sharedDrawable) { + throw new IllegalArgumentException("Shared Drawable is null"); + } + sharedDrawable.lockSurface(); + try { + long hdc = sharedDrawable.getHandle(); + if (0 == hdc) { + throw new GLException("Error: HDC is null"); + } + updateGraphicsConfiguration(config, chooser, factory, hdc, true, pfdIDs); + } finally { + sharedDrawable.unlockSurface(); + } + } + private static void updateGraphicsConfiguration(WindowsWGLGraphicsConfiguration config, CapabilitiesChooser chooser, + GLDrawableFactory factory, long hdc, boolean extHDC, int[] pfdIDs) { if (DEBUG) { - System.err.println("updateGraphicsConfiguration: hdc "+toHexString(hdc)); + if(extHDC) { + System.err.println("updateGraphicsConfiguration(using shared): hdc "+toHexString(hdc)); + } else { + System.err.println("updateGraphicsConfiguration(using target): hdc "+toHexString(hdc)); + } System.err.println("!!! user chosen caps " + config.getChosenCapabilities()); } - - if( !updateGraphicsConfigurationARB(hdc, config, chooser, (WindowsWGLDrawableFactory) _factory) ) { - updateGraphicsConfigurationGDI(hdc, config, chooser, (WindowsWGLDrawableFactory) _factory); + if( !updateGraphicsConfigurationARB(hdc, extHDC, config, chooser, (WindowsWGLDrawableFactory)factory, pfdIDs) ) { + updateGraphicsConfigurationGDI(hdc, extHDC, config, chooser, pfdIDs); } } - private static boolean updateGraphicsConfigurationARB(long hdc, WindowsWGLGraphicsConfiguration config, - CapabilitiesChooser chooser, WindowsWGLDrawableFactory factory) { + private static boolean updateGraphicsConfigurationARB(long hdc, boolean extHDC, WindowsWGLGraphicsConfiguration config, + CapabilitiesChooser chooser, WindowsWGLDrawableFactory factory, int[] pformats) { AbstractGraphicsDevice device = config.getScreen().getDevice(); WindowsWGLContext sharedContext = (WindowsWGLContext) factory.getOrCreateSharedContextImpl(device); if (null == sharedContext) { @@ -147,129 +207,80 @@ public class WindowsWGLGraphicsConfigurationFactory extends GraphicsConfiguratio boolean usePBuffer = capsChosen.isPBuffer(); GLProfile glProfile = capsChosen.getGLProfile(); - int pixelFormatSet = -1; // 1-based pixel format - GLCapabilitiesImmutable pixelFormatCaps = null; + GLCapabilitiesImmutable[] availableCaps = null; // caps array matching PFD ID of pformats array + int pfdID; // chosen or preset PFD ID + GLCapabilitiesImmutable pixelFormatCaps = null; // chosen or preset PFD ID's caps + boolean pixelFormatSet = false; // indicates a preset PFD ID [caps] - GLCapabilitiesImmutable[] availableCaps = null; - int[] pformats = null; // if != null, then index matches availableCaps - int numFormats = -1; - int recommendedIndex = -1; - - synchronized (sharedContext) { - sharedContext.makeCurrent(); - try { - if (!sharedContext.isExtensionAvailable("WGL_ARB_pixel_format")) { - if (DEBUG) { - System.err.println("updateGraphicsConfigurationARB: wglChoosePixelFormatARB not available"); - } - return false; + if (!sharedContext.isExtensionAvailable(WindowsWGLGraphicsConfiguration.WGL_ARB_pixel_format)) { + if (DEBUG) { + System.err.println("updateGraphicsConfigurationARB: "+WindowsWGLGraphicsConfiguration.WGL_ARB_pixel_format+" not available"); + } + return false; + } + sharedContext.makeCurrent(); + try { + if ( !extHDC && 1 <= ( pfdID = GDI.GetPixelFormat(hdc) ) ) { + // Pixelformat already set by either + // - a previous preselectGraphicsConfiguration() 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("updateGraphicsConfigurationARB: Pixel format already chosen for HDC: " + toHexString(hdc) + + ", pixelformat " + pfdID); } - if ((pixelFormatSet = GDI.GetPixelFormat(hdc)) >= 1) { - // 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("updateGraphicsConfigurationARB: Pixel format already chosen for HDC: " + toHexString(hdc) - + ", pixelformat " + pixelFormatSet); - } - - // only fetch the specific one .. - pixelFormatCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedContext, hdc, pixelFormatSet, glProfile, onscreen, usePBuffer); - } else { + pixelFormatSet = true; + pixelFormatCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedContext, hdc, pfdID, glProfile, onscreen, usePBuffer); + } else { + int recommendedIndex = -1; // recommended index + + if(null == pformats) { + // No given PFD IDs + // + // 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice 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) { - 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); - } - } - } - - // 2nd choice: get all GLCapabilities available, no preferred recommendedIndex available - if (null == availableCaps) { + pformats = WindowsWGLGraphicsConfiguration.wglChoosePixelFormatARB(hdc, sharedContext, capsChosen, + iattributes, -1, fattributes); + if (null != pformats) { + recommendedIndex = 0; if (DEBUG) { - System.err.println("updateGraphicsConfigurationARB: wglChoosePixelFormatARB failed (Query all formats without recommendation): " + GDI.GetLastError()); + System.err.println("updateGraphicsConfigurationARB: NumFormats (wglChoosePixelFormatARB) " + pformats.length); + System.err.println("updateGraphicsConfigurationARB: Used wglChoosePixelFormatARB to recommend pixel format " + pformats[recommendedIndex] + ", idx " + recommendedIndex); } - availableCaps = WindowsWGLGraphicsConfiguration.wglARBAllPFIDs2GLCapabilities(sharedContext, hdc, - glProfile, onscreen, usePBuffer, pformats); - if (null != availableCaps) { - numFormats = availableCaps.length; + } else { + // 2nd choice: get all GLCapabilities available, no preferred recommendedIndex available + pformats = WindowsWGLGraphicsConfiguration.wglAllARBPFIDs(sharedContext, hdc); + if (DEBUG) { + System.err.println("updateGraphicsConfigurationARB: NumFormats (wglAllARBPFIDs) " + pformats.length); } } - } - } finally { - sharedContext.release(); - } - } // synchronized(factory.sharedContext) - - if (pixelFormatSet <= 0 && null == availableCaps) { - if (DEBUG) { - 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); + if (null == pformats) { + if (DEBUG) { + Thread.dumpStack(); + } + return false; } } - } catch (NativeWindowException e) { - if (DEBUG) { - e.printStackTrace(); - } - } + // translate chosen/all or given PFD IDs + availableCaps = WindowsWGLGraphicsConfiguration.wglARBPFIDs2GLCapabilities(sharedContext, hdc, pformats, + glProfile, onscreen, usePBuffer); - 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 .. + int chosenIndex = chooseCapabilities(chooser, capsChosen, availableCaps, recommendedIndex); + if ( 0 > chosenIndex ) { if (DEBUG) { - System.err.println("updateGraphicsConfigurationARB: Failed .. nothing available, bail out"); + Thread.dumpStack(); } return false; } pixelFormatCaps = availableCaps[chosenIndex]; + pfdID = pformats[chosenIndex]; if (DEBUG) { - System.err.println("updateGraphicsConfigurationARB: Failed .. unable to choose config, using first available idx: " + chosenIndex); - System.err.println("!!! fallback caps " + pixelFormatCaps); + System.err.println("!!! chosen pfdID "+pfdID+", caps " + pixelFormatCaps); } } - pfdID = pformats[chosenIndex]; - } else { - pfdID = pixelFormatSet; - } - if (DEBUG) { - System.err.println("updateGraphicsConfigurationARB: using pfdID "+pfdID); + } finally { + sharedContext.release(); } PIXELFORMATDESCRIPTOR pfd = WindowsWGLGraphicsConfiguration.createPixelFormatDescriptor(); @@ -278,136 +289,96 @@ public class WindowsWGLGraphicsConfigurationFactory extends GraphicsConfiguratio throw new GLException("updateGraphicsConfigurationARB: Error describing the chosen pixel format: " + pfdID + ", " + GDI.GetLastError()); } - if (pixelFormatSet <= 0) { + if ( !extHDC && !pixelFormatSet ) { if (!GDI.SetPixelFormat(hdc, pfdID, pfd)) { throw new GLException("Unable to set pixel format " + pfdID + " for device context " + toHexString(hdc) + ": error code " + GDI.GetLastError()); } + if (DEBUG) { + System.err.println("!!! setPixelFormat (ARB): hdc "+toHexString(hdc) +", "+config.getPixelFormatID()+" -> "+pfdID); + } } - config.setCapsPFD(pixelFormatCaps, pfd, pfdID, true); return true; } - private static boolean updateGraphicsConfigurationGDI(long hdc, WindowsWGLGraphicsConfiguration config, - CapabilitiesChooser chooser, WindowsWGLDrawableFactory factory) { + private static boolean updateGraphicsConfigurationGDI(long hdc, boolean extHDC, WindowsWGLGraphicsConfiguration config, + CapabilitiesChooser chooser, int[] pformats) { 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; // caps array matching PFD ID of pformats array + int pfdID; // chosen or preset PFD ID + GLCapabilitiesImmutable pixelFormatCaps = null; // chosen or preset PFD ID's caps + boolean pixelFormatSet = false; // indicates a preset PFD ID [caps] - GLCapabilitiesImmutable[] availableCaps = null; - int numFormats = -1; - int recommendedIndex = -1; + PIXELFORMATDESCRIPTOR pfd = WindowsWGLGraphicsConfiguration.createPixelFormatDescriptor(); // PFD storage - if ((pixelFormatSet = GDI.GetPixelFormat(hdc)) != 0) { + if ( !extHDC && 1 <= ( pfdID = GDI.GetPixelFormat(hdc) ) ) { // Pixelformat already set by either - // - a previous updateGraphicsConfiguration() call on the same HDC, + // - a previous preselectGraphicsConfiguration() 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("updateGraphicsConfigurationGDI: NOTE: pixel format already chosen for HDC: " + toHexString(hdc) - + ", pixelformat " + pixelFormatSet); + + ", pixelformat " + pfdID); } - } - - int recommendedPixelFormat = pixelFormatSet; - - 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"); + pixelFormatSet = true; + pixelFormatCaps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, hdc, pfdID, onscreen, usePBuffer, pfd); + } else { + if(null == pformats) { + pformats = WindowsWGLGraphicsConfiguration.wglAllGDIPFIDs(hdc); + } + int numFormats = pformats.length; + availableCaps = new GLCapabilitiesImmutable[numFormats]; + for (int i = 0; i < numFormats; i++) { + availableCaps[i] = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, hdc, pformats[i], onscreen, usePBuffer, pfd); + } + pfd = WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(capsChosen, pfd); + pfdID = GDI.ChoosePixelFormat(hdc, pfd); + int recommendedIndex = -1 ; + if( 1 <= pfdID ) { + // seek index .. + for (recommendedIndex = numFormats - 1 ; + 0 <= recommendedIndex && pfdID != pformats[recommendedIndex]; + recommendedIndex--) + { /* nop */ } } - 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); + System.err.println("updateGraphicsConfigurationGDI: ChoosePixelFormat(HDC " + toHexString(hdc) + ") = " + pfdID + ", idx " + recommendedIndex + " (LastError: " + GDI.GetLastError() + ")"); } - - 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); - } - } - } catch (NativeWindowException e) { + int chosenIndex = chooseCapabilities(chooser, capsChosen, availableCaps, recommendedIndex); + if ( 0 > chosenIndex ) { if (DEBUG) { - e.printStackTrace(); + Thread.dumpStack(); } + return false; } - - 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 { - pfdID = pixelFormatSet; - pixelFormatCaps = availableCaps[pixelFormatSet-1]; + pixelFormatCaps = availableCaps[chosenIndex]; + pfdID = pformats[chosenIndex]; if (DEBUG) { - System.err.println("updateGraphicsConfigurationGDI: Using preset PFID: " + pixelFormatSet); - System.err.println("!!! preset caps " + pixelFormatCaps); + System.err.println("!!! chosen pfdID "+pfdID+", idx " + chosenIndex + ", caps " + pixelFormatCaps); } } - if (DEBUG) { - System.err.println("updateGraphicsConfigurationGDI: using pfdID "+pfdID); - } - + 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 ( !extHDC && !pixelFormatSet ) { if (!GDI.SetPixelFormat(hdc, pfdID, pfd)) { throw new GLException("Unable to set pixel format " + pfdID + " for device context " + toHexString(hdc) + ": error code " + GDI.GetLastError()); } + if (DEBUG) { + System.err.println("!!! setPixelFormat (GDI): hdc "+toHexString(hdc) +", "+config.getPixelFormatID()+" -> "+pfdID); + } } - - config.setCapsPFD(pixelFormatCaps, pfd, pfdID, true); + config.setCapsPFD(pixelFormatCaps, pfd, pfdID, false); return true; } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java index da4f2113d..4fbdab9c2 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -33,6 +34,9 @@ package com.jogamp.opengl.impl.windows.wgl.awt; +import com.jogamp.common.util.ArrayHashSet; +import com.jogamp.nativewindow.impl.jawt.windows.Win32SunJDKReflection; +import com.jogamp.opengl.impl.GLGraphicsConfigurationFactoryImpl; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; @@ -53,8 +57,9 @@ import javax.media.opengl.GLCapabilitiesImmutable; import javax.media.opengl.GLException; import com.jogamp.opengl.impl.windows.wgl.WindowsWGLGraphicsConfiguration; +import javax.media.opengl.GLDrawableFactory; -public class WindowsAWTWGLGraphicsConfigurationFactory extends GraphicsConfigurationFactory { +public class WindowsAWTWGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactoryImpl { protected static final boolean DEBUG = com.jogamp.opengl.impl.Debug.debug("GraphicsConfiguration"); public WindowsAWTWGLGraphicsConfigurationFactory() { @@ -72,6 +77,9 @@ public class WindowsAWTWGLGraphicsConfigurationFactory extends GraphicsConfigura if(null==absScreen) { absScreen = AWTGraphicsScreen.createScreenDevice(-1, AbstractGraphicsDevice.DEFAULT_UNIT); + if(DEBUG) { + System.err.println("WindowsAWTWGLGraphicsConfigurationFactory: creating default device: "+absScreen); + } } AWTGraphicsScreen awtScreen = (AWTGraphicsScreen) absScreen; device = ((AWTGraphicsDevice)awtScreen.getDevice()).getGraphicsDevice(); @@ -92,28 +100,74 @@ public class WindowsAWTWGLGraphicsConfigurationFactory extends GraphicsConfigura if(DEBUG) { System.err.println("WindowsAWTWGLGraphicsConfigurationFactory: got "+absScreen); } - GraphicsConfiguration gc = device.getDefaultConfiguration(); + WindowsGraphicsDevice winDevice = new WindowsGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT); DefaultGraphicsScreen winScreen = new DefaultGraphicsScreen(winDevice, awtScreen.getIndex()); - if(DEBUG) { - System.err.println("WindowsAWTWGLGraphicsConfigurationFactory: made "+winScreen); - } + GraphicsConfigurationFactory configFactory = GraphicsConfigurationFactory.getFactory(winDevice); + GLDrawableFactory drawableFactory = GLDrawableFactory.getFactory( ((GLCapabilitiesImmutable)capsChosen).getGLProfile() ); WindowsWGLGraphicsConfiguration winConfig = (WindowsWGLGraphicsConfiguration) - GraphicsConfigurationFactory.getFactory(winDevice).chooseGraphicsConfiguration(capsChosen, - capsRequested, - chooser, winScreen); - + configFactory.chooseGraphicsConfiguration(capsChosen, + capsRequested, + chooser, winScreen); if (winConfig == null) { throw new GLException("Unable to choose a GraphicsConfiguration: "+capsChosen+",\n\t"+chooser+"\n\t"+winScreen); } - if(DEBUG) { - System.err.println("WindowsAWTWGLGraphicsConfigurationFactory: chosen "+winConfig); + GraphicsConfiguration chosenGC = null; + + // 1st Choice: Create an AWT GraphicsConfiguration with the desired PFD + // This gc will probably not be able to support GDI (WGL_SUPPORT_GDI_ARB, PFD_SUPPORT_GDI) + // however on most GPUs this is the current situation for Windows, + // otherwise no hardware accelerated PFD could be achieved. + // - preselect with no constrains + // - try to create dedicated GC + winConfig.preselectGraphicsConfiguration(drawableFactory, null); + if ( 1 <= winConfig.getPixelFormatID() ) { + chosenGC = Win32SunJDKReflection.graphicsConfigurationGet(device, winConfig.getPixelFormatID()); + if(DEBUG) { + System.err.println("WindowsAWTWGLGraphicsConfigurationFactory: Found new AWT PFD ID "+winConfig.getPixelFormatID()+" -> "+winConfig); + } + } + + if( null == chosenGC ) { + // 2nd Choice: Choose and match the GL Visual with AWT: + // - collect all AWT PFDs + // - choose a GL config from the pool of AWT PFDs + // + // The resulting GraphicsConfiguration has to be 'forced' on the AWT native peer, + // ie. returned by GLCanvas's getGraphicsConfiguration() befor call by super.addNotify(). + // + + // collect all available PFD IDs + GraphicsConfiguration[] configs = device.getConfigurations(); + int[] pfdIDs = new int[configs.length]; + ArrayHashSet pfdIDOSet = new ArrayHashSet(); + for (int i = 0; i < configs.length; i++) { + GraphicsConfiguration gc = configs[i]; + pfdIDs[i] = Win32SunJDKReflection.graphicsConfigurationGetPixelFormatID(gc); + pfdIDOSet.add(new Integer(pfdIDs[i])); + if(DEBUG) { + System.err.println("AWT pfd["+i+"] "+pfdIDs[i]); + } + } + if(DEBUG) { + System.err.println("WindowsAWTWGLGraphicsConfigurationFactory: PFD IDs: "+pfdIDs.length+", unique: "+pfdIDOSet.size()); + } + winConfig.preselectGraphicsConfiguration(drawableFactory, pfdIDs); + int gcIdx = pfdIDOSet.indexOf(new Integer(winConfig.getPixelFormatID())); + if( 0 > gcIdx ) { + chosenGC = configs[gcIdx]; + if(DEBUG) { + System.err.println("WindowsAWTWGLGraphicsConfigurationFactory: Found matching AWT PFD ID "+winConfig.getPixelFormatID()+" -> "+winConfig); + } + } } - // We have nothing to match .. so choose the default + if ( null == chosenGC ) { + throw new GLException("Unable to determine GraphicsConfiguration: "+winConfig); + } return new AWTGraphicsConfiguration(awtScreen, winConfig.getChosenCapabilities(), winConfig.getRequestedCapabilities(), - gc, winConfig); + chosenGC, winConfig); } } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java index 3abbcee57..7303e6e50 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java @@ -220,6 +220,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { VersionNumber glXVersion; try { X11GLXContext ctx = (X11GLXContext) sharedDrawable.createContext(null); + ctx.setSynchronized(true); ctx.makeCurrent(); { int[] major = new int[1]; 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 327ecd0be..88ed852d5 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 @@ -53,6 +53,7 @@ import com.jogamp.nativewindow.impl.x11.X11Lib; import com.jogamp.nativewindow.impl.x11.X11Util; import com.jogamp.nativewindow.impl.x11.XVisualInfo; import com.jogamp.opengl.impl.Debug; +import com.jogamp.opengl.impl.GLGraphicsConfigurationFactoryImpl; /** Subclass of GraphicsConfigurationFactory used when non-AWT toolkits @@ -60,7 +61,7 @@ import com.jogamp.opengl.impl.Debug; to this one to change the accepted and returned types of the GraphicsDevice and GraphicsConfiguration abstractions. */ -public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFactory { +public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationFactoryImpl { protected static final boolean DEBUG = Debug.debug("GraphicsConfiguration"); X11GLXGraphicsConfigurationFactory() { @@ -225,51 +226,13 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac } } - if( recommendedIndex < 1 && null==chooser) { - chooser = new DefaultGLCapabilitiesChooser(); - } - - 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]); - } - } - } 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("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig Failed .. nothing available, bail out"); - } - return null; - } - 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.." + (availableCaps.length - 1) + ", got "+chosenIndex+")"); + int chosenIndex = chooseCapabilities(chooser, capsChosen, availableCaps, recommendedIndex); + if ( 0 > chosenIndex ) { + if (DEBUG) { + Thread.dumpStack(); } return null; } - retFBID = X11GLXGraphicsConfiguration.glXFBConfig2FBConfigID(display, fbcfgsL.get(chosenIndex)); retXVisualInfo = GLX.glXGetVisualFromFBConfig(display, fbcfgsL.get(chosenIndex)); @@ -300,10 +263,9 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac GLProfile glProfile = capsChosen.getGLProfile(); boolean onscreen = capsChosen.isOnscreen(); - GLCapabilitiesImmutable[] caps = null; + GLCapabilitiesImmutable[] availableCaps = null; int recommendedIndex = -1; XVisualInfo retXVisualInfo = null; - int chosen=-1; AbstractGraphicsDevice absDevice = x11Screen.getDevice(); long display = absDevice.getHandle(); @@ -329,36 +291,24 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac if (infos == null || infos.length<1) { throw new GLException("Error while enumerating available XVisualInfos"); } - caps = new GLCapabilitiesImmutable[infos.length]; + availableCaps = new GLCapabilitiesImmutable[infos.length]; for (int i = 0; i < infos.length; i++) { - caps[i] = X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(glProfile, display, infos[i], onscreen, false, isMultisampleAvailable); + availableCaps[i] = X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(glProfile, display, infos[i], onscreen, false, isMultisampleAvailable); // Attempt to find the visual chosenIndex by glXChooseVisual if (recommendedVis != null && recommendedVis.getVisualid() == infos[i].getVisualid()) { recommendedIndex = i; } } - try { - chosen = chooser.chooseCapabilities(capsChosen, caps, recommendedIndex); - } catch (NativeWindowException e) { - if(DEBUG) { - e.printStackTrace(); - } - chosen = -1; - } - if (chosen < 0) { - // keep on going .. - if(DEBUG) { - System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationXVisual Failed .. unable to choose config, using first"); - } - chosen = 0; // default .. - } else if (chosen >= caps.length) { - throw new GLException("GLCapabilitiesChooser specified invalid index (expected 0.." + (caps.length - 1) + ")"); - } - if (infos[chosen] == null) { - throw new GLException("GLCapabilitiesChooser chose an invalid visual for "+caps[chosen]); + int chosenIndex = chooseCapabilities(chooser, capsChosen, availableCaps, recommendedIndex); + if ( 0 > chosenIndex ) { + if (DEBUG) { + Thread.dumpStack(); + } + return null; } - retXVisualInfo = XVisualInfo.create(infos[chosen]); - return new X11GLXGraphicsConfiguration(x11Screen, caps[chosen], capsReq, chooser, retXVisualInfo, 0, -1); + + retXVisualInfo = XVisualInfo.create(infos[chosenIndex]); + return new X11GLXGraphicsConfiguration(x11Screen, availableCaps[chosenIndex], capsReq, chooser, retXVisualInfo, 0, -1); } static String toHexString(int val) { diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java index 0fbe7a1c9..b9b42e16a 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java @@ -43,10 +43,8 @@ import javax.media.opengl.*; import com.jogamp.opengl.impl.*; import com.jogamp.nativewindow.impl.jawt.x11.*; import com.jogamp.nativewindow.impl.x11.*; -import com.jogamp.opengl.impl.x11.glx.X11GLXGraphicsConfigurationFactory; -import java.awt.image.ColorModel; -public class X11AWTGLXGraphicsConfigurationFactory extends GraphicsConfigurationFactory { +public class X11AWTGLXGraphicsConfigurationFactory extends GLGraphicsConfigurationFactoryImpl { protected static final boolean DEBUG = Debug.debug("GraphicsConfiguration"); public X11AWTGLXGraphicsConfigurationFactory() { @@ -153,15 +151,13 @@ public class X11AWTGLXGraphicsConfigurationFactory extends GraphicsConfiguration visualID = x11Config.getVisualID(); for (int i = 0; i < configs.length; i++) { gc = configs[i]; - if (gc != null) { - if (X11SunJDKReflection.graphicsConfigurationGetVisualID(gc) == visualID) { - if(DEBUG) { - System.err.println("Found matching default AWT visual: 0x"+Long.toHexString(visualID) +" -> "+x11Config); - } - return new AWTGraphicsConfiguration(awtScreen, - x11Config.getChosenCapabilities(), x11Config.getRequestedCapabilities(), - gc, x11Config); + if (X11SunJDKReflection.graphicsConfigurationGetVisualID(gc) == visualID) { + if(DEBUG) { + System.err.println("Found matching default AWT visual: 0x"+Long.toHexString(visualID) +" -> "+x11Config); } + return new AWTGraphicsConfiguration(awtScreen, + x11Config.getChosenCapabilities(), x11Config.getRequestedCapabilities(), + gc, x11Config); } } diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/GraphicsConfigurationFactoryImpl.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/DefaultGraphicsConfigurationFactoryImpl.java index c53f4c88b..f77454fac 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/GraphicsConfigurationFactoryImpl.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/DefaultGraphicsConfigurationFactoryImpl.java @@ -35,7 +35,7 @@ package com.jogamp.nativewindow.impl; import javax.media.nativewindow.*; -public class GraphicsConfigurationFactoryImpl extends GraphicsConfigurationFactory { +public class DefaultGraphicsConfigurationFactoryImpl extends GraphicsConfigurationFactory { protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl( CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested, CapabilitiesChooser chooser, AbstractGraphicsScreen screen) { return new DefaultGraphicsConfiguration(screen, capsChosen, capsRequested); diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/windows/Win32SunJDKReflection.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/windows/Win32SunJDKReflection.java new file mode 100644 index 000000000..05d31a40e --- /dev/null +++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/windows/Win32SunJDKReflection.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for use + * in the design, construction, operation or maintenance of any nuclear + * facility. + * + * Sun gratefully acknowledges that this software was originally authored + * and developed by Kenneth Bradley Russell and Christopher John Kline. + */ + +package com.jogamp.nativewindow.impl.jawt.windows; + +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; + +import java.lang.reflect.Method; +import java.security.AccessController; +import java.security.PrivilegedAction; + +import javax.media.nativewindow.AbstractGraphicsConfiguration; +import javax.media.nativewindow.awt.AWTGraphicsConfiguration; + +/** This class encapsulates the reflection routines necessary to peek + inside a few data structures in the AWT implementation on X11 for + the purposes of correctly enumerating the available visuals. */ + +public class Win32SunJDKReflection { + private static Class win32GraphicsDeviceClass; + private static Class win32GraphicsConfigClass; + private static Method win32GraphicsConfigGetConfigMethod; + private static Method win32GraphicsConfigGetVisualMethod; + private static boolean initted; + + static { + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + try { + win32GraphicsDeviceClass = Class.forName("sun.awt.Win32GraphicsDevice"); + win32GraphicsConfigClass = Class.forName("sun.awt.Win32GraphicsConfig"); + win32GraphicsConfigGetConfigMethod = win32GraphicsConfigClass.getDeclaredMethod("getConfig", new Class[] { win32GraphicsDeviceClass, int.class }); + win32GraphicsConfigGetConfigMethod.setAccessible(true); + win32GraphicsConfigGetVisualMethod = win32GraphicsConfigClass.getDeclaredMethod("getVisual", new Class[] {}); + win32GraphicsConfigGetVisualMethod.setAccessible(true); + initted = true; + } catch (Exception e) { + // Either not a Sun JDK or the interfaces have changed since 1.4.2 / 1.5 + } + return null; + } + }); + } + + public static GraphicsConfiguration graphicsConfigurationGet(GraphicsDevice device, int pfdID) { + if (!initted) { + return null; + } + + try { + return (GraphicsConfiguration) win32GraphicsConfigGetConfigMethod.invoke(null, new Object[] { device, new Integer(pfdID) }); + } catch (Exception e) { + return null; + } + } + + public static int graphicsConfigurationGetPixelFormatID(AbstractGraphicsConfiguration config) { + try { + if (config instanceof AWTGraphicsConfiguration) { + return graphicsConfigurationGetPixelFormatID(((AWTGraphicsConfiguration) config).getGraphicsConfiguration()); + } + return 0; + } catch (Exception e) { + return 0; + } + } + + public static int graphicsConfigurationGetPixelFormatID(GraphicsConfiguration config) { + if (!initted) { + return 0; + } + + try { + return ((Integer) win32GraphicsConfigGetVisualMethod.invoke(config, null)).intValue(); + } catch (Exception e) { + return 0; + } + } +} diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11SunJDKReflection.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11SunJDKReflection.java index 081975afb..b4a99624c 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11SunJDKReflection.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11SunJDKReflection.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -39,12 +40,12 @@ package com.jogamp.nativewindow.impl.jawt.x11; -import com.jogamp.nativewindow.impl.x11.*; - import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; -import java.lang.reflect.*; -import java.security.*; + +import java.lang.reflect.Method; +import java.security.AccessController; +import java.security.PrivilegedAction; import javax.media.nativewindow.AbstractGraphicsConfiguration; import javax.media.nativewindow.awt.AWTGraphicsConfiguration; @@ -55,7 +56,6 @@ import javax.media.nativewindow.awt.AWTGraphicsConfiguration; public class X11SunJDKReflection { private static Class x11GraphicsDeviceClass; - private static Method x11GraphicsDeviceGetScreenMethod; private static Method x11GraphicsDeviceGetDisplayMethod; private static Class x11GraphicsConfigClass; private static Method x11GraphicsConfigGetVisualMethod; @@ -66,8 +66,6 @@ public class X11SunJDKReflection { public Object run() { try { x11GraphicsDeviceClass = Class.forName("sun.awt.X11GraphicsDevice"); - x11GraphicsDeviceGetScreenMethod = x11GraphicsDeviceClass.getDeclaredMethod("getScreen", new Class[] {}); - x11GraphicsDeviceGetScreenMethod.setAccessible(true); x11GraphicsDeviceGetDisplayMethod = x11GraphicsDeviceClass.getDeclaredMethod("getDisplay", new Class[] {}); x11GraphicsDeviceGetDisplayMethod.setAccessible(true); @@ -83,18 +81,6 @@ public class X11SunJDKReflection { }); } - public static int graphicsDeviceGetScreen(GraphicsDevice device) { - if (!initted) { - return 0; - } - - try { - return ((Integer) x11GraphicsDeviceGetScreenMethod.invoke(device, null)).intValue(); - } catch (Exception e) { - return 0; - } - } - public static long graphicsDeviceGetDisplay(GraphicsDevice device) { if (!initted) { return 0; diff --git a/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java b/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java index c061f597f..ba047c1f6 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java +++ b/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java @@ -33,10 +33,13 @@ package javax.media.nativewindow; -import java.util.*; +import com.jogamp.common.util.ReflectionUtil; +import com.jogamp.nativewindow.impl.Debug; +import com.jogamp.nativewindow.impl.DefaultGraphicsConfigurationFactoryImpl; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; -import com.jogamp.common.util.*; -import com.jogamp.nativewindow.impl.*; /** * Provides the mechanism by which the graphics configuration for a @@ -88,7 +91,7 @@ public abstract class GraphicsConfigurationFactory { // AWTGraphicsDevice instances -- the OpenGL binding will take // care of handling AWTGraphicsDevices on X11 platforms (as // well as X11GraphicsDevices in non-AWT situations) - registerFactory(abstractGraphicsDeviceClass, new GraphicsConfigurationFactoryImpl()); + registerFactory(abstractGraphicsDeviceClass, new DefaultGraphicsConfigurationFactoryImpl()); } /** Returns the factory for use with the given type of @@ -232,4 +235,5 @@ public abstract class GraphicsConfigurationFactory { chooseGraphicsConfigurationImpl(CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested, CapabilitiesChooser chooser, AbstractGraphicsScreen screen) throws IllegalArgumentException, NativeWindowException; + } |