diff options
Diffstat (limited to 'src/jogl/classes/jogamp/opengl/windows')
17 files changed, 1219 insertions, 1251 deletions
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WGLGLCapabilities.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WGLGLCapabilities.java index 6a4ce5a4e..25b73a2a6 100644 --- a/src/jogl/classes/jogamp/opengl/windows/wgl/WGLGLCapabilities.java +++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WGLGLCapabilities.java @@ -28,6 +28,8 @@ package jogamp.opengl.windows.wgl; +import java.nio.IntBuffer; + import jogamp.nativewindow.windows.GDI; import jogamp.nativewindow.windows.PIXELFORMATDESCRIPTOR; @@ -42,7 +44,7 @@ public class WGLGLCapabilities extends GLCapabilities { final private int pfdID; private int arb_pixelformat; // -1 PFD, 0 NOP, 1 ARB - public WGLGLCapabilities(PIXELFORMATDESCRIPTOR pfd, int pfdID, GLProfile glp) { + public WGLGLCapabilities(final PIXELFORMATDESCRIPTOR pfd, final int pfdID, final GLProfile glp) { super(glp); this.pfd = pfd; this.pfdID = pfdID; @@ -56,17 +58,18 @@ public class WGLGLCapabilities extends GLCapabilities { setRedBits(pfd.getCRedBits()); setGreenBits(pfd.getCGreenBits()); setBlueBits(pfd.getCBlueBits()); - setAlphaBits(pfd.getCAlphaBits()); + setAlphaBits(pfd.getCAlphaBits()); setAccumRedBits(pfd.getCAccumRedBits()); setAccumGreenBits(pfd.getCAccumGreenBits()); setAccumBlueBits(pfd.getCAccumBlueBits()); setAccumAlphaBits(pfd.getCAccumAlphaBits()); setDepthBits(pfd.getCDepthBits()); setStencilBits(pfd.getCStencilBits()); - setDoubleBuffered((pfd.getDwFlags() & GDI.PFD_DOUBLEBUFFER) != 0); - setStereo((pfd.getDwFlags() & GDI.PFD_STEREO) != 0); - setHardwareAccelerated((pfd.getDwFlags() & GDI.PFD_GENERIC_FORMAT) == 0 - || (pfd.getDwFlags() & GDI.PFD_GENERIC_ACCELERATED) != 0); + final int dwFlags = pfd.getDwFlags(); + setDoubleBuffered((dwFlags & GDI.PFD_DOUBLEBUFFER) != 0); + setStereo((dwFlags & GDI.PFD_STEREO) != 0); + setHardwareAccelerated((dwFlags & GDI.PFD_GENERIC_FORMAT) == 0 + || (dwFlags & GDI.PFD_GENERIC_ACCELERATED) != 0); // n/a with non ARB/GDI method: // multisample // opaque @@ -75,12 +78,49 @@ public class WGLGLCapabilities extends GLCapabilities { return true; } - public boolean setValuesByARB(final int[] iattribs, final int niattribs, final int[] iresults) { + public static final String PFD2String(final PIXELFORMATDESCRIPTOR pfd, final int pfdID) { + final int dwFlags = pfd.getDwFlags(); + final StringBuilder sb = new StringBuilder(); + boolean sep = false; + + if( 0 != (GDI.PFD_DRAW_TO_WINDOW & dwFlags ) ) { + sep = true; + sb.append("window"); + } + if( 0 != (GDI.PFD_DRAW_TO_BITMAP & dwFlags ) ) { + if(sep) { sb.append(CSEP); } sep=true; + sb.append("bitmap"); + } + if( 0 != (GDI.PFD_SUPPORT_OPENGL & dwFlags ) ) { + if(sep) { sb.append(CSEP); } sep=true; + sb.append("opengl"); + } + if( 0 != (GDI.PFD_DOUBLEBUFFER & dwFlags ) ) { + if(sep) { sb.append(CSEP); } sep=true; + sb.append("dblbuf"); + } + if( 0 != (GDI.PFD_STEREO & dwFlags ) ) { + if(sep) { sb.append(CSEP); } sep=true; + sb.append("stereo"); + } + if( 0 == (GDI.PFD_GENERIC_FORMAT & dwFlags ) || 0 == (GDI.PFD_GENERIC_ACCELERATED & dwFlags ) ) { + if(sep) { sb.append(CSEP); } sep=true; + sb.append("hw-accel"); + } + return "PFD[id = "+pfdID+" (0x"+Integer.toHexString(pfdID)+ + "), colorBits "+pfd.getCColorBits()+", rgba "+pfd.getCRedBits()+ESEP+pfd.getCGreenBits()+ESEP+pfd.getCBlueBits()+ESEP+pfd.getCAlphaBits()+ + ", accum-rgba "+pfd.getCAccumRedBits()+ESEP+pfd.getCAccumGreenBits()+ESEP+pfd.getCAccumBlueBits()+ESEP+pfd.getCAccumAlphaBits()+ + ", dp/st/ms: "+pfd.getCDepthBits()+ESEP+pfd.getCStencilBits()+ESEP+"0"+ + ", flags: "+sb.toString(); + } + + public boolean setValuesByARB(final IntBuffer iattribs, final int niattribs, final IntBuffer iresults) { arb_pixelformat = 1; int alphaBits = 0; for (int i = 0; i < niattribs; i++) { - int attr = iattribs[i]; + final int attr = iattribs.get(i); + final int res = iresults.get(i); switch (attr) { case WGLExt.WGL_DRAW_TO_WINDOW_ARB: case WGLExt.WGL_DRAW_TO_BITMAP_ARB: @@ -88,93 +128,87 @@ public class WGLGLCapabilities extends GLCapabilities { break; case WGLExt.WGL_ACCELERATION_ARB: - setHardwareAccelerated(iresults[i] == WGLExt.WGL_FULL_ACCELERATION_ARB); + setHardwareAccelerated(res == WGLExt.WGL_FULL_ACCELERATION_ARB); break; case WGLExt.WGL_SUPPORT_OPENGL_ARB: - if (iresults[i] != GL.GL_TRUE) { + if (res != GL.GL_TRUE) { return false; } break; case WGLExt.WGL_DEPTH_BITS_ARB: - setDepthBits(iresults[i]); + setDepthBits(res); break; case WGLExt.WGL_STENCIL_BITS_ARB: - setStencilBits(iresults[i]); + setStencilBits(res); break; case WGLExt.WGL_DOUBLE_BUFFER_ARB: - setDoubleBuffered(iresults[i] == GL.GL_TRUE); + setDoubleBuffered(res == GL.GL_TRUE); break; case WGLExt.WGL_STEREO_ARB: - setStereo(iresults[i] == GL.GL_TRUE); + setStereo(res == GL.GL_TRUE); break; case WGLExt.WGL_PIXEL_TYPE_ARB: - if(iresults[i] == WGLExt.WGL_TYPE_COLORINDEX_ARB) { + if(res == WGLExt.WGL_TYPE_COLORINDEX_ARB) { return false; // color index not supported } - if (iresults[i] == WGLExt.WGL_TYPE_RGBA_FLOAT_ARB) { - setPbufferFloatingPointBuffers(true); + if (res == WGLExt.WGL_TYPE_RGBA_FLOAT_ARB) { + return false; // not supported } // normal RGBA FB: WGLExt.WGL_TYPE_RGBA_ARB // ignore unknown results here break; - case WGLExt.WGL_FLOAT_COMPONENTS_NV: - if (iresults[i] != 0) { - setPbufferFloatingPointBuffers(true); - } - break; - case WGLExt.WGL_RED_BITS_ARB: - setRedBits(iresults[i]); + setRedBits(res); break; case WGLExt.WGL_GREEN_BITS_ARB: - setGreenBits(iresults[i]); + setGreenBits(res); break; case WGLExt.WGL_BLUE_BITS_ARB: - setBlueBits(iresults[i]); + setBlueBits(res); break; case WGLExt.WGL_ALPHA_BITS_ARB: // ALPHA shall be set at last - due to it's auto setting by !opaque / samples - alphaBits = iresults[i]; + alphaBits = res; break; case WGLExt.WGL_ACCUM_RED_BITS_ARB: - setAccumRedBits(iresults[i]); + setAccumRedBits(res); break; case WGLExt.WGL_ACCUM_GREEN_BITS_ARB: - setAccumGreenBits(iresults[i]); + setAccumGreenBits(res); break; case WGLExt.WGL_ACCUM_BLUE_BITS_ARB: - setAccumBlueBits(iresults[i]); + setAccumBlueBits(res); break; case WGLExt.WGL_ACCUM_ALPHA_BITS_ARB: - setAccumAlphaBits(iresults[i]); + setAccumAlphaBits(res); break; case WGLExt.WGL_SAMPLE_BUFFERS_ARB: - setSampleBuffers(iresults[i] != 0); + setSampleBuffers(res != 0); break; case WGLExt.WGL_SAMPLES_ARB: - setNumSamples(iresults[i]); + setNumSamples(res); break; default: - throw new GLException("Unknown pixel format attribute " + iattribs[i]); + throw new GLException("Unknown pixel format attribute " + attr); } } setAlphaBits(alphaBits); @@ -190,7 +224,7 @@ public class WGLGLCapabilities extends GLCapabilities { public Object clone() { try { return super.clone(); - } catch (RuntimeException e) { + } catch (final RuntimeException e) { throw new GLException(e); } } @@ -203,7 +237,7 @@ public class WGLGLCapabilities extends GLCapabilities { final public boolean isSet() { return 0 != arb_pixelformat; } @Override - final public int getVisualID(VIDType type) throws NativeWindowException { + final public int getVisualID(final VIDType type) throws NativeWindowException { switch(type) { case INTRINSIC: case NATIVE: @@ -219,7 +253,7 @@ public class WGLGLCapabilities extends GLCapabilities { if(null == sink) { sink = new StringBuilder(); } - sink.append("wgl vid 0x").append(Integer.toHexString(pfdID)).append(" "); + sink.append("wgl vid ").append(pfdID).append(" "); switch (arb_pixelformat) { case -1: sink.append("gdi"); @@ -236,4 +270,4 @@ public class WGLGLCapabilities extends GLCapabilities { sink.append(": "); return super.toString(sink); } -}
\ No newline at end of file +} diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WGLUtil.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WGLUtil.java index f1598d580..08ff0e05b 100644 --- a/src/jogl/classes/jogamp/opengl/windows/wgl/WGLUtil.java +++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WGLUtil.java @@ -27,21 +27,23 @@ */ package jogamp.opengl.windows.wgl; +import com.jogamp.common.util.PropertyAccess; + import jogamp.nativewindow.windows.GDI; import jogamp.nativewindow.windows.PIXELFORMATDESCRIPTOR; import jogamp.opengl.Debug; public class WGLUtil { /** - * Switch to use the <code>wgl</code> variants of {@link jogamp.opengl.windows.wgl.WGL} + * Switch to use the <code>wgl</code> variants of {@link jogamp.opengl.windows.wgl.WGL} * to replace the following 5 GDI based functions (see below). * <p> * Disabled per default. - * </p> + * </p> * <p> * You can enable it by defining the property <code>jogl.windows.useWGLVersionOf5WGLGDIFuncSet</code>. * </p> - * + * * @see jogamp.nativewindow.windows.GDI#ChoosePixelFormat(long, PIXELFORMATDESCRIPTOR) * @see jogamp.nativewindow.windows.GDI#DescribePixelFormat(long, int, int, PIXELFORMATDESCRIPTOR) * @see jogamp.nativewindow.windows.GDI#GetPixelFormat(long) @@ -49,47 +51,48 @@ public class WGLUtil { * @see jogamp.nativewindow.windows.GDI#SwapBuffers(long) */ public static final boolean USE_WGLVersion_Of_5WGLGDIFuncSet; - + static { - USE_WGLVersion_Of_5WGLGDIFuncSet = Debug.isPropertyDefined("jogl.windows.useWGLVersionOf5WGLGDIFuncSet", true); + Debug.initSingleton(); + USE_WGLVersion_Of_5WGLGDIFuncSet = PropertyAccess.isPropertyDefined("jogl.windows.useWGLVersionOf5WGLGDIFuncSet", true); if(USE_WGLVersion_Of_5WGLGDIFuncSet) { System.err.println("Use WGL version of 5 WGL/GDI functions."); } } - public static int ChoosePixelFormat(long hdc, PIXELFORMATDESCRIPTOR pfd) { + public static int ChoosePixelFormat(final long hdc, final PIXELFORMATDESCRIPTOR pfd) { if(USE_WGLVersion_Of_5WGLGDIFuncSet) { return WGL.wglChoosePixelFormat(hdc, pfd); } else { return GDI.ChoosePixelFormat(hdc, pfd); - } + } } - public static int DescribePixelFormat(long hdc, int pfdid, int pfdSize, PIXELFORMATDESCRIPTOR pfd) { + public static int DescribePixelFormat(final long hdc, final int pfdid, final int pfdSize, final PIXELFORMATDESCRIPTOR pfd) { if(USE_WGLVersion_Of_5WGLGDIFuncSet) { return WGL.wglDescribePixelFormat(hdc, pfdid, pfdSize, pfd); } else { return GDI.DescribePixelFormat(hdc, pfdid, pfdSize, pfd); - } + } } - public static int GetPixelFormat(long hdc) { + public static int GetPixelFormat(final long hdc) { if(USE_WGLVersion_Of_5WGLGDIFuncSet) { return WGL.wglGetPixelFormat(hdc); } else { return GDI.GetPixelFormat(hdc); - } + } } - public static boolean SetPixelFormat(long hdc, int pfdid, PIXELFORMATDESCRIPTOR pfd) { + public static boolean SetPixelFormat(final long hdc, final int pfdid, final PIXELFORMATDESCRIPTOR pfd) { if(USE_WGLVersion_Of_5WGLGDIFuncSet) { return WGL.wglSetPixelFormat(hdc, pfdid, pfd); } else { return GDI.SetPixelFormat(hdc, pfdid, pfd); - } + } } - public static boolean SwapBuffers(long hdc) { + public static boolean SwapBuffers(final long hdc) { if(USE_WGLVersion_Of_5WGLGDIFuncSet) { return WGL.wglSwapBuffers(hdc); } else { return GDI.SwapBuffers(hdc); - } + } } } diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLContext.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLContext.java deleted file mode 100644 index 51341a098..000000000 --- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLContext.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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 jogamp.opengl.windows.wgl; - -import javax.media.opengl.*; - -public class WindowsBitmapWGLContext extends WindowsWGLContext { - public WindowsBitmapWGLContext(WindowsBitmapWGLDrawable drawable, - GLContext shareWith) { - super(drawable, shareWith); - } - - @Override - public int getOffscreenContextPixelDataType() { - return GL.GL_UNSIGNED_BYTE; - } - - @Override - public int getOffscreenContextReadBuffer() { - // On Windows these contexts are always single-buffered - return GL.GL_FRONT; - } - - @Override - public boolean offscreenImageNeedsVerticalFlip() { - // We can take care of this in the DIB creation (see below) - return false; - } -} diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLDrawable.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLDrawable.java index cf6f43b1c..0878f186c 100644 --- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLDrawable.java +++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLDrawable.java @@ -40,16 +40,19 @@ package jogamp.opengl.windows.wgl; +import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.NativeSurface; import javax.media.nativewindow.MutableSurface; import javax.media.opengl.GLCapabilitiesImmutable; import javax.media.opengl.GLContext; import javax.media.opengl.GLDrawableFactory; import javax.media.opengl.GLException; +import javax.media.opengl.GLProfile; import jogamp.nativewindow.windows.BITMAPINFO; import jogamp.nativewindow.windows.BITMAPINFOHEADER; import jogamp.nativewindow.windows.GDI; +import jogamp.opengl.GLGraphicsConfigurationUtil; import com.jogamp.common.nio.PointerBuffer; @@ -57,8 +60,28 @@ public class WindowsBitmapWGLDrawable extends WindowsWGLDrawable { private long origbitmap; private long hbitmap; - protected WindowsBitmapWGLDrawable(GLDrawableFactory factory, NativeSurface target) { - super(factory, target, false); + private WindowsBitmapWGLDrawable(final GLDrawableFactory factory, final NativeSurface comp) { + super(factory, comp, false); + } + + protected static WindowsBitmapWGLDrawable create(final GLDrawableFactory factory, final NativeSurface comp) { + final WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration)comp.getGraphicsConfiguration(); + final AbstractGraphicsDevice aDevice = config.getScreen().getDevice(); + if( !GLProfile.isAvailable(aDevice, GLProfile.GL2) ) { + throw new GLException("GLProfile GL2 n/a on "+aDevice+" but required for Windows BITMAP"); + } + final GLProfile glp = GLProfile.get(GLProfile.GL2); + final GLCapabilitiesImmutable capsChosen0 = (GLCapabilitiesImmutable)config.getChosenCapabilities(); + // RGB555 and also alpha channel is experienced to fail on some Windows machines + final GLCapabilitiesImmutable capsChosen1 = GLGraphicsConfigurationUtil.clipRGBAGLCapabilities(capsChosen0, false /* allowRGB555 */, false /* allowAlpha */); + final GLCapabilitiesImmutable capsChosen2 = GLGraphicsConfigurationUtil.fixGLProfile(capsChosen1, glp); + if( capsChosen0 != capsChosen2 ) { + config.setChosenCapabilities(capsChosen2); + if(DEBUG) { + System.err.println("WindowsBitmapWGLDrawable: "+capsChosen0+" -> "+capsChosen2); + } + } + return new WindowsBitmapWGLDrawable(factory, comp); } @Override @@ -71,35 +94,43 @@ public class WindowsBitmapWGLDrawable extends WindowsWGLDrawable { } @Override - public GLContext createContext(GLContext shareWith) { - return new WindowsBitmapWGLContext(this, shareWith); + public GLContext createContext(final GLContext shareWith) { + return new WindowsWGLContext(this, shareWith); + } + + @Override + public boolean isGLOriented() { + return false; } private void createBitmap() { int werr; - NativeSurface ns = getNativeSurface(); + final NativeSurface ns = getNativeSurface(); if(DEBUG) { - System.err.println("WindowsBitmapWGLDrawable (1): "+ns); + System.err.println(getThreadName()+": WindowsBitmapWGLDrawable (1): "+ns); } - WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration)ns.getGraphicsConfiguration(); - GLCapabilitiesImmutable capabilities = (GLCapabilitiesImmutable)config.getRequestedCapabilities(); - int width = getWidth(); - int height = getHeight(); + final WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration)ns.getGraphicsConfiguration(); + final GLCapabilitiesImmutable capsChosen = (GLCapabilitiesImmutable)config.getChosenCapabilities(); + final int width = getSurfaceWidth(); + final int height = getSurfaceHeight(); // // 1. Create DIB Section // - BITMAPINFO info = BITMAPINFO.create(); - BITMAPINFOHEADER header = info.getBmiHeader(); - int bitsPerPixel = (capabilities.getRedBits() + - capabilities.getGreenBits() + - capabilities.getBlueBits() + - capabilities.getAlphaBits()); + final BITMAPINFO info = BITMAPINFO.create(); + final BITMAPINFOHEADER header = info.getBmiHeader(); + final int bitsPerPixelIn = capsChosen.getRedBits() + + capsChosen.getGreenBits() + + capsChosen.getBlueBits(); + final int bitsPerPixel; + // Note: For BITMAP 32 bpp, the high-byte is _not_ used and hence maximum color is RGB888! + // Note: For BITAMP a biBitCount value other than 24 (RGB888) usually does not work! + bitsPerPixel = 24; // RGB888 only! header.setBiSize(BITMAPINFOHEADER.size()); header.setBiWidth(width); - // NOTE: negating the height causes the DIB to be in top-down row - // order rather than bottom-up; ends up being correct during pixel - // readback + // NOTE: Positive height causes the DIB's origin at bottom-left (OpenGL), + // a negative height causes the DIB's origin at top-left (Java AWT, Windows, ..). + // We use !OpenGL origin to remove the need for vertical flip, see 'isGLOriented()' above. header.setBiHeight(-1 * height); header.setBiPlanes((short) 1); header.setBiBitCount((short) bitsPerPixel); @@ -108,21 +139,21 @@ public class WindowsBitmapWGLDrawable extends WindowsWGLDrawable { header.setBiClrUsed(0); header.setBiClrImportant(0); header.setBiCompression(GDI.BI_RGB); - int byteNum = width * height * ( bitsPerPixel >> 3 ) ; + final int byteNum = width * height * ( bitsPerPixel >> 3 ) ; header.setBiSizeImage(byteNum); - PointerBuffer pb = PointerBuffer.allocateDirect(1); + final PointerBuffer pb = PointerBuffer.allocateDirect(1); hbitmap = GDI.CreateDIBSection(0, info, GDI.DIB_RGB_COLORS, pb, 0, 0); werr = GDI.GetLastError(); if(DEBUG) { - long p = ( pb.capacity() > 0 ) ? pb.get(0) : 0; + final long p = ( pb.capacity() > 0 ) ? pb.get(0) : 0; System.err.println("WindowsBitmapWGLDrawable: pb sz/ptr "+pb.capacity() + ", "+toHexString(p)); System.err.println("WindowsBitmapWGLDrawable: " + width+"x"+height + - ", bpp " + bitsPerPixel + + ", bpp " + bitsPerPixelIn + " -> " + bitsPerPixel + ", bytes " + byteNum + ", header sz " + BITMAPINFOHEADER.size() + ", DIB ptr num " + pb.capacity()+ - ", "+capabilities+ + ", "+capsChosen+ ", werr "+werr); } if (hbitmap == 0) { @@ -141,7 +172,7 @@ public class WindowsBitmapWGLDrawable extends WindowsWGLDrawable { } ((MutableSurface)ns).setSurfaceHandle(hdc); if(DEBUG) { - System.err.println("WindowsBitmapWGLDrawable (2): "+ns); + System.err.println(getThreadName()+": WindowsBitmapWGLDrawable (2): "+ns); } if ((origbitmap = GDI.SelectObject(hdc, hbitmap)) == 0) { @@ -156,7 +187,7 @@ public class WindowsBitmapWGLDrawable extends WindowsWGLDrawable { } protected void destroyBitmap() { - NativeSurface ns = getNativeSurface(); + final NativeSurface ns = getNativeSurface(); if (ns.getSurfaceHandle() != 0) { // Must destroy bitmap and device context GDI.SelectObject(ns.getSurfaceHandle(), origbitmap); diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java index f6cc2956d..4cebc6357 100644 --- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java +++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java @@ -50,26 +50,26 @@ import javax.media.opengl.GLDrawableFactory; import javax.media.opengl.GLException; import javax.media.opengl.GLProfile; - import jogamp.nativewindow.WrappedSurface; import jogamp.nativewindow.windows.GDI; import jogamp.opengl.GLContextShareSet; public class WindowsExternalWGLContext extends WindowsWGLContext { - private GLContext lastContext; - private WindowsExternalWGLContext(Drawable drawable, long ctx, WindowsWGLGraphicsConfiguration cfg) { + private WindowsExternalWGLContext(final Drawable drawable, final long ctx, final WindowsWGLGraphicsConfiguration cfg) { super(drawable, null); this.contextHandle = ctx; if (DEBUG) { System.err.println(getThreadName() + ": Created external OpenGL context " + toHexString(ctx) + " for " + this); } GLContextShareSet.contextCreated(this); - setGLFunctionAvailability(false, 0, 0, CTX_PROFILE_COMPAT); // use GL_VERSION + if( !setGLFunctionAvailability(false, 0, 0, CTX_PROFILE_COMPAT, false /* strictMatch */, false /* withinGLVersionsMapping */) ) { // use GL_VERSION + throw new InternalError("setGLFunctionAvailability !strictMatch failed"); + } getGLStateTracker().setEnabled(false); // external context usage can't track state in Java } - protected static WindowsExternalWGLContext create(GLDrawableFactory factory, GLProfile glp) { + protected static WindowsExternalWGLContext create(final GLDrawableFactory factory, final GLProfile glp) { if(DEBUG) { System.err.println("WindowsExternalWGLContext 0: werr: " + GDI.GetLastError()); } @@ -83,7 +83,7 @@ public class WindowsExternalWGLContext extends WindowsWGLContext { if (0 == hdc) { throw new GLException("Error: attempted to make an external GLDrawable without a drawable current, werr " + GDI.GetLastError()); } - AbstractGraphicsScreen aScreen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_WINDOWS); + final AbstractGraphicsScreen aScreen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_WINDOWS); WindowsWGLGraphicsConfiguration cfg; final int pfdID = WGLUtil.GetPixelFormat(hdc); if (0 == pfdID) { @@ -106,25 +106,6 @@ public class WindowsExternalWGLContext extends WindowsWGLContext { } @Override - public int makeCurrent() throws GLException { - // Save last context if necessary to allow external GLContexts to - // talk to other GLContexts created by this library - GLContext cur = getCurrent(); - if (cur != null && cur != this) { - lastContext = cur; - setCurrent(null); - } - return super.makeCurrent(); - } - - @Override - public void release() throws GLException { - super.release(); - setCurrent(lastContext); - lastContext = null; - } - - @Override protected void makeCurrentImpl() throws GLException { } @@ -138,26 +119,26 @@ public class WindowsExternalWGLContext extends WindowsWGLContext { // Need to provide the display connection to extension querying APIs static class Drawable extends WindowsWGLDrawable { - Drawable(GLDrawableFactory factory, NativeSurface comp) { + Drawable(final GLDrawableFactory factory, final NativeSurface comp) { super(factory, comp, true); } @Override - public GLContext createContext(GLContext shareWith) { + public GLContext createContext(final GLContext shareWith) { throw new GLException("Should not call this"); } @Override - public int getWidth() { + public int getSurfaceWidth() { throw new GLException("Should not call this"); } @Override - public int getHeight() { + public int getSurfaceHeight() { throw new GLException("Should not call this"); } - public void setSize(int width, int height) { + public void setSize(final int width, final int height) { throw new GLException("Should not call this"); } } diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLDrawable.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLDrawable.java index f8c237c9e..1378bcf3e 100644 --- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLDrawable.java +++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLDrawable.java @@ -51,21 +51,20 @@ import javax.media.opengl.GLProfile; import jogamp.nativewindow.WrappedSurface; import jogamp.nativewindow.windows.GDI; -import jogamp.nativewindow.windows.GDIUtil; public class WindowsExternalWGLDrawable extends WindowsWGLDrawable { - private WindowsExternalWGLDrawable(GLDrawableFactory factory, NativeSurface component) { + private WindowsExternalWGLDrawable(final GLDrawableFactory factory, final NativeSurface component) { super(factory, component, true); } - protected static WindowsExternalWGLDrawable create(GLDrawableFactory factory, GLProfile glp) { - long hdc = WGL.wglGetCurrentDC(); + protected static WindowsExternalWGLDrawable create(final GLDrawableFactory factory, final GLProfile glp) { + final long hdc = WGL.wglGetCurrentDC(); if (0==hdc) { throw new GLException("Error: attempted to make an external GLDrawable without a drawable current, werr " + GDI.GetLastError()); } - int pfdID = WGLUtil.GetPixelFormat(hdc); + final int pfdID = WGLUtil.GetPixelFormat(hdc); if (pfdID == 0) { throw new GLException("Error: attempted to make an external GLContext without a valid pixelformat, werr " + GDI.GetLastError()); } @@ -77,21 +76,21 @@ public class WindowsExternalWGLDrawable extends WindowsWGLDrawable { @Override - public GLContext createContext(GLContext shareWith) { + public GLContext createContext(final GLContext shareWith) { return new WindowsWGLContext(this, shareWith); } - public void setSize(int newWidth, int newHeight) { + public void setSize(final int newWidth, final int newHeight) { throw new GLException("Should not call this"); } @Override - public int getWidth() { + public int getSurfaceWidth() { throw new GLException("Should not call this"); } @Override - public int getHeight() { + public int getSurfaceHeight() { throw new GLException("Should not call this"); } } diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsOnscreenWGLContext.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsOnscreenWGLContext.java deleted file mode 100644 index aef55efc6..000000000 --- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsOnscreenWGLContext.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2003 Sun Microsystems, Inc. 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 jogamp.opengl.windows.wgl; - -import javax.media.opengl.*; - -public class WindowsOnscreenWGLContext extends WindowsWGLContext { - public WindowsOnscreenWGLContext(WindowsOnscreenWGLDrawable drawable, - GLContext shareWith) { - super(drawable, shareWith); - } -} diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsOnscreenWGLDrawable.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsOnscreenWGLDrawable.java index ddbb29d51..0d0681df9 100644 --- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsOnscreenWGLDrawable.java +++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsOnscreenWGLDrawable.java @@ -45,13 +45,13 @@ import javax.media.opengl.GLContext; import javax.media.opengl.GLDrawableFactory; public class WindowsOnscreenWGLDrawable extends WindowsWGLDrawable { - protected WindowsOnscreenWGLDrawable(GLDrawableFactory factory, NativeSurface component) { + protected WindowsOnscreenWGLDrawable(final GLDrawableFactory factory, final NativeSurface component) { super(factory, component, false); } @Override - public GLContext createContext(GLContext shareWith) { - return new WindowsOnscreenWGLContext(this, shareWith); + public GLContext createContext(final GLContext shareWith) { + return new WindowsWGLContext(this, shareWith); } } diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLContext.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLContext.java deleted file mode 100644 index 7dda6a1f1..000000000 --- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLContext.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * 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 jogamp.opengl.windows.wgl; - -import javax.media.opengl.*; - -import com.jogamp.opengl.GLExtensions; - -import jogamp.opengl.GLContextImpl; - -public class WindowsPbufferWGLContext extends WindowsWGLContext { - // State for render-to-texture and render-to-texture-rectangle support - private boolean rtt; // render-to-texture? - private boolean hasRTT; // render-to-texture extension available? - private boolean rect; // render-to-texture-rectangle? - private int textureTarget; // e.g. GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE_NV - private int texture; // actual texture object - - protected WindowsPbufferWGLContext(WindowsPbufferWGLDrawable drawable, - GLContext shareWith) { - super(drawable, shareWith); - } - - @Override - public void bindPbufferToTexture() { - if (!rtt) { - throw new GLException("Shouldn't try to bind a pbuffer to a texture if render-to-texture hasn't been " + - "specified in its GLCapabilities"); - } - GL gl = getGL(); - WGLExt wglExt = getWGLExt(); - gl.glBindTexture(textureTarget, texture); - if (rtt && hasRTT) { - if (!wglExt.wglBindTexImageARB(((WindowsPbufferWGLDrawable)drawable).getPbufferHandle(), WGLExt.WGL_FRONT_LEFT_ARB)) { - throw new GLException("Binding of pbuffer to texture failed: " + wglGetLastError()); - } - } - // FIXME: comment is wrong now - // Note that if the render-to-texture extension is not supported, - // we perform a glCopyTexImage2D in swapBuffers(). - } - - @Override - public void releasePbufferFromTexture() { - if (!rtt) { - throw new GLException("Shouldn't try to bind a pbuffer to a texture if render-to-texture hasn't been " + - "specified in its GLCapabilities"); - } - if (rtt && hasRTT) { - WGLExt wglExt = getWGLExt(); - if (!wglExt.wglReleaseTexImageARB(((WindowsPbufferWGLDrawable)drawable).getPbufferHandle(), WGLExt.WGL_FRONT_LEFT_ARB)) { - throw new GLException("Releasing of pbuffer from texture failed: " + wglGetLastError()); - } - } - } - - @Override - protected boolean createImpl(GLContextImpl shareWith) { - boolean res = super.createImpl(shareWith); - if(res) { - GLCapabilitiesImmutable capabilities = drawable.getChosenGLCapabilities(); - - // Initialize render-to-texture support if requested - GL gl = getGL(); - rtt = capabilities.getPbufferRenderToTexture(); - rect = gl.isGL2GL3() && capabilities.getPbufferRenderToTextureRectangle(); - - if (rtt) { - if (DEBUG) { - System.err.println("Initializing render-to-texture support"); - } - - if (!gl.isExtensionAvailable("WGL_ARB_render_texture")) { - System.err.println("WindowsPbufferWGLContext: WARNING: WGL_ARB_render_texture extension not " + - "supported; implementing render_to_texture support using slow texture readback"); - } else { - hasRTT = true; - - if (rect && !gl.isExtensionAvailable(GLExtensions.NV_texture_rectangle)) { - System.err.println("WindowsPbufferWGLContext: WARNING: GL_NV_texture_rectangle extension not " + - "supported; skipping requested render_to_texture_rectangle support for pbuffer"); - rect = false; - } - if (rect) { - if (DEBUG) { - System.err.println(" Using render-to-texture-rectangle"); - } - textureTarget = GL2GL3.GL_TEXTURE_RECTANGLE_ARB; - } else { - if (DEBUG) { - System.err.println(" Using vanilla render-to-texture"); - } - textureTarget = GL.GL_TEXTURE_2D; - } - int[] tmp = new int[1]; - gl.glGenTextures(1, tmp, 0); - texture = tmp[0]; - gl.glBindTexture(textureTarget, texture); - gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST); - gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST); - gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE); - gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE); - gl.glCopyTexImage2D(textureTarget, 0, GL.GL_RGB, 0, 0, drawable.getWidth(), drawable.getHeight(), 0); - } - } - } - return res; - } - - @Override - public int getFloatingPointMode() { - return ((WindowsPbufferWGLDrawable)drawable).getFloatingPointMode(); - } - - private static String wglGetLastError() { - return WindowsWGLDrawableFactory.wglGetLastError(); - } -} diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java index 75c1c4441..775e2936c 100644 --- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java +++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java @@ -40,31 +40,32 @@ package jogamp.opengl.windows.wgl; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; + import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.NativeSurface; import javax.media.nativewindow.NativeWindowException; import javax.media.nativewindow.MutableSurface; -import javax.media.opengl.GL; import javax.media.opengl.GLCapabilitiesImmutable; import javax.media.opengl.GLContext; import javax.media.opengl.GLDrawableFactory; import javax.media.opengl.GLException; import javax.media.opengl.GLProfile; +import com.jogamp.common.nio.Buffers; + import jogamp.nativewindow.windows.GDI; import jogamp.opengl.GLDrawableImpl; import jogamp.opengl.GLGraphicsConfigurationUtil; import jogamp.opengl.windows.wgl.WindowsWGLDrawableFactory.SharedResource; -// import javax.media.opengl.GLPbuffer; public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable { private WGLExt cachedWGLExt; // cached WGLExt instance from parent GLCanvas, // needed to destroy pbuffer private long buffer; // pbuffer handle - private int floatMode; - - protected WindowsPbufferWGLDrawable(GLDrawableFactory factory, NativeSurface target) { + protected WindowsPbufferWGLDrawable(final GLDrawableFactory factory, final NativeSurface target) { super(factory, target, false); } @@ -78,14 +79,14 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable { } @Override - public GLContext createContext(GLContext shareWith) { - return new WindowsPbufferWGLContext(this, shareWith); + public GLContext createContext(final GLContext shareWith) { + return new WindowsWGLContext(this, shareWith); } protected void destroyPbuffer() { - NativeSurface ns = getNativeSurface(); + final NativeSurface ns = getNativeSurface(); if(0!=buffer) { - WGLExt wglExt = cachedWGLExt; + final WGLExt wglExt = cachedWGLExt; if (ns.getSurfaceHandle() != 0) { // Must release DC and pbuffer // NOTE that since the context is not current, glGetError() can @@ -110,30 +111,26 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable { return buffer; } - public int getFloatingPointMode() { - return floatMode; - } - private void createPbuffer() { - WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration) getNativeSurface().getGraphicsConfiguration(); - SharedResource sharedResource = ((WindowsWGLDrawableFactory)factory).getOrCreateSharedResource(config.getScreen().getDevice()); - NativeSurface sharedSurface = sharedResource.getDrawable().getNativeSurface(); + final WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration) getNativeSurface().getGraphicsConfiguration(); + final SharedResource sharedResource = ((WindowsWGLDrawableFactory)factory).getOrCreateSharedResourceImpl(config.getScreen().getDevice()); + final NativeSurface sharedSurface = sharedResource.getDrawable().getNativeSurface(); if (NativeSurface.LOCK_SURFACE_NOT_READY >= sharedSurface.lockSurface()) { throw new NativeWindowException("Could not lock (sharedSurface): "+this); } try { - long sharedHdc = sharedSurface.getSurfaceHandle(); - WGLExt wglExt = ((WindowsWGLContext)sharedResource.getContext()).getWGLExt(); + final long sharedHdc = sharedSurface.getSurfaceHandle(); + final WGLExt wglExt = ((WindowsWGLContext)sharedResource.getContext()).getWGLExt(); if (DEBUG) { - System.out.println("Pbuffer config: " + config); + System.err.println(getThreadName()+": Pbuffer config: " + config); } final int winattrPbuffer = GLGraphicsConfigurationUtil.getExclusiveWinAttributeBits(false /* onscreen */, false /* fbo */, true /* pbuffer */, false /* bitmap */); - - int[] iattributes = new int [2*WindowsWGLGraphicsConfiguration.MAX_ATTRIBS]; - float[] fattributes = new float[1]; - int[] floatModeTmp = new int[1]; + + final IntBuffer iattributes = Buffers.newDirectIntBuffer(2*WindowsWGLGraphicsConfiguration.MAX_ATTRIBS); + final FloatBuffer fattributes = Buffers.newDirectFloatBuffer(1); + final int[] floatModeTmp = new int[1]; int niattribs = 0; final GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable)config.getChosenCapabilities(); @@ -141,38 +138,23 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable { final AbstractGraphicsDevice device = config.getScreen().getDevice(); if (DEBUG) { - System.out.println("Pbuffer parentHdc = " + toHexString(sharedHdc)); - System.out.println("Pbuffer chosenCaps: " + chosenCaps); + System.err.println(getThreadName()+": Pbuffer parentHdc = " + toHexString(sharedHdc)); + System.err.println(getThreadName()+": Pbuffer chosenCaps: " + chosenCaps); } - if(!WindowsWGLGraphicsConfiguration.GLCapabilities2AttribList(chosenCaps, - iattributes, sharedResource, -1, floatModeTmp)){ + if( !WindowsWGLGraphicsConfiguration.GLCapabilities2AttribList( sharedResource, chosenCaps, + iattributes, -1, floatModeTmp) ) { throw new GLException("Pbuffer-related extensions not supported"); } - floatMode = floatModeTmp[0]; - boolean rtt = chosenCaps.getPbufferRenderToTexture(); - boolean rect = chosenCaps.getPbufferRenderToTextureRectangle(); - boolean useFloat = chosenCaps.getPbufferFloatingPointBuffers(); - // boolean ati = false; - - /** - if (useFloat) { - ati = (floatMode == GLPbuffer.ATI_FLOAT); - } */ - - int[] pformats = new int[WindowsWGLGraphicsConfiguration.MAX_PFORMATS]; - int nformats; - int[] nformatsTmp = new int[1]; + final IntBuffer pformats = Buffers.newDirectIntBuffer(WindowsWGLGraphicsConfiguration.MAX_PFORMATS); + final IntBuffer nformatsTmp = Buffers.newDirectIntBuffer(1); if (!wglExt.wglChoosePixelFormatARB(sharedHdc, - iattributes, 0, - fattributes, 0, - WindowsWGLGraphicsConfiguration.MAX_PFORMATS, - pformats, 0, - nformatsTmp, 0)) { + iattributes, fattributes, WindowsWGLGraphicsConfiguration.MAX_PFORMATS, + pformats, nformatsTmp)) { throw new GLException("pbuffer creation error: wglChoosePixelFormat() failed"); } - nformats = nformatsTmp[0]; + final int nformats = Math.min(nformatsTmp.get(0), WindowsWGLGraphicsConfiguration.MAX_PFORMATS); if (nformats <= 0) { throw new GLException("pbuffer creation error: Couldn't find a suitable pixel format"); } @@ -180,9 +162,9 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable { if (DEBUG) { System.err.println("" + nformats + " suitable pixel formats found"); for (int i = 0; i < nformats; i++) { - WGLGLCapabilities dbgCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedResource, device, glProfile, - sharedHdc, pformats[i], winattrPbuffer); - System.err.println("pixel format " + pformats[i] + " (index " + i + "): " + dbgCaps); + final WGLGLCapabilities dbgCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilitiesNoCheck(sharedResource, device, glProfile, + sharedHdc, pformats.get(i), winattrPbuffer); + System.err.println("pixel format " + pformats.get(i) + " (index " + i + "): " + dbgCaps); } } @@ -192,32 +174,14 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable { int whichFormat; // Loop is a workaround for bugs in NVidia's recent drivers for (whichFormat = 0; whichFormat < nformats; whichFormat++) { - int format = pformats[whichFormat]; + final int format = pformats.get(whichFormat); // Create the p-buffer. niattribs = 0; - if (rtt) { - iattributes[niattribs++] = WGLExt.WGL_TEXTURE_FORMAT_ARB; - if (useFloat) { - iattributes[niattribs++] = WGLExt.WGL_TEXTURE_FLOAT_RGB_NV; - } else { - iattributes[niattribs++] = WGLExt.WGL_TEXTURE_RGBA_ARB; - } - - iattributes[niattribs++] = WGLExt.WGL_TEXTURE_TARGET_ARB; - iattributes[niattribs++] = rect ? WGLExt.WGL_TEXTURE_RECTANGLE_NV : WGLExt.WGL_TEXTURE_2D_ARB; - - iattributes[niattribs++] = WGLExt.WGL_MIPMAP_TEXTURE_ARB; - iattributes[niattribs++] = GL.GL_FALSE; - - iattributes[niattribs++] = WGLExt.WGL_PBUFFER_LARGEST_ARB; // exact - iattributes[niattribs++] = GL.GL_FALSE; - } - - iattributes[niattribs++] = 0; + iattributes.put(niattribs++, 0); - tmpBuffer = wglExt.wglCreatePbufferARB(sharedHdc, format, getWidth(), getHeight(), iattributes, 0); + tmpBuffer = wglExt.wglCreatePbufferARB(sharedHdc, format, getSurfaceWidth(), getSurfaceHeight(), iattributes); if (tmpBuffer != 0) { // Done break; @@ -228,16 +192,16 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable { throw new GLException("pbuffer creation error: wglCreatePbuffer() failed: tried " + nformats + " pixel formats, last error was: " + wglGetLastError()); } - pfdid = pformats[whichFormat]; + pfdid = pformats.get(whichFormat); } // Get the device context. - long tmpHdc = wglExt.wglGetPbufferDCARB(tmpBuffer); + final long tmpHdc = wglExt.wglGetPbufferDCARB(tmpBuffer); if (tmpHdc == 0) { throw new GLException("pbuffer creation error: wglGetPbufferDC() failed"); } - NativeSurface ns = getNativeSurface(); + final NativeSurface ns = getNativeSurface(); // Set up instance variables buffer = tmpBuffer; ((MutableSurface)ns).setSurfaceHandle(tmpHdc); @@ -245,7 +209,7 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable { // Re-query chosen pixel format { - WGLGLCapabilities newCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedResource, device, glProfile, + final WGLGLCapabilities newCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedResource, device, glProfile, sharedHdc, pfdid, winattrPbuffer); if(null == newCaps) { throw new GLException("pbuffer creation error: unable to re-query chosen PFD ID: " + pfdid + ", hdc " + GLDrawableImpl.toHexString(tmpHdc)); diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java index 8825bad0a..ebd107c47 100644 --- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java +++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java @@ -41,6 +41,7 @@ package jogamp.opengl.windows.wgl; import java.nio.ByteBuffer; +import java.nio.IntBuffer; import java.util.HashMap; import java.util.Map; @@ -50,10 +51,13 @@ import javax.media.nativewindow.NativeSurface; import javax.media.opengl.GLContext; import javax.media.opengl.GLException; import javax.media.opengl.GLCapabilitiesImmutable; +import javax.media.opengl.GLProfile; +import com.jogamp.common.nio.Buffers; import com.jogamp.gluegen.runtime.ProcAddressTable; import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver; import com.jogamp.opengl.GLExtensions; +import com.jogamp.opengl.GLRendererQuirks; import jogamp.nativewindow.windows.GDI; import jogamp.opengl.GLContextImpl; @@ -84,13 +88,13 @@ public class WindowsWGLContext extends GLContextImpl { } // FIXME: figure out how to hook back in the Java 2D / JOGL bridge - WindowsWGLContext(GLDrawableImpl drawable, - GLContext shareWith) { + WindowsWGLContext(final GLDrawableImpl drawable, + final GLContext shareWith) { super(drawable, shareWith); } @Override - protected void resetStates() { + protected void resetStates(final boolean isInit) { wglGetExtensionsStringEXTInitialized=false; wglGetExtensionsStringEXTAvailable=false; wglGLReadDrawableAvailableSet=false; @@ -99,7 +103,7 @@ public class WindowsWGLContext extends GLContextImpl { wglExtProcAddressTable=null; hasSwapIntervalSGI = 0; hasSwapGroupNV = 0; - super.resetStates(); + super.resetStates(isInit); } @Override @@ -120,9 +124,9 @@ public class WindowsWGLContext extends GLContextImpl { @Override public final boolean isGLReadDrawableAvailable() { if(!wglGLReadDrawableAvailableSet && null != getWGLExtProcAddressTable()) { - WindowsWGLDrawableFactory factory = (WindowsWGLDrawableFactory)drawable.getFactoryImpl(); - AbstractGraphicsConfiguration config = drawable.getNativeSurface().getGraphicsConfiguration(); - AbstractGraphicsDevice device = config.getScreen().getDevice(); + final WindowsWGLDrawableFactory factory = (WindowsWGLDrawableFactory)drawable.getFactoryImpl(); + final AbstractGraphicsConfiguration config = drawable.getNativeSurface().getGraphicsConfiguration(); + final AbstractGraphicsDevice device = config.getScreen().getDevice(); switch( factory.isReadDrawableAvailable(device) ) { case 1: wglGLReadDrawableAvailable = true; @@ -137,7 +141,7 @@ public class WindowsWGLContext extends GLContextImpl { return wglGLReadDrawableAvailable; } - private final boolean wglMakeContextCurrent(long hDrawDC, long hReadDC, long ctx) { + private final boolean wglMakeContextCurrent(final long hDrawDC, final long hReadDC, final long ctx) { boolean ok = false; if(wglGLReadDrawableAvailable) { // needs initilized WGL ProcAddress table @@ -148,9 +152,9 @@ public class WindowsWGLContext extends GLContextImpl { // should not happen due to 'isGLReadDrawableAvailable()' query in GLContextImpl throw new InternalError("Given readDrawable but no driver support"); } - int werr = ( !ok ) ? GDI.GetLastError() : GDI.ERROR_SUCCESS; + final int werr = ( !ok ) ? GDI.GetLastError() : GDI.ERROR_SUCCESS; if(DEBUG && !ok) { - Throwable t = new Throwable ("Info: wglMakeContextCurrent draw "+ + final Throwable t = new Throwable ("Info: wglMakeContextCurrent draw "+ GLContext.toHexString(hDrawDC) + ", read " + GLContext.toHexString(hReadDC) + ", ctx " + GLContext.toHexString(ctx) + ", werr " + werr); t.printStackTrace(); @@ -179,26 +183,26 @@ public class WindowsWGLContext extends GLContextImpl { protected Map<String, String> getExtensionNameMap() { return extensionNameMap; } @Override - protected void destroyContextARBImpl(long context) { + protected void destroyContextARBImpl(final long context) { WGL.wglMakeCurrent(0, 0); WGL.wglDeleteContext(context); } @Override - protected long createContextARBImpl(long share, boolean direct, int ctp, int major, int minor) { + protected long createContextARBImpl(final long share, final boolean direct, final int ctp, final int major, final int minor) { if( null == getWGLExtProcAddressTable()) { updateGLXProcAddressTable(); } - WGLExt _wglExt = getWGLExt(); + final WGLExt _wglExt = getWGLExt(); if(DEBUG) { System.err.println(getThreadName()+" - WindowWGLContext.createContextARBImpl: "+getGLVersion(major, minor, ctp, "@creation") + ", handle "+toHexString(drawable.getHandle()) + ", share "+toHexString(share)+", direct "+direct+ ", wglCreateContextAttribsARB: "+toHexString(wglExtProcAddressTable._addressof_wglCreateContextAttribsARB)); } - boolean ctBwdCompat = 0 != ( CTX_PROFILE_COMPAT & ctp ) ; - boolean ctFwdCompat = 0 != ( CTX_OPTION_FORWARD & ctp ) ; - boolean ctDebug = 0 != ( CTX_OPTION_DEBUG & ctp ) ; + final boolean ctBwdCompat = 0 != ( CTX_PROFILE_COMPAT & ctp ) ; + final boolean ctFwdCompat = 0 != ( CTX_OPTION_FORWARD & ctp ) ; + final boolean ctDebug = 0 != ( CTX_OPTION_DEBUG & ctp ) ; long ctx=0; @@ -207,7 +211,7 @@ public class WindowsWGLContext extends GLContextImpl { /* WGLExt.WGL_CONTEXT_LAYER_PLANE_ARB, WGLExt.WGL_CONTEXT_LAYER_PLANE_ARB, */ - int attribs[] = { + final int attribs[] = { /* 0 */ WGLExt.WGL_CONTEXT_MAJOR_VERSION_ARB, major, /* 2 */ WGLExt.WGL_CONTEXT_MINOR_VERSION_ARB, minor, /* 4 */ WGLExt.WGL_CONTEXT_FLAGS_ARB, 0, @@ -216,7 +220,6 @@ public class WindowsWGLContext extends GLContextImpl { }; if ( major > 3 || major == 3 && minor >= 2 ) { - // FIXME: Verify with a None drawable binding (default framebuffer) attribs[idx_profile+0] = WGLExt.WGL_CONTEXT_PROFILE_MASK_ARB; if( ctBwdCompat ) { attribs[idx_profile+1] = WGLExt.WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; @@ -235,10 +238,11 @@ public class WindowsWGLContext extends GLContextImpl { } try { - ctx = _wglExt.wglCreateContextAttribsARB(drawable.getHandle(), share, attribs, 0); - } catch (RuntimeException re) { + final IntBuffer attribsNIO = Buffers.newDirectIntBuffer(attribs); + ctx = _wglExt.wglCreateContextAttribsARB(drawable.getHandle(), share, attribsNIO); + } catch (final RuntimeException re) { if(DEBUG) { - Throwable t = new Throwable("Info: WindowWGLContext.createContextARBImpl wglCreateContextAttribsARB failed with "+getGLVersion(major, minor, ctp, "@creation"), re); + final Throwable t = new Throwable("Info: WindowWGLContext.createContextARBImpl wglCreateContextAttribsARB failed with "+getGLVersion(major, minor, ctp, "@creation"), re); t.printStackTrace(); } } @@ -265,74 +269,93 @@ public class WindowsWGLContext extends GLContextImpl { * called by {@link #makeCurrentImpl()}. */ @Override - protected boolean createImpl(GLContextImpl shareWith) { - AbstractGraphicsConfiguration config = drawable.getNativeSurface().getGraphicsConfiguration(); - AbstractGraphicsDevice device = config.getScreen().getDevice(); - WindowsWGLDrawableFactory factory = (WindowsWGLDrawableFactory)drawable.getFactoryImpl(); - WindowsWGLContext sharedContext = (WindowsWGLContext) factory.getOrCreateSharedContextImpl(device); - GLCapabilitiesImmutable glCaps = drawable.getChosenGLCapabilities(); + protected boolean createImpl(long shareWithHandle) { + final AbstractGraphicsConfiguration config = drawable.getNativeSurface().getGraphicsConfiguration(); + final AbstractGraphicsDevice device = config.getScreen().getDevice(); + final WindowsWGLDrawableFactory factory = (WindowsWGLDrawableFactory)drawable.getFactoryImpl(); + final WindowsWGLContext sharedContext = (WindowsWGLContext) factory.getOrCreateSharedContext(device); + final GLCapabilitiesImmutable glCaps = drawable.getChosenGLCapabilities(); isGLReadDrawableAvailable(); // trigger setup wglGLReadDrawableAvailable - // Windows can set up sharing of display lists after creation time - long share = 0; - if (null != shareWith) { - share = shareWith.getHandle(); - if (share == 0) { - throw new GLException("GLContextShareSet returned an invalid OpenGL context"); - } + if (DEBUG) { + System.err.println(getThreadName() + ": createImpl: START "+glCaps+", share "+toHexString(shareWithHandle)); } boolean createContextARBTried = false; - // utilize the shared context's GLXExt in case it was using the ARB method and it already exists - if( null!=sharedContext && sharedContext.isCreatedWithARBMethod() ) { - contextHandle = createContextARB(share, true); + // utilize the shared context's GLXExt in case it was using the ARB method and it already exists ; exclude BITMAP + if( null != sharedContext && sharedContext.isCreatedWithARBMethod() && !glCaps.isBitmap() ) { + if ( sharedContext.getRendererQuirks().exist( GLRendererQuirks.NeedCurrCtx4ARBCreateContext ) ) { + if(GLContext.CONTEXT_NOT_CURRENT == sharedContext.makeCurrent()) { + throw new GLException("Could not make Shared Context current: "+sharedContext); + } + contextHandle = createContextARB(shareWithHandle, true); + sharedContext.release(); + if (!wglMakeContextCurrent(drawable.getHandle(), drawableRead.getHandle(), contextHandle)) { + throw new GLException("Cannot make previous verified context current: 0x" + toHexString(contextHandle) + ", werr: " + GDI.GetLastError()); + } + } else { + contextHandle = createContextARB(shareWithHandle, true); + } createContextARBTried = true; - if (DEBUG && 0!=contextHandle) { - System.err.println(getThreadName() + ": createImpl: OK (ARB, using sharedContext) share "+share); + if ( DEBUG && 0 != contextHandle ) { + System.err.println(getThreadName() + ": createImpl: OK (ARB, using sharedContext) share "+toHexString(shareWithHandle)); } } - long temp_ctx = 0; - if(0==contextHandle) { + final long temp_ctx; + if( 0 == contextHandle ) { // To use WGL_ARB_create_context, we have to make a temp context current, // so we are able to use GetProcAddress temp_ctx = WGL.wglCreateContext(drawable.getHandle()); - if (temp_ctx == 0) { + if ( 0 == temp_ctx ) { throw new GLException("Unable to create temp OpenGL context for device context " + toHexString(drawable.getHandle())); } - if (!WGL.wglMakeCurrent(drawable.getHandle(), temp_ctx)) { + if ( !WGL.wglMakeCurrent(drawable.getHandle(), temp_ctx) ) { throw new GLException("Error making temp context current: 0x" + toHexString(temp_ctx) + ", werr: "+GDI.GetLastError()); } - setGLFunctionAvailability(true, 0, 0, CTX_PROFILE_COMPAT); // use GL_VERSION + if( !setGLFunctionAvailability(true, 0, 0, CTX_PROFILE_COMPAT, false /* strictMatch */, null == sharedContext /* withinGLVersionsMapping */) ) { // use GL_VERSION + throw new InternalError("setGLFunctionAvailability !strictMatch failed"); + } WGL.wglMakeCurrent(0, 0); // release temp context - if( !createContextARBTried) { + if( !createContextARBTried ) { // is*Available calls are valid since setGLFunctionAvailability(..) was called - final boolean isProcCreateContextAttribsARBAvailable = isFunctionAvailable("wglCreateContextAttribsARB"); - final boolean isExtARBCreateContextAvailable = isExtensionAvailable("WGL_ARB_create_context"); - if ( isProcCreateContextAttribsARBAvailable && isExtARBCreateContextAvailable ) { + final boolean isProcCreateContextAttribsARBAvailable; + final boolean isExtARBCreateContextAvailable; + if( !glCaps.isBitmap() ) { // exclude ARB if BITMAP + isProcCreateContextAttribsARBAvailable = isFunctionAvailable("wglCreateContextAttribsARB"); + isExtARBCreateContextAvailable = isExtensionAvailable("WGL_ARB_create_context"); + } else { + isProcCreateContextAttribsARBAvailable = false; + isExtARBCreateContextAvailable = false; + } + if ( isProcCreateContextAttribsARBAvailable && isExtARBCreateContextAvailable && !GLProfile.disableOpenGLARBContext && !getRendererQuirks().exist( GLRendererQuirks.NoARBCreateContext ) ) { // initial ARB context creation - contextHandle = createContextARB(share, true); + contextHandle = createContextARB(shareWithHandle, true); createContextARBTried=true; if (DEBUG) { - if(0!=contextHandle) { - System.err.println(getThreadName() + ": createContextImpl: OK (ARB, initial) share "+share); + if( 0 != contextHandle ) { + System.err.println(getThreadName() + ": createContextImpl: OK (ARB, initial) share "+toHexString(shareWithHandle)); } else { - System.err.println(getThreadName() + ": createContextImpl: NOT OK (ARB, initial) - creation failed - share "+share); + System.err.println(getThreadName() + ": createContextImpl: NOT OK (ARB, initial) - creation failed - share "+toHexString(shareWithHandle)); } } } else if (DEBUG) { - System.err.println(getThreadName() + ": createContextImpl: NOT OK (ARB, initial) - extension not available - share "+share+ - ", isProcCreateContextAttribsARBAvailable "+isProcCreateContextAttribsARBAvailable+", isExtGLXARBCreateContextAvailable "+isExtARBCreateContextAvailable); + System.err.println(getThreadName() + ": createContextImpl: NOT OK (ARB, initial) - extension not available - share "+toHexString(shareWithHandle)+ + ", isProcCreateContextAttribsARBAvailable "+isProcCreateContextAttribsARBAvailable+ + ", isExtGLXARBCreateContextAvailable "+isExtARBCreateContextAvailable+ + ", disableOpenGLARBContext "+GLProfile.disableOpenGLARBContext); } } + } else { + temp_ctx = 0; } - if(0!=contextHandle) { - share = 0; // mark as shared thx to the ARB create method - if(0!=temp_ctx) { + if( 0 != contextHandle ) { + shareWithHandle = 0; // mark as shared thx to the ARB create method + if( 0 != temp_ctx ) { WGL.wglMakeCurrent(0, 0); WGL.wglDeleteContext(temp_ctx); if (!wglMakeContextCurrent(drawable.getHandle(), drawableRead.getHandle(), contextHandle)) { @@ -340,32 +363,35 @@ public class WindowsWGLContext extends GLContextImpl { } } } else { - if(glCaps.getGLProfile().isGL3()) { - WGL.wglMakeCurrent(0, 0); - WGL.wglDeleteContext(temp_ctx); - throw new GLException("WindowsWGLContext.createContext ctx !ARB, context > GL2 requested "+getGLVersion()); + if( glCaps.getGLProfile().isGL3() && createContextARBTried ) { + // We shall not allow context creation >= GL3 w/ non ARB methods if ARB is used, + // otherwise context of similar profile but different creation method may not be share-able. + WGL.wglMakeCurrent(0, 0); + WGL.wglDeleteContext(temp_ctx); + throw new GLException(getThreadName()+": WindowsWGLContex.createContextImpl ctx !ARB but ARB is used, profile > GL2 requested (OpenGL >= 3.0.1). Requested: "+glCaps.getGLProfile()+", current: "+getGLVersion()); } if(DEBUG) { - System.err.println("WindowsWGLContext.createContext failed, fall back to !ARB context "+getGLVersion()); + System.err.println("WindowsWGLContext.createContext ARB not used, fall back to !ARB context "+getGLVersion()); } - // continue with temp context for GL < 3.0 + // continue with temp context contextHandle = temp_ctx; - if (!wglMakeContextCurrent(drawable.getHandle(), drawableRead.getHandle(), contextHandle)) { + if ( !wglMakeContextCurrent(drawable.getHandle(), drawableRead.getHandle(), contextHandle) ) { WGL.wglMakeCurrent(0, 0); WGL.wglDeleteContext(contextHandle); throw new GLException("Error making old context current: 0x" + toHexString(contextHandle) + ", werr: " + GDI.GetLastError()); } - if(0!=share) { + if( 0 != shareWithHandle ) { + // Windows can set up sharing of display lists after creation time if using GDI // Only utilize the classic GDI 'wglShareLists' shared context method // for traditional non ARB context. - if (!WGL.wglShareLists(share, contextHandle)) { - throw new GLException("wglShareLists(" + toHexString(share) + + if ( !WGL.wglShareLists(shareWithHandle, contextHandle) ) { + throw new GLException("wglShareLists(" + toHexString(shareWithHandle) + ", " + toHexString(contextHandle) + ") failed: werr " + GDI.GetLastError()); } } if (DEBUG) { - System.err.println(getThreadName() + ": createImpl: OK (old) share "+share); + System.err.println(getThreadName() + ": createImpl: OK (old) share "+toHexString(shareWithHandle)); } } @@ -376,7 +402,11 @@ public class WindowsWGLContext extends GLContextImpl { protected void makeCurrentImpl() throws GLException { if (WGL.wglGetCurrentContext() != contextHandle) { if (!wglMakeContextCurrent(drawable.getHandle(), drawableRead.getHandle(), contextHandle)) { - throw new GLException("Error making context current: 0x" + toHexString(contextHandle) + ", werr: " + GDI.GetLastError() + ", " + this); + throw new GLException("Error making context " + toHexString(contextHandle) + + " current on Thread " + getThreadName() + + ", drawableWrite " + toHexString(drawable.getHandle()) + + ", drawableRead "+ toHexString(drawableRead.getHandle()) + + ", werr: " + GDI.GetLastError() + ", " + this); } } } @@ -397,7 +427,7 @@ public class WindowsWGLContext extends GLContextImpl { } @Override - protected void copyImpl(GLContext source, int mask) throws GLException { + protected void copyImpl(final GLContext source, final int mask) throws GLException { if (!WGL.wglCopyContext(source.getHandle(), getHandle(), mask)) { throw new GLException("wglCopyContext failed"); } @@ -439,7 +469,7 @@ public class WindowsWGLContext extends GLContextImpl { @Override protected final StringBuilder getPlatformExtensionsStringImpl() { - StringBuilder sb = new StringBuilder(); + final StringBuilder sb = new StringBuilder(); if (!wglGetExtensionsStringEXTInitialized) { wglGetExtensionsStringEXTAvailable = (WGL.wglGetProcAddress("wglGetExtensionsStringEXT") != 0); @@ -452,26 +482,26 @@ public class WindowsWGLContext extends GLContextImpl { } @Override - protected boolean setSwapIntervalImpl(int interval) { - WGLExt wglExt = getWGLExt(); + protected boolean setSwapIntervalImpl(final int interval) { + final WGLExt wglExt = getWGLExt(); if(0==hasSwapIntervalSGI) { try { hasSwapIntervalSGI = wglExt.isExtensionAvailable("WGL_EXT_swap_control")?1:-1; - } catch (Throwable t) { hasSwapIntervalSGI=1; } + } catch (final Throwable t) { hasSwapIntervalSGI=1; } } if (hasSwapIntervalSGI>0) { try { return wglExt.wglSwapIntervalEXT(interval); - } catch (Throwable t) { hasSwapIntervalSGI=-1; } + } catch (final Throwable t) { hasSwapIntervalSGI=-1; } } return false; } - private final int initSwapGroupImpl(WGLExt wglExt) { + private final int initSwapGroupImpl(final WGLExt wglExt) { if(0==hasSwapGroupNV) { try { hasSwapGroupNV = wglExt.isExtensionAvailable("WGL_NV_swap_group")?1:-1; - } catch (Throwable t) { hasSwapGroupNV=1; } + } catch (final Throwable t) { hasSwapGroupNV=1; } if(DEBUG) { System.err.println("initSwapGroupImpl: hasSwapGroupNV: "+hasSwapGroupNV); } @@ -480,79 +510,63 @@ public class WindowsWGLContext extends GLContextImpl { } @Override - protected final boolean queryMaxSwapGroupsImpl(int[] maxGroups, int maxGroups_offset, - int[] maxBarriers, int maxBarriers_offset) { + protected final boolean queryMaxSwapGroupsImpl(final int[] maxGroups, final int maxGroups_offset, + final int[] maxBarriers, final int maxBarriers_offset) { boolean res = false; - WGLExt wglExt = getWGLExt(); + final WGLExt wglExt = getWGLExt(); if (initSwapGroupImpl(wglExt)>0) { final NativeSurface ns = drawable.getNativeSurface(); try { - if( wglExt.wglQueryMaxSwapGroupsNV(ns.getDisplayHandle(), - maxGroups, maxGroups_offset, - maxBarriers, maxBarriers_offset) ) { + final IntBuffer maxGroupsNIO = Buffers.newDirectIntBuffer(maxGroups.length - maxGroups_offset); + final IntBuffer maxBarriersNIO = Buffers.newDirectIntBuffer(maxBarriers.length - maxBarriers_offset); + + if( wglExt.wglQueryMaxSwapGroupsNV(ns.getDisplayHandle(), maxGroupsNIO, maxBarriersNIO) ) { + maxGroupsNIO.get(maxGroups, maxGroups_offset, maxGroupsNIO.remaining()); + maxBarriersNIO.get(maxGroups, maxGroups_offset, maxBarriersNIO.remaining()); res = true; } - } catch (Throwable t) { hasSwapGroupNV=-1; } + } catch (final Throwable t) { hasSwapGroupNV=-1; } } return res; } @Override - protected final boolean joinSwapGroupImpl(int group) { + protected final boolean joinSwapGroupImpl(final int group) { boolean res = false; - WGLExt wglExt = getWGLExt(); + final WGLExt wglExt = getWGLExt(); if (initSwapGroupImpl(wglExt)>0) { try { if( wglExt.wglJoinSwapGroupNV(drawable.getHandle(), group) ) { currentSwapGroup = group; res = true; } - } catch (Throwable t) { hasSwapGroupNV=-1; } + } catch (final Throwable t) { hasSwapGroupNV=-1; } } return res; } @Override - protected final boolean bindSwapBarrierImpl(int group, int barrier) { + protected final boolean bindSwapBarrierImpl(final int group, final int barrier) { boolean res = false; - WGLExt wglExt = getWGLExt(); + final WGLExt wglExt = getWGLExt(); if (initSwapGroupImpl(wglExt)>0) { try { if( wglExt.wglBindSwapBarrierNV(group, barrier) ) { res = true; } - } catch (Throwable t) { hasSwapGroupNV=-1; } + } catch (final Throwable t) { hasSwapGroupNV=-1; } } return res; } @Override - public ByteBuffer glAllocateMemoryNV(int arg0, float arg1, float arg2, float arg3) { - return getWGLExt().wglAllocateMemoryNV(arg0, arg1, arg2, arg3); - } - - @Override - public int getOffscreenContextPixelDataType() { - throw new GLException("Should not call this"); - } - - public int getOffscreenContextReadBuffer() { - throw new GLException("Should not call this"); - } - - @Override - public boolean offscreenImageNeedsVerticalFlip() { - throw new GLException("Should not call this"); - } - - @Override - public void bindPbufferToTexture() { - throw new GLException("Should not call this"); + public final ByteBuffer glAllocateMemoryNV(final int size, final float readFrequency, final float writeFrequency, final float priority) { + return getWGLExt().wglAllocateMemoryNV(size, readFrequency, writeFrequency, priority); } @Override - public void releasePbufferFromTexture() { - throw new GLException("Should not call this"); + public final void glFreeMemoryNV(final ByteBuffer pointer) { + getWGLExt().wglFreeMemoryNV(pointer); } } diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawable.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawable.java index 3b3f0c123..00b048e38 100644 --- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawable.java +++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawable.java @@ -44,6 +44,8 @@ import javax.media.nativewindow.NativeSurface; import javax.media.opengl.GLDrawableFactory; import javax.media.opengl.GLException; +import com.jogamp.common.util.PropertyAccess; + import jogamp.nativewindow.windows.GDI; import jogamp.opengl.Debug; import jogamp.opengl.GLDrawableImpl; @@ -51,29 +53,35 @@ import jogamp.opengl.GLDynamicLookupHelper; public abstract class WindowsWGLDrawable extends GLDrawableImpl { - private static final boolean PROFILING = Debug.isPropertyDefined("jogl.debug.GLDrawable.profiling", true); + private static final boolean PROFILING; + + static { + Debug.initSingleton(); + PROFILING = PropertyAccess.isPropertyDefined("jogl.debug.GLDrawable.profiling", true); + } + private static final int PROFILING_TICKS = 200; private int profilingSwapBuffersTicks; private long profilingSwapBuffersTime; - public WindowsWGLDrawable(GLDrawableFactory factory, NativeSurface comp, boolean realized) { + public WindowsWGLDrawable(final GLDrawableFactory factory, final NativeSurface comp, final boolean realized) { super(factory, comp, realized); } @Override protected void setRealizedImpl() { if(realized) { - NativeSurface ns = getNativeSurface(); - WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration)ns.getGraphicsConfiguration(); + final NativeSurface ns = getNativeSurface(); + final WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration)ns.getGraphicsConfiguration(); config.updateGraphicsConfiguration(getFactory(), ns, null); if (DEBUG) { - System.err.println("WindowsWGLDrawable.setRealized(true): "+config); + System.err.println(getThreadName()+": WindowsWGLDrawable.setRealized(true): "+config); } } } @Override - protected final void swapBuffersImpl(boolean doubleBuffered) { + protected final void swapBuffersImpl(final boolean doubleBuffered) { if(doubleBuffered) { final long t0; if (PROFILING) { @@ -81,11 +89,11 @@ public abstract class WindowsWGLDrawable extends GLDrawableImpl { } else { t0 = 0; } - + if (!WGLUtil.SwapBuffers(getHandle()) && (GDI.GetLastError() != GDI.ERROR_SUCCESS)) { throw new GLException("Error swapping buffers"); } - + if (PROFILING) { profilingSwapBuffersTime += System.currentTimeMillis() - t0; if (++profilingSwapBuffersTicks == PROFILING_TICKS) { diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java index 91d5c225a..fa052d784 100644 --- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java +++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java @@ -42,6 +42,8 @@ package jogamp.opengl.windows.wgl; import java.nio.Buffer; import java.nio.ShortBuffer; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.Collection; import java.util.HashMap; import java.util.List; @@ -53,7 +55,6 @@ import javax.media.nativewindow.DefaultGraphicsScreen; import javax.media.nativewindow.NativeSurface; import javax.media.nativewindow.ProxySurface; import javax.media.nativewindow.UpstreamSurfaceHook; -import javax.media.opengl.GL; import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLCapabilitiesChooser; import javax.media.opengl.GLCapabilitiesImmutable; @@ -67,6 +68,7 @@ import jogamp.nativewindow.windows.GDI; import jogamp.nativewindow.windows.GDIDummyUpstreamSurfaceHook; import jogamp.nativewindow.windows.GDISurface; import jogamp.nativewindow.windows.RegisteredClassFactory; +import jogamp.opengl.Debug; import jogamp.opengl.DesktopGLDynamicLookupHelper; import jogamp.opengl.GLContextImpl; import jogamp.opengl.GLDrawableFactoryImpl; @@ -75,34 +77,101 @@ import jogamp.opengl.GLDynamicLookupHelper; import jogamp.opengl.GLGraphicsConfigurationUtil; import jogamp.opengl.SharedResourceRunner; -import com.jogamp.common.JogampRuntimeException; import com.jogamp.common.nio.PointerBuffer; -import com.jogamp.common.os.Platform; +import com.jogamp.common.util.PropertyAccess; import com.jogamp.common.util.ReflectionUtil; -import com.jogamp.common.util.VersionNumber; import com.jogamp.nativewindow.windows.WindowsGraphicsDevice; import com.jogamp.opengl.GLExtensions; +import com.jogamp.opengl.GLRendererQuirks; public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { + /** + * Bug 1036: NVidia Windows Driver 'Threaded optimization' workaround. + * <p> + * https://jogamp.org/bugzilla/show_bug.cgi?id=1036 + * </p> + * <p> + * Since NV driver 260.99 from 2010-12-11 a 'Threaded optimization' feature has been introduced. + * The driver spawns off a dedicated thread to off-load certain OpenGL tasks from the calling thread + * to perform them async and off-thread. + * </p> + * <p> + * If 'Threaded optimization' is manually enabled 'on', the driver may crash with JOGL's consistent + * multi-threaded usage - this is a driver bug. + * </p> + * <p> + * If 'Threaded optimization' is manually disabled 'off', the driver always works correctly. + * </p> + * <p> + * 'Threaded optimization' default setting is 'auto' and the driver may crash without this workaround. + * </p> + * <p> + * If setting the process affinity to '1' (1st CPU) while initialization and launching + * the {@link SharedResourceRunner}, the driver does not crash anymore in 'auto' mode. + * This might be either because the driver does not enable 'Threaded optimization' + * or because the driver's worker thread is bound to the same CPU. + * </p> + * <p> + * Property integer value <code>jogl.windows.cpu_affinity_mode</code>: + * <ul> + * <li>0 - none (no affinity, may cause driver crash with 'Threaded optimization' = ['auto', 'on'])</li> + * <li>1 - process affinity (default, workaround for driver crash for 'Threaded optimization' = 'auto', still crashes if set to 'on')</li> + * </ul> + * </p> + * <p> + * Test case reproducing the crash reliable is: com.jogamp.opengl.test.junit.jogl.caps.TestTranslucencyNEWT<br> + * (don't ask why ..) + * </p> + */ + private static final int CPU_AFFINITY_MODE; + + static { + Debug.initSingleton(); + CPU_AFFINITY_MODE = PropertyAccess.getIntProperty("jogl.windows.cpu_affinity_mode", true, 1); + } + private static DesktopGLDynamicLookupHelper windowsWGLDynamicLookupHelper = null; + private final CPUAffinity cpuAffinity; + public WindowsWGLDrawableFactory() { super(); + switch( CPU_AFFINITY_MODE ) { + case 0: + cpuAffinity = new NopCPUAffinity(); + break; + /** + * Doesn't work ! + case 2: + cpuAffinity = new WindowsThreadAffinity(); + break; + */ + default: + cpuAffinity = new WindowsProcessAffinity(); + break; + } + synchronized(WindowsWGLDrawableFactory.class) { - if(null==windowsWGLDynamicLookupHelper) { - DesktopGLDynamicLookupHelper tmp = null; - try { - tmp = new DesktopGLDynamicLookupHelper(new WindowsWGLDynamicLibraryBundleInfo()); - } catch (GLException gle) { - if(DEBUG) { - gle.printStackTrace(); + if( null == windowsWGLDynamicLookupHelper ) { + windowsWGLDynamicLookupHelper = AccessController.doPrivileged(new PrivilegedAction<DesktopGLDynamicLookupHelper>() { + @Override + public DesktopGLDynamicLookupHelper run() { + DesktopGLDynamicLookupHelper tmp; + try { + tmp = new DesktopGLDynamicLookupHelper(new WindowsWGLDynamicLibraryBundleInfo()); + if(null!=tmp && tmp.isLibComplete()) { + WGL.getWGLProcAddressTable().reset(tmp); + } + } catch (final Exception ex) { + tmp = null; + if(DEBUG) { + ex.printStackTrace(); + } + } + return tmp; } - } - if(null!=tmp && tmp.isLibComplete()) { - windowsWGLDynamicLookupHelper = tmp; - WGL.getWGLProcAddressTable().reset(windowsWGLDynamicLookupHelper); - } + } ); } } @@ -116,7 +185,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { try { ReflectionUtil.callStaticMethod("jogamp.opengl.windows.wgl.awt.WindowsAWTWGLGraphicsConfigurationFactory", "registerFactory", null, null, getClass().getClassLoader()); - } catch (JogampRuntimeException jre) { /* n/a .. */ } + } catch (final Exception jre) { /* n/a .. */ } } sharedMap = new HashMap<String, SharedResourceRunner.Resource>(); @@ -132,10 +201,13 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { protected final boolean isComplete() { return null != windowsWGLDynamicLookupHelper; } - - + + @Override - protected final void destroy() { + protected final void shutdownImpl() { + if( DEBUG ) { + System.err.println("WindowsWGLDrawableFactory.shutdown"); + } if(null != sharedResourceRunner) { sharedResourceRunner.stop(); sharedResourceRunner = null; @@ -156,74 +228,42 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { } @Override - public GLDynamicLookupHelper getGLDynamicLookupHelper(int profile) { + public GLDynamicLookupHelper getGLDynamicLookupHelper(final int profile) { return windowsWGLDynamicLookupHelper; } + /* pp */ static String toHexString(final long l) { return "0x"+Long.toHexString(l); } + private WindowsGraphicsDevice defaultDevice; private SharedResourceRunner sharedResourceRunner; private HashMap<String /*connection*/, SharedResourceRunner.Resource> sharedMap; - private long processAffinityChanges = 0; - private PointerBuffer procMask = PointerBuffer.allocateDirect(1); - private PointerBuffer sysMask = PointerBuffer.allocateDirect(1); - @Override protected void enterThreadCriticalZone() { - synchronized (sysMask) { - if( 0 == processAffinityChanges) { - long pid = GDI.GetCurrentProcess(); - if ( GDI.GetProcessAffinityMask(pid, procMask, sysMask) ) { - if(DEBUG) { - System.err.println("WindowsWGLDrawableFactory.enterThreadCriticalZone() - 0x" + Long.toHexString(pid) + " - " + Thread.currentThread().getName()); - // Thread.dumpStack(); - } - processAffinityChanges = pid; - GDI.SetProcessAffinityMask(pid, 1); - } - } + synchronized (cpuAffinity) { + cpuAffinity.set(1); } } @Override protected void leaveThreadCriticalZone() { - synchronized (sysMask) { - if( 0 != processAffinityChanges) { - long pid = GDI.GetCurrentProcess(); - if( pid != processAffinityChanges) { - throw new GLException("PID doesn't match: set PID 0x" + Long.toHexString(processAffinityChanges) + - " this PID 0x" + Long.toHexString(pid) ); - } - if(DEBUG) { - System.err.println("WindowsWGLDrawableFactory.leaveThreadCriticalZone() - 0x" + Long.toHexString(pid) + " - " + Thread.currentThread().getName()); - } - GDI.SetProcessAffinityMask(pid, sysMask.get(0)); - } + synchronized (cpuAffinity) { + cpuAffinity.reset(); } } - /** - * http://msdn.microsoft.com/en-us/library/ms724832%28v=vs.85%29.aspx - * Windows XP 5.1 - */ - static final VersionNumber winXPVersionNumber = new VersionNumber ( 5, 1, 0); - static class SharedResource implements SharedResourceRunner.Resource { + private final boolean hasARBPixelFormat; + private final boolean hasARBMultisample; + private final boolean hasARBPBuffer; + private final boolean hasARBReadDrawable; private WindowsGraphicsDevice device; private AbstractGraphicsScreen screen; private GLDrawableImpl drawable; private GLContextImpl context; - private boolean hasARBPixelFormat; - private boolean hasARBMultisample; - private boolean hasARBPBuffer; - private boolean hasARBReadDrawable; - private String vendor; - private boolean isVendorATI; - private boolean isVendorNVIDIA; - private boolean needsCurrenContext4ARBPFDQueries; - - SharedResource(WindowsGraphicsDevice dev, AbstractGraphicsScreen scrn, GLDrawableImpl draw, GLContextImpl ctx, - boolean arbPixelFormat, boolean arbMultisample, boolean arbPBuffer, boolean arbReadDrawable, String glVendor) { + + SharedResource(final WindowsGraphicsDevice dev, final AbstractGraphicsScreen scrn, final GLDrawableImpl draw, final GLContextImpl ctx, + final boolean arbPixelFormat, final boolean arbMultisample, final boolean arbPBuffer, final boolean arbReadDrawable) { device = dev; screen = scrn; drawable = draw; @@ -232,28 +272,13 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { hasARBMultisample = arbMultisample; hasARBPBuffer = arbPBuffer; hasARBReadDrawable = arbReadDrawable; - vendor = glVendor; - if(null != vendor) { - isVendorNVIDIA = vendor.startsWith("NVIDIA") ; - isVendorATI = vendor.startsWith("ATI") ; - } - - if ( isVendorATI() ) { - final VersionNumber winVersion = Platform.getOSVersionNumber(); - final boolean isWinXPOrLess = winVersion.compareTo(winXPVersionNumber) <= 0; - if(DEBUG) { - System.err.println("needsCurrenContext4ARBPFDQueries: "+winVersion+" <= "+winXPVersionNumber+" = "+isWinXPOrLess+" - "+Platform.getOSVersion()); - } - needsCurrenContext4ARBPFDQueries = isWinXPOrLess; - } else { - if(DEBUG) { - System.err.println("needsCurrenContext4ARBPFDQueries: false"); - } - needsCurrenContext4ARBPFDQueries = false; - } } @Override + public final boolean isValid() { + return null != context; + } + @Override final public AbstractGraphicsDevice getDevice() { return device; } @Override final public AbstractGraphicsScreen getScreen() { return screen; } @@ -261,45 +286,29 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { final public GLDrawableImpl getDrawable() { return drawable; } @Override final public GLContextImpl getContext() { return context; } + @Override + public GLRendererQuirks getRendererQuirks() { + return null != context ? context.getRendererQuirks() : null; + } final boolean hasARBPixelFormat() { return hasARBPixelFormat; } final boolean hasARBMultisample() { return hasARBMultisample; } final boolean hasARBPBuffer() { return hasARBPBuffer; } final boolean hasReadDrawable() { return hasARBReadDrawable; } - - final String vendor() { return vendor; } - final boolean isVendorATI() { return isVendorATI; } - final boolean isVendorNVIDIA() { return isVendorNVIDIA; } - - /** - * Solves bug #480 - * - * TODO: Validate if bug is actually relates to the 'old' ATI Windows driver for old GPU's like X300 etc - * and unrelated to the actual Windows version ! - * - * @return true if GL_VENDOR is ATI _and_ platform is Windows version XP or less! - */ - final boolean needsCurrentContext4ARBPFDQueries() { return needsCurrenContext4ARBPFDQueries; } } class SharedResourceImplementation implements SharedResourceRunner.Implementation { @Override public void clear() { - synchronized(sharedMap) { - sharedMap.clear(); - } + sharedMap.clear(); } @Override - public SharedResourceRunner.Resource mapPut(String connection, SharedResourceRunner.Resource resource) { - synchronized(sharedMap) { - return sharedMap.put(connection, resource); - } + public SharedResourceRunner.Resource mapPut(final String connection, final SharedResourceRunner.Resource resource) { + return sharedMap.put(connection, resource); } @Override - public SharedResourceRunner.Resource mapGet(String connection) { - synchronized(sharedMap) { - return sharedMap.get(connection); - } + public SharedResourceRunner.Resource mapGet(final String connection) { + return sharedMap.get(connection); } @Override public Collection<SharedResourceRunner.Resource> mapValues() { @@ -309,7 +318,12 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { } @Override - public SharedResourceRunner.Resource createSharedResource(String connection) { + public boolean isDeviceSupported(final String connection) { + return true; + } + + @Override + public SharedResourceRunner.Resource createSharedResource(final String connection) { final WindowsGraphicsDevice sharedDevice = new WindowsGraphicsDevice(connection, AbstractGraphicsDevice.DEFAULT_UNIT); sharedDevice.lock(); try { @@ -318,9 +332,10 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { if (null == glp) { throw new GLException("Couldn't get default GLProfile for device: "+sharedDevice); } - final GLDrawableImpl sharedDrawable = createOnscreenDrawableImpl(createDummySurfaceImpl(sharedDevice, false, new GLCapabilities(glp), null, 64, 64)); + final GLCapabilitiesImmutable caps = new GLCapabilities(glp); + final GLDrawableImpl sharedDrawable = createOnscreenDrawableImpl(createDummySurfaceImpl(sharedDevice, false, caps, caps, null, 64, 64)); sharedDrawable.setRealized(true); - + final GLContextImpl sharedContext = (GLContextImpl) sharedDrawable.createContext(null); if (null == sharedContext) { throw new GLException("Couldn't create shared context for drawable: "+sharedDrawable); @@ -329,7 +344,6 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { boolean hasARBMultisample; boolean hasARBPBuffer; boolean hasARBReadDrawableAvailable; - String vendor; sharedContext.makeCurrent(); try { hasARBPixelFormat = sharedContext.isExtensionAvailable(WGL_ARB_pixel_format); @@ -337,7 +351,6 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { hasARBPBuffer = sharedContext.isExtensionAvailable(GLExtensions.ARB_pbuffer); hasARBReadDrawableAvailable = sharedContext.isExtensionAvailable(WGL_ARB_make_current_read) && sharedContext.isFunctionAvailable(wglMakeContextCurrent); - vendor = sharedContext.getGL().glGetString(GL.GL_VENDOR); } finally { sharedContext.release(); } @@ -349,12 +362,11 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { System.err.println("multisample: " + hasARBMultisample); System.err.println("pbuffer: " + hasARBPBuffer); System.err.println("readDrawable: " + hasARBReadDrawableAvailable); - System.err.println("vendor: " + vendor); } return new SharedResource(sharedDevice, absScreen, sharedDrawable, sharedContext, hasARBPixelFormat, hasARBMultisample, - hasARBPBuffer, hasARBReadDrawableAvailable, vendor); - } catch (Throwable t) { + hasARBPBuffer, hasARBReadDrawableAvailable); + } catch (final Throwable t) { throw new GLException("WindowsWGLDrawableFactory - Could not initialize shared resources for "+connection, t); } finally { sharedDevice.unlock(); @@ -362,8 +374,8 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { } @Override - public void releaseSharedResource(SharedResourceRunner.Resource shared) { - SharedResource sr = (SharedResource) shared; + public void releaseSharedResource(final SharedResourceRunner.Resource shared) { + final SharedResource sr = (SharedResource) shared; if (DEBUG) { System.err.println("Shutdown Shared:"); System.err.println("Device : " + sr.device); @@ -374,6 +386,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { if (null != sr.context) { // may cause JVM SIGSEGV: sharedContext.destroy(); + sr.context.destroy(); // will also pull the dummy MutableSurface sr.context = null; } @@ -399,7 +412,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { } @Override - public final boolean getIsDeviceCompatible(AbstractGraphicsDevice device) { + public final boolean getIsDeviceCompatible(final AbstractGraphicsDevice device) { if(null!=windowsWGLDynamicLookupHelper && device instanceof WindowsGraphicsDevice) { return true; } @@ -419,58 +432,25 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { } @Override - protected final boolean createSharedResource(AbstractGraphicsDevice device) { - try { - SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device); - if(null!=sr) { - return null != sr.getContext(); - } - } catch (GLException gle) { - if(DEBUG) { - System.err.println("Catched Exception while WindowsWGL Shared Resource initialization"); - gle.printStackTrace(); - } - } - return false; - } - - @Override - protected final GLContext getOrCreateSharedContextImpl(AbstractGraphicsDevice device) { - SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device); - if(null!=sr) { - return sr.getContext(); - } - return null; - } - - @Override - protected AbstractGraphicsDevice getOrCreateSharedDeviceImpl(AbstractGraphicsDevice device) { - SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device); - if(null!=sr) { - return sr.getDevice(); - } - return null; + protected final SharedResource getOrCreateSharedResourceImpl(final AbstractGraphicsDevice device) { + return (SharedResource) sharedResourceRunner.getOrCreateShared(device); } - protected WindowsWGLDrawable getOrCreateSharedDrawable(AbstractGraphicsDevice device) { - SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device); + protected final WindowsWGLDrawable getOrCreateSharedDrawable(final AbstractGraphicsDevice device) { + final SharedResourceRunner.Resource sr = getOrCreateSharedResourceImpl(device); if(null!=sr) { return (WindowsWGLDrawable) sr.getDrawable(); } return null; } - SharedResource getOrCreateSharedResource(AbstractGraphicsDevice device) { - return (SharedResource) sharedResourceRunner.getOrCreateShared(device); - } - @Override - protected List<GLCapabilitiesImmutable> getAvailableCapabilitiesImpl(AbstractGraphicsDevice device) { + protected List<GLCapabilitiesImmutable> getAvailableCapabilitiesImpl(final AbstractGraphicsDevice device) { return WindowsWGLGraphicsConfigurationFactory.getAvailableCapabilities(this, device); } @Override - protected final GLDrawableImpl createOnscreenDrawableImpl(NativeSurface target) { + protected final GLDrawableImpl createOnscreenDrawableImpl(final NativeSurface target) { if (target == null) { throw new IllegalArgumentException("Null target"); } @@ -482,10 +462,10 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { if (target == null) { throw new IllegalArgumentException("Null target"); } - AbstractGraphicsConfiguration config = target.getGraphicsConfiguration(); - GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities(); + final AbstractGraphicsConfiguration config = target.getGraphicsConfiguration(); + final GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities(); if(!chosenCaps.isPBuffer()) { - return new WindowsBitmapWGLDrawable(this, target); + return WindowsBitmapWGLDrawable.create(this, target); } // PBuffer GLDrawable Creation @@ -496,9 +476,9 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { * Similar to ATI Bug https://bugzilla.mozilla.org/show_bug.cgi?id=486277, * we need to have a context current on the same Display to create a PBuffer. */ - final SharedResource sr = (SharedResource) sharedResourceRunner.getOrCreateShared(device); + final SharedResource sr = getOrCreateSharedResourceImpl(device); if(null!=sr) { - GLContext lastContext = GLContext.getCurrent(); + final GLContext lastContext = GLContext.getCurrent(); if (lastContext != null) { lastContext.release(); } @@ -521,8 +501,8 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { * @return 1 if read drawable extension is available, 0 if not * and -1 if undefined yet, ie no shared device exist at this point. */ - public final int isReadDrawableAvailable(AbstractGraphicsDevice device) { - SharedResource sr = (SharedResource) sharedResourceRunner.getOrCreateShared((null!=device)?device:defaultDevice); + public final int isReadDrawableAvailable(final AbstractGraphicsDevice device) { + final SharedResource sr = getOrCreateSharedResourceImpl( ( null != device ) ? device : defaultDevice ); if(null!=sr) { return sr.hasReadDrawable() ? 1 : 0 ; } @@ -530,8 +510,8 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { } @Override - public final boolean canCreateGLPbuffer(AbstractGraphicsDevice device) { - SharedResource sr = (SharedResource) sharedResourceRunner.getOrCreateShared((null!=device)?device:defaultDevice); + public final boolean canCreateGLPbuffer(final AbstractGraphicsDevice device, final GLProfile glp) { + final SharedResource sr = getOrCreateSharedResourceImpl( ( null != device ) ? device : defaultDevice ); if(null!=sr) { return sr.hasARBPBuffer(); } @@ -539,11 +519,11 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { } @Override - protected final ProxySurface createMutableSurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice, - GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, - GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstreamHook) { + protected final ProxySurface createMutableSurfaceImpl(final AbstractGraphicsDevice deviceReq, final boolean createNewDevice, + final GLCapabilitiesImmutable capsChosen, final GLCapabilitiesImmutable capsRequested, + final GLCapabilitiesChooser chooser, final UpstreamSurfaceHook upstreamHook) { final WindowsGraphicsDevice device; - if(createNewDevice) { + if(createNewDevice || !(deviceReq instanceof WindowsGraphicsDevice)) { device = new WindowsGraphicsDevice(deviceReq.getConnection(), deviceReq.getUnitID()); } else { device = (WindowsGraphicsDevice)deviceReq; @@ -551,31 +531,31 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { final AbstractGraphicsScreen screen = new DefaultGraphicsScreen(device, 0); final WindowsWGLGraphicsConfiguration config = WindowsWGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsChosen, capsRequested, chooser, screen); if(null == config) { - throw new GLException("Choosing GraphicsConfiguration failed w/ "+capsChosen+" on "+screen); - } + throw new GLException("Choosing GraphicsConfiguration failed w/ "+capsChosen+" on "+screen); + } return new WrappedSurface(config, 0, upstreamHook, createNewDevice); } @Override - public final ProxySurface createDummySurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice, - GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height) { + public final ProxySurface createDummySurfaceImpl(final AbstractGraphicsDevice deviceReq, final boolean createNewDevice, + GLCapabilitiesImmutable chosenCaps, final GLCapabilitiesImmutable requestedCaps, final GLCapabilitiesChooser chooser, final int width, final int height) { final WindowsGraphicsDevice device; - if(createNewDevice) { + if( createNewDevice || !(deviceReq instanceof WindowsGraphicsDevice) ) { device = new WindowsGraphicsDevice(deviceReq.getConnection(), deviceReq.getUnitID()); } else { device = (WindowsGraphicsDevice)deviceReq; } final AbstractGraphicsScreen screen = new DefaultGraphicsScreen(device, 0); - final GLCapabilitiesImmutable chosenCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(requestedCaps); + chosenCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(chosenCaps); final WindowsWGLGraphicsConfiguration config = WindowsWGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(chosenCaps, requestedCaps, chooser, screen); - if(null == config) { - throw new GLException("Choosing GraphicsConfiguration failed w/ "+requestedCaps+" on "+screen); - } + if(null == config) { + throw new GLException("Choosing GraphicsConfiguration failed w/ "+chosenCaps+" on "+screen); + } return new GDISurface(config, 0, new GDIDummyUpstreamSurfaceHook(width, height), createNewDevice); - } - + } + @Override - protected final ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice deviceReq, int screenIdx, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstream) { + protected final ProxySurface createProxySurfaceImpl(final AbstractGraphicsDevice deviceReq, final int screenIdx, final long windowHandle, final GLCapabilitiesImmutable capsRequested, final GLCapabilitiesChooser chooser, final UpstreamSurfaceHook upstream) { final WindowsGraphicsDevice device = new WindowsGraphicsDevice(deviceReq.getConnection(), deviceReq.getUnitID()); final AbstractGraphicsScreen screen = new DefaultGraphicsScreen(device, screenIdx); final WindowsWGLGraphicsConfiguration cfg = WindowsWGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsRequested, capsRequested, chooser, screen); @@ -588,7 +568,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { } @Override - public final boolean canCreateExternalGLDrawable(AbstractGraphicsDevice device) { + public final boolean canCreateExternalGLDrawable(final AbstractGraphicsDevice device) { return true; } @@ -598,7 +578,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { } static String wglGetLastError() { - long err = GDI.GetLastError(); + final long err = GDI.GetLastError(); String detail = null; switch ((int) err) { case GDI.ERROR_SUCCESS: detail = "ERROR_SUCCESS"; break; @@ -612,17 +592,6 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { return detail; } - @Override - public final boolean canCreateContextOnJava2DSurface(AbstractGraphicsDevice device) { - return false; - } - - @Override - public final GLContext createContextOnJava2DSurface(Object graphics, GLContext shareWith) - throws GLException { - throw new GLException("Unimplemented on this platform"); - } - //------------------------------------------------------ // Gamma-related functionality // @@ -630,32 +599,40 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { private static final int GAMMA_RAMP_LENGTH = 256; @Override - protected final int getGammaRampLength() { + protected final int getGammaRampLength(final NativeSurface surface) { return GAMMA_RAMP_LENGTH; } @Override - protected final boolean setGammaRamp(float[] ramp) { - short[] rampData = new short[3 * GAMMA_RAMP_LENGTH]; + protected final boolean setGammaRamp(final NativeSurface surface, final float[] ramp) { + final short[] rampData = new short[3 * GAMMA_RAMP_LENGTH]; for (int i = 0; i < GAMMA_RAMP_LENGTH; i++) { - short scaledValue = (short) (ramp[i] * 65535); + final short scaledValue = (short) (ramp[i] * 65535); rampData[i] = scaledValue; rampData[i + GAMMA_RAMP_LENGTH] = scaledValue; rampData[i + 2 * GAMMA_RAMP_LENGTH] = scaledValue; } - long screenDC = GDI.GetDC(0); - boolean res = GDI.SetDeviceGammaRamp(screenDC, ShortBuffer.wrap(rampData)); - GDI.ReleaseDC(0, screenDC); + final long hDC = surface.getSurfaceHandle(); + if( 0 == hDC ) { + return false; + } + // final long screenDC = GDI.GetDC(0); + final boolean res = GDI.SetDeviceGammaRamp(hDC, ShortBuffer.wrap(rampData)); + // GDI.ReleaseDC(0, screenDC); return res; } @Override - protected final Buffer getGammaRamp() { - ShortBuffer rampData = ShortBuffer.wrap(new short[3 * GAMMA_RAMP_LENGTH]); - long screenDC = GDI.GetDC(0); - boolean res = GDI.GetDeviceGammaRamp(screenDC, rampData); - GDI.ReleaseDC(0, screenDC); + protected final Buffer getGammaRamp(final NativeSurface surface) { + final ShortBuffer rampData = ShortBuffer.wrap(new short[3 * GAMMA_RAMP_LENGTH]); + final long hDC = surface.getSurfaceHandle(); + if( 0 == hDC ) { + return null; + } + // final long screenDC = GDI.GetDC(0); + final boolean res = GDI.GetDeviceGammaRamp(hDC, rampData); + // GDI.ReleaseDC(0, screenDC); if (!res) { return null; } @@ -663,13 +640,167 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { } @Override - protected final void resetGammaRamp(Buffer originalGammaRamp) { + protected final void resetGammaRamp(final NativeSurface surface, final Buffer originalGammaRamp) { + if (originalGammaRamp == null) { + // getGammaRamp failed earlier + return; + } + final long hDC = surface.getSurfaceHandle(); + if( 0 == hDC ) { + return; + } + // final long screenDC = GDI.GetDC(0); + GDI.SetDeviceGammaRamp(hDC, originalGammaRamp); + // GDI.ReleaseDC(0, hDC); + } + + @Override + protected final void resetGammaRamp(final DeviceScreenID deviceScreenID, final Buffer originalGammaRamp) { if (originalGammaRamp == null) { // getGammaRamp failed earlier return; } - long screenDC = GDI.GetDC(0); + final long screenDC = GDI.GetDC(0); GDI.SetDeviceGammaRamp(screenDC, originalGammaRamp); GDI.ReleaseDC(0, screenDC); } + + + static interface CPUAffinity { + boolean set(final int newAffinity); + boolean reset(); + } + static final class WindowsThreadAffinity implements CPUAffinity { + private long threadHandle; + private long threadOrigAffinity; + private long threadNewAffinity; + public WindowsThreadAffinity() { + threadHandle = 0; + threadOrigAffinity = 0; + threadNewAffinity = 0; + } + @Override + public boolean set(final int newAffinity) { + final long tid = GDI.GetCurrentThread(); + if( 0 != threadHandle ) { + throw new IllegalStateException("Affinity already set"); + } + final long threadLastAffinity = GDI.SetThreadAffinityMask(tid, newAffinity); + final int werr = GDI.GetLastError(); + final boolean res; + if( 0 != threadLastAffinity ) { + res = true; + this.threadHandle = tid; + this.threadNewAffinity = newAffinity; + this.threadOrigAffinity = threadLastAffinity; + } else { + res = false; + } + if(DEBUG) { + System.err.println("WindowsThreadAffinity.set() - tid " + toHexString(tid) + " - " + getThreadName() + + ": OK "+res+" (werr "+werr+"), Affinity: "+toHexString(threadOrigAffinity) + " -> " + toHexString(newAffinity)); + } + return res; + } + @Override + public boolean reset() { + if( 0 == threadHandle ) { + return true; + } + final long tid = GDI.GetCurrentThread(); + if( tid != threadHandle) { + throw new IllegalStateException("TID doesn't match: set TID " + toHexString(threadHandle) + + " this TID " + toHexString(tid) ); + } + final long preThreadAffinity = GDI.SetThreadAffinityMask(threadHandle, threadOrigAffinity); + final boolean res = 0 != preThreadAffinity; + if(DEBUG) { + System.err.println("WindowsThreadAffinity.reset() - tid " + toHexString(threadHandle) + " - " + getThreadName() + + ": OK "+res+" (werr "+GDI.GetLastError()+"), Affinity: "+toHexString(threadNewAffinity)+" -> orig "+ toHexString(threadOrigAffinity)); + } + this.threadHandle = 0; + this.threadNewAffinity = this.threadOrigAffinity; + return res; + } + } + static final class WindowsProcessAffinity implements CPUAffinity { + private long processHandle; + private long newAffinity; + private final PointerBuffer procMask; + private final PointerBuffer sysMask; + + public WindowsProcessAffinity() { + processHandle = 0; + newAffinity = 0; + procMask = PointerBuffer.allocateDirect(1); + sysMask = PointerBuffer.allocateDirect(1); + } + @Override + public boolean set(final int newAffinity) { + if( 0 != processHandle ) { + throw new IllegalStateException("Affinity already set"); + } + final long pid = GDI.GetCurrentProcess(); + final boolean res; + if ( GDI.GetProcessAffinityMask(pid, procMask, sysMask) ) { + if( GDI.SetProcessAffinityMask(pid, newAffinity) ) { + this.processHandle = pid; + this.newAffinity = newAffinity; + res = true; + } else { + res = false; + } + if(DEBUG) { + System.err.println("WindowsProcessAffinity.set() - pid " + toHexString(pid) + " - " + getThreadName() + + ": OK "+res+" (werr "+GDI.GetLastError()+"), Affinity: procMask "+ toHexString(procMask.get(0)) + ", sysMask "+ toHexString(sysMask.get(0)) + + " -> "+toHexString(newAffinity)); + } + } else { + if(DEBUG) { + System.err.println("WindowsProcessAffinity.set() - pid " + toHexString(pid) + " - " + getThreadName() + + ": Error, could not GetProcessAffinityMask, werr "+GDI.GetLastError()); + } + res = false; + } + return res; + } + @Override + public boolean reset() { + if( 0 == processHandle ) { + return true; + } + final long pid = GDI.GetCurrentProcess(); + if( pid != processHandle) { + throw new IllegalStateException("PID doesn't match: set PID " + toHexString(processHandle) + + " this PID " + toHexString(pid) ); + } + final long origProcAffinity = procMask.get(0); + final boolean res = GDI.SetProcessAffinityMask(processHandle, origProcAffinity); + if(DEBUG) { + final int werr = GDI.GetLastError(); + System.err.println("WindowsProcessAffinity.reset() - pid " + toHexString(processHandle) + " - " + getThreadName() + + ": OK "+res+" (werr "+werr+"), Affinity: "+toHexString(newAffinity)+" -> procMask "+ toHexString(origProcAffinity)); + } + this.processHandle = 0; + this.newAffinity = origProcAffinity; + return res; + } + } + static final class NopCPUAffinity implements CPUAffinity { + public NopCPUAffinity() { } + @Override + public boolean set(final int newAffinity) { + if(DEBUG) { + System.err.println("NopCPUAffinity.set() - " + getThreadName()); + } + return false; + } + @Override + public boolean reset() { + if(DEBUG) { + System.err.println("NopCPUAffinity.reset() - " + getThreadName()); + } + return false; + } + } } diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDynamicLibraryBundleInfo.java index a553bd4c2..2285ae996 100644 --- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDynamicLibraryBundleInfo.java +++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDynamicLibraryBundleInfo.java @@ -3,14 +3,14 @@ * * 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 @@ -20,40 +20,40 @@ * 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 jogamp.opengl.windows.wgl; import jogamp.opengl.*; import java.util.*; -public class WindowsWGLDynamicLibraryBundleInfo extends DesktopGLDynamicLibraryBundleInfo { +public final class WindowsWGLDynamicLibraryBundleInfo extends DesktopGLDynamicLibraryBundleInfo { protected WindowsWGLDynamicLibraryBundleInfo() { super(); } @Override - public List<List<String>> getToolLibNames() { + public final List<List<String>> getToolLibNames() { final List<List<String>> libsList = new ArrayList<List<String>>(); final List<String> libsGL = new ArrayList<String>(); libsGL.add("OpenGL32"); - libsList.add(libsGL); + libsList.add(libsGL); return libsList; } - + @Override public final List<String> getToolGetProcAddressFuncNameList() { - List<String> res = new ArrayList<String>(); + final List<String> res = new ArrayList<String>(); res.add("wglGetProcAddress"); return res; } @Override - public final long toolGetProcAddress(long toolGetProcAddressHandle, String funcName) { + public final long toolGetProcAddress(final long toolGetProcAddressHandle, final String funcName) { return WGL.wglGetProcAddress(toolGetProcAddressHandle, funcName); } } diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java index 058f4e336..5785f8041 100644 --- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java +++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java @@ -1,22 +1,22 @@ /* * 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 * 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 @@ -33,6 +33,8 @@ package jogamp.opengl.windows.wgl; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; import java.util.ArrayList; import java.util.List; @@ -44,46 +46,45 @@ import javax.media.opengl.GLCapabilitiesImmutable; import javax.media.opengl.GLCapabilitiesChooser; import javax.media.opengl.GLDrawableFactory; import javax.media.opengl.GLException; -import javax.media.opengl.GLPbuffer; import javax.media.opengl.GLProfile; +import com.jogamp.common.nio.Buffers; import com.jogamp.nativewindow.MutableGraphicsConfiguration; -import com.jogamp.opengl.GLExtensions; +import com.jogamp.opengl.GLRendererQuirks; import jogamp.nativewindow.windows.DWM_BLURBEHIND; import jogamp.nativewindow.windows.GDI; +import jogamp.nativewindow.windows.GDIUtil; import jogamp.nativewindow.windows.MARGINS; import jogamp.nativewindow.windows.PIXELFORMATDESCRIPTOR; -import jogamp.opengl.GLContextImpl; import jogamp.opengl.GLGraphicsConfigurationUtil; -@SuppressWarnings("deprecation") -public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguration implements Cloneable { +public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguration implements Cloneable { protected static final int MAX_PFORMATS = 256; protected static final int MAX_ATTRIBS = 256; - private GLCapabilitiesChooser chooser; + private final GLCapabilitiesChooser chooser; private boolean isDetermined = false; private boolean isExternal = false; - WindowsWGLGraphicsConfiguration(AbstractGraphicsScreen screen, - GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, - GLCapabilitiesChooser chooser) { + WindowsWGLGraphicsConfiguration(final AbstractGraphicsScreen screen, + final GLCapabilitiesImmutable capsChosen, final GLCapabilitiesImmutable capsRequested, + final GLCapabilitiesChooser chooser) { super(screen, capsChosen, capsRequested); this.chooser=chooser; this.isDetermined = false; } - WindowsWGLGraphicsConfiguration(AbstractGraphicsScreen screen, - WGLGLCapabilities capsChosen, GLCapabilitiesImmutable capsRequested) { + WindowsWGLGraphicsConfiguration(final AbstractGraphicsScreen screen, + final WGLGLCapabilities capsChosen, final GLCapabilitiesImmutable capsRequested) { super(screen, capsChosen, capsRequested); setCapsPFD(capsChosen); this.chooser=null; } - static WindowsWGLGraphicsConfiguration createFromExternal(GLDrawableFactory _factory, long hdc, int pfdID, - GLProfile glp, AbstractGraphicsScreen screen, boolean onscreen) + static WindowsWGLGraphicsConfiguration createFromExternal(final GLDrawableFactory _factory, final long hdc, final int pfdID, + GLProfile glp, final AbstractGraphicsScreen screen, final boolean onscreen) { if(_factory==null) { throw new GLException("Null factory"); @@ -97,10 +98,10 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio if(null==glp) { glp = GLProfile.getDefault(screen.getDevice()); } - WindowsWGLDrawableFactory factory = (WindowsWGLDrawableFactory) _factory; - AbstractGraphicsDevice device = screen.getDevice(); - WindowsWGLDrawableFactory.SharedResource sharedResource = factory.getOrCreateSharedResource(device); - boolean hasARB = null != sharedResource && sharedResource.hasARBPixelFormat(); + final WindowsWGLDrawableFactory factory = (WindowsWGLDrawableFactory) _factory; + final AbstractGraphicsDevice device = screen.getDevice(); + final WindowsWGLDrawableFactory.SharedResource sharedResource = factory.getOrCreateSharedResourceImpl(device); + final boolean hasARB = null != sharedResource && sharedResource.hasARBPixelFormat(); WGLGLCapabilities caps = null; @@ -114,11 +115,12 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio ", pfdID "+pfdID+", onscreen "+onscreen+", hasARB "+hasARB); } - WindowsWGLGraphicsConfiguration cfg = new WindowsWGLGraphicsConfiguration(screen, caps, caps); + final WindowsWGLGraphicsConfiguration cfg = new WindowsWGLGraphicsConfiguration(screen, caps, caps); cfg.markExternal(); return cfg; } + @Override public Object clone() { return super.clone(); } @@ -135,7 +137,7 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio * @see #isDetermined() * @see #isExternal() */ - public final void updateGraphicsConfiguration(GLDrawableFactory factory, NativeSurface ns, int[] pfIDs) { + public final void updateGraphicsConfiguration(final GLDrawableFactory factory, final NativeSurface ns, final int[] pfIDs) { WindowsWGLGraphicsConfigurationFactory.updateGraphicsConfiguration(chooser, factory, ns, pfIDs); } @@ -149,32 +151,32 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio * * @see #isDetermined() */ - public final void preselectGraphicsConfiguration(GLDrawableFactory factory, int[] pfdIDs) { - AbstractGraphicsDevice device = getScreen().getDevice(); + public final void preselectGraphicsConfiguration(final GLDrawableFactory factory, final int[] pfdIDs) { + final AbstractGraphicsDevice device = getScreen().getDevice(); WindowsWGLGraphicsConfigurationFactory.preselectGraphicsConfiguration(chooser, factory, device, this, pfdIDs); } /** * Sets the hdc's PixelFormat, this configuration's capabilities and marks it as determined. */ - final void setPixelFormat(long hdc, WGLGLCapabilities caps) { + final void setPixelFormat(final long hdc, final WGLGLCapabilities caps) { if (0 == hdc) { throw new GLException("Error: HDC is null"); } - + if (!WGLUtil.SetPixelFormat(hdc, caps.getPFDID(), caps.getPFD())) { throw new GLException("Unable to set pixel format " + caps.getPFDID() + " of " + caps + " for device context " + toHexString(hdc) + ": error code " + GDI.GetLastError()); } - if(!caps.isBackgroundOpaque()) { + if( !caps.isBackgroundOpaque() ) { final long hwnd = GDI.WindowFromDC(hdc); - DWM_BLURBEHIND bb = DWM_BLURBEHIND.create(); - bb.setDwFlags(GDI.DWM_BB_ENABLE); - bb.setFEnable(1); + final DWM_BLURBEHIND bb = DWM_BLURBEHIND.create(); + bb.setDwFlags(GDI.DWM_BB_ENABLE| GDI.DWM_BB_TRANSITIONONMAXIMIZED); + bb.setFEnable( 1 ); boolean ok = GDI.DwmEnableBlurBehindWindow(hwnd, bb); - if(ok) { - MARGINS m = MARGINS.create(); + if( ok ) { + final MARGINS m = MARGINS.create(); m.setCxLeftWidth(-1); m.setCxRightWidth(-1); m.setCyBottomHeight(-1); @@ -182,7 +184,9 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio ok = GDI.DwmExtendFrameIntoClientArea(hwnd, m); } if(DEBUG) { - System.err.println("translucency enabled on wnd: 0x"+Long.toHexString(hwnd)+" - ok: "+ok); + final boolean isUndecorated = GDIUtil.IsUndecorated(hwnd); + final boolean isChild = GDIUtil.IsChild(hwnd); + System.err.println("translucency enabled on wnd: 0x"+Long.toHexString(hwnd)+" - isUndecorated "+isUndecorated+", isChild "+isChild+", ok: "+ok); } } if (DEBUG) { @@ -190,12 +194,12 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio } setCapsPFD(caps); } - + /** * Only sets this configuration's capabilities and marks it as determined, * the actual pixelformat is not set. */ - final void setCapsPFD(WGLGLCapabilities caps) { + final void setCapsPFD(final WGLGLCapabilities caps) { setChosenCapabilities(caps); this.isDetermined = true; if (DEBUG) { @@ -207,90 +211,81 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio * External configuration's HDC pixelformat shall not be modified */ public final boolean isExternal() { return isExternal; } - + final void markExternal() { this.isExternal=true; } - + /** * Determined configuration states set target capabilties via {@link #setCapsPFD(WGLGLCapabilities)}, * but does not imply a set pixelformat. - * - * @see #setPixelFormat(long, WGLGLCapabilities) + * + * @see #setPixelFormat(long, WGLGLCapabilities) * @see #setCapsPFD(WGLGLCapabilities) */ public final boolean isDetermined() { return isDetermined; } - + public final PIXELFORMATDESCRIPTOR getPixelFormat() { return isDetermined ? ((WGLGLCapabilities)capabilitiesChosen).getPFD() : null; } public final int getPixelFormatID() { return isDetermined ? ((WGLGLCapabilities)capabilitiesChosen).getPFDID() : 0; } public final boolean isChoosenByARB() { return isDetermined ? ((WGLGLCapabilities)capabilitiesChosen).isSetByARB() : false; } - static int fillAttribsForGeneralWGLARBQuery(WindowsWGLDrawableFactory.SharedResource sharedResource, int[] iattributes) { + static int fillAttribsForGeneralWGLARBQuery(final WindowsWGLDrawableFactory.SharedResource sharedResource, final IntBuffer iattributes) { int niattribs = 0; - iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_WINDOW_ARB; + iattributes.put(niattribs++, WGLExt.WGL_DRAW_TO_WINDOW_ARB); if(sharedResource.hasARBPBuffer()) { - iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_PBUFFER_ARB; - } - iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_BITMAP_ARB; - iattributes[niattribs++] = WGLExt.WGL_ACCELERATION_ARB; - iattributes[niattribs++] = WGLExt.WGL_SUPPORT_OPENGL_ARB; - iattributes[niattribs++] = WGLExt.WGL_DEPTH_BITS_ARB; - iattributes[niattribs++] = WGLExt.WGL_STENCIL_BITS_ARB; - iattributes[niattribs++] = WGLExt.WGL_DOUBLE_BUFFER_ARB; - iattributes[niattribs++] = WGLExt.WGL_STEREO_ARB; - iattributes[niattribs++] = WGLExt.WGL_PIXEL_TYPE_ARB; - iattributes[niattribs++] = WGLExt.WGL_RED_BITS_ARB; - iattributes[niattribs++] = WGLExt.WGL_GREEN_BITS_ARB; - iattributes[niattribs++] = WGLExt.WGL_BLUE_BITS_ARB; - iattributes[niattribs++] = WGLExt.WGL_ALPHA_BITS_ARB; - iattributes[niattribs++] = WGLExt.WGL_ACCUM_RED_BITS_ARB; - iattributes[niattribs++] = WGLExt.WGL_ACCUM_GREEN_BITS_ARB; - iattributes[niattribs++] = WGLExt.WGL_ACCUM_BLUE_BITS_ARB; - iattributes[niattribs++] = WGLExt.WGL_ACCUM_ALPHA_BITS_ARB; + iattributes.put(niattribs++, WGLExt.WGL_DRAW_TO_PBUFFER_ARB); + } + iattributes.put(niattribs++, WGLExt.WGL_DRAW_TO_BITMAP_ARB); + iattributes.put(niattribs++, WGLExt.WGL_ACCELERATION_ARB); + iattributes.put(niattribs++, WGLExt.WGL_SUPPORT_OPENGL_ARB); + iattributes.put(niattribs++, WGLExt.WGL_DEPTH_BITS_ARB); + iattributes.put(niattribs++, WGLExt.WGL_STENCIL_BITS_ARB); + iattributes.put(niattribs++, WGLExt.WGL_DOUBLE_BUFFER_ARB); + iattributes.put(niattribs++, WGLExt.WGL_STEREO_ARB); + iattributes.put(niattribs++, WGLExt.WGL_PIXEL_TYPE_ARB); + iattributes.put(niattribs++, WGLExt.WGL_RED_BITS_ARB); + iattributes.put(niattribs++, WGLExt.WGL_GREEN_BITS_ARB); + iattributes.put(niattribs++, WGLExt.WGL_BLUE_BITS_ARB); + iattributes.put(niattribs++, WGLExt.WGL_ALPHA_BITS_ARB); + iattributes.put(niattribs++, WGLExt.WGL_ACCUM_RED_BITS_ARB); + iattributes.put(niattribs++, WGLExt.WGL_ACCUM_GREEN_BITS_ARB); + iattributes.put(niattribs++, WGLExt.WGL_ACCUM_BLUE_BITS_ARB); + iattributes.put(niattribs++, WGLExt.WGL_ACCUM_ALPHA_BITS_ARB); if(sharedResource.hasARBMultisample()) { - iattributes[niattribs++] = WGLExt.WGL_SAMPLE_BUFFERS_ARB; - iattributes[niattribs++] = WGLExt.WGL_SAMPLES_ARB; + iattributes.put(niattribs++, WGLExt.WGL_SAMPLE_BUFFERS_ARB); + iattributes.put(niattribs++, WGLExt.WGL_SAMPLES_ARB); } - - if(sharedResource.hasARBPBuffer()) { - GLContextImpl sharedCtx = sharedResource.getContext(); - if(null != sharedCtx && sharedCtx.isExtensionAvailable(WindowsWGLDrawableFactory.WGL_NV_float_buffer)) { - // pbo float buffer - iattributes[niattribs++] = WGLExt.WGL_FLOAT_COMPONENTS_NV; // nvidia - } - } - return niattribs; } - - static boolean wglARBPFIDValid(WindowsWGLContext sharedCtx, long hdc, int pfdID) { - int[] in = new int[1]; - int[] out = new int[1]; - in[0] = WGLExt.WGL_COLOR_BITS_ARB; - if (!sharedCtx.getWGLExt().wglGetPixelFormatAttribivARB(hdc, pfdID, 0, 1, in, 0, out, 0)) { + + static boolean wglARBPFIDValid(final WindowsWGLContext sharedCtx, final long hdc, final int pfdID) { + final IntBuffer out = Buffers.newDirectIntBuffer(1); + final IntBuffer in = Buffers.newDirectIntBuffer(1); + in.put(0, WGLExt.WGL_COLOR_BITS_ARB); + if (!sharedCtx.getWGLExt().wglGetPixelFormatAttribivARB(hdc, pfdID, 0, 1, in, out)) { // Some GPU's falsely fails with a zero error code (success) return GDI.GetLastError() == GDI.ERROR_SUCCESS ; } return true; } - static int wglARBPFDIDCount(WindowsWGLContext sharedCtx, long hdc) { - int[] iattributes = new int[1]; - int[] iresults = new int[1]; + static int wglARBPFDIDCount(final WindowsWGLContext sharedCtx, final long hdc) { + final IntBuffer iresults = Buffers.newDirectIntBuffer(1); + final IntBuffer iattributes = Buffers.newDirectIntBuffer(1); + iattributes.put(0, WGLExt.WGL_NUMBER_PIXEL_FORMATS_ARB); - WGLExt wglExt = sharedCtx.getWGLExt(); - iattributes[0] = WGLExt.WGL_NUMBER_PIXEL_FORMATS_ARB; + final WGLExt wglExt = sharedCtx.getWGLExt(); // pfdID shall be ignored here (spec), however, pass a valid pdf index '1' below (possible driver bug) - if (!wglExt.wglGetPixelFormatAttribivARB(hdc, 1 /* pfdID */, 0, 1, iattributes, 0, iresults, 0)) { + if (!wglExt.wglGetPixelFormatAttribivARB(hdc, 1 /* pfdID */, 0, 1, iattributes, iresults)) { if(DEBUG) { System.err.println("GetPixelFormatAttribivARB: Failed - HDC 0x" + Long.toHexString(hdc) + - ", value "+iresults[0]+ + ", value "+iresults.get(0)+ ", LastError: " + GDI.GetLastError()); Thread.dumpStack(); } return 0; } - final int pfdIDCount = iresults[0]; + final int pfdIDCount = iresults.get(0); if(0 == pfdIDCount) { if(DEBUG) { System.err.println("GetPixelFormatAttribivARB: No formats - HDC 0x" + Long.toHexString(hdc) + @@ -300,42 +295,60 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio } return pfdIDCount; } - - static int[] wglAllARBPFDIDs(int pfdIDCount) { - int[] pfdIDs = new int[pfdIDCount]; + + static int[] wglAllARBPFDIDs(final int pfdIDCount) { + final int[] pfdIDs = new int[pfdIDCount]; for (int i = 0; i < pfdIDCount; i++) { pfdIDs[i] = 1 + i; } return pfdIDs; } - - static WGLGLCapabilities wglARBPFID2GLCapabilities(WindowsWGLDrawableFactory.SharedResource sharedResource, - AbstractGraphicsDevice device, GLProfile glp, - long hdc, int pfdID, int winattrbits) { + + static WGLGLCapabilities wglARBPFID2GLCapabilities(final WindowsWGLDrawableFactory.SharedResource sharedResource, + final AbstractGraphicsDevice device, final GLProfile glp, + final long hdc, final int pfdID, final int winattrbits) { if (!sharedResource.hasARBPixelFormat()) { return null; } - int[] iattributes = new int [2*MAX_ATTRIBS]; - int[] iresults = new int [2*MAX_ATTRIBS]; - - int niattribs = fillAttribsForGeneralWGLARBQuery(sharedResource, iattributes); + final IntBuffer iattributes = Buffers.newDirectIntBuffer(2*MAX_ATTRIBS); + final IntBuffer iresults = Buffers.newDirectIntBuffer(2*MAX_ATTRIBS); + final int niattribs = fillAttribsForGeneralWGLARBQuery(sharedResource, iattributes); - if (!((WindowsWGLContext)sharedResource.getContext()).getWGLExt().wglGetPixelFormatAttribivARB(hdc, pfdID, 0, niattribs, iattributes, 0, iresults, 0)) { - throw new GLException("wglARBPFID2GLCapabilities: Error getting pixel format attributes for pixel format " + pfdID + + if ( !( (WindowsWGLContext)sharedResource.getContext()).getWGLExt() + .wglGetPixelFormatAttribivARB(hdc, pfdID, 0, niattribs, iattributes, iresults) ) { + throw new GLException("wglARBPFID2GLCapabilities: Error getting pixel format attributes for pixel format " + pfdID + " of device context " + toHexString(hdc) + ", werr " + GDI.GetLastError()); } return AttribList2GLCapabilities(device, glp, hdc, pfdID, iattributes, niattribs, iresults, winattrbits); } - static int[] wglChoosePixelFormatARB(WindowsWGLDrawableFactory.SharedResource sharedResource, AbstractGraphicsDevice device, - GLCapabilitiesImmutable capabilities, - long hdc, int[] iattributes, int accelerationMode, float[] fattributes) + static WGLGLCapabilities wglARBPFID2GLCapabilitiesNoCheck(final WindowsWGLDrawableFactory.SharedResource sharedResource, + final AbstractGraphicsDevice device, final GLProfile glp, + final long hdc, final int pfdID, final int winattrbits) { + if (!sharedResource.hasARBPixelFormat()) { + return null; + } + + final IntBuffer iattributes = Buffers.newDirectIntBuffer(2 * MAX_ATTRIBS); + final IntBuffer iresults = Buffers.newDirectIntBuffer(2 * MAX_ATTRIBS); + final int niattribs = fillAttribsForGeneralWGLARBQuery(sharedResource, iattributes); + + if ( !( (WindowsWGLContext)sharedResource.getContext()).getWGLExt() + .wglGetPixelFormatAttribivARB(hdc, pfdID, 0, niattribs, iattributes, iresults) ) { + throw new GLException("wglARBPFID2GLCapabilities: Error getting pixel format attributes for pixel format " + + pfdID + " of device context " + toHexString(hdc) + ", werr " + GDI.GetLastError()); + } + return AttribList2GLCapabilitiesNoCheck(device, glp, hdc, pfdID, iattributes, niattribs, iresults, winattrbits); + } + + static int[] wglChoosePixelFormatARB(final WindowsWGLDrawableFactory.SharedResource sharedResource, + final AbstractGraphicsDevice device, final GLCapabilitiesImmutable capabilities, + final long hdc, final IntBuffer iattributes, final int accelerationMode, + final FloatBuffer fattributes) { - - if ( !WindowsWGLGraphicsConfiguration.GLCapabilities2AttribList(capabilities, - iattributes, sharedResource, accelerationMode, null)) - { + if ( !WindowsWGLGraphicsConfiguration.GLCapabilities2AttribList( sharedResource, capabilities, + iattributes, accelerationMode, null) ) { if (DEBUG) { System.err.println("wglChoosePixelFormatARB: GLCapabilities2AttribList failed: " + GDI.GetLastError()); Thread.dumpStack(); @@ -343,62 +356,74 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio return null; } - int[] pformatsTmp = new int[WindowsWGLGraphicsConfiguration.MAX_PFORMATS]; - int[] numFormatsTmp = new int[1]; - if ( !((WindowsWGLContext)sharedResource.getContext()).getWGLExt().wglChoosePixelFormatARB(hdc, iattributes, 0, - fattributes, 0, - WindowsWGLGraphicsConfiguration.MAX_PFORMATS, - pformatsTmp, 0, numFormatsTmp, 0)) - { + final WGLExt wglExt = ((WindowsWGLContext)sharedResource.getContext()).getWGLExt(); + final IntBuffer pformatsTmp = Buffers.newDirectIntBuffer(WindowsWGLGraphicsConfiguration.MAX_PFORMATS); + final IntBuffer numFormatsTmp = Buffers.newDirectIntBuffer(1); + + if ( !wglExt.wglChoosePixelFormatARB(hdc, iattributes, fattributes, + WindowsWGLGraphicsConfiguration.MAX_PFORMATS, + pformatsTmp, numFormatsTmp) ) { if (DEBUG) { System.err.println("wglChoosePixelFormatARB: wglChoosePixelFormatARB failed: " + GDI.GetLastError()); Thread.dumpStack(); } return null; } - int numFormats = numFormatsTmp[0]; - int[] pformats = null; + final int numFormats = Math.min(numFormatsTmp.get(0), WindowsWGLGraphicsConfiguration.MAX_PFORMATS); + final int[] pformats; if( 0 < numFormats ) { pformats = new int[numFormats]; - System.arraycopy(pformatsTmp, 0, pformats, 0, numFormats); + pformatsTmp.get(pformats, 0, numFormats); + } else { + pformats = null; } if (DEBUG) { System.err.println("wglChoosePixelFormatARB: NumFormats (wglChoosePixelFormatARB) accelMode 0x" + Integer.toHexString(accelerationMode) + ": " + numFormats); for (int i = 0; i < numFormats; i++) { - WGLGLCapabilities dbgCaps0 = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities( - sharedResource, device, capabilities.getGLProfile(), hdc, pformats[i], GLGraphicsConfigurationUtil.ALL_BITS); + final WGLGLCapabilities dbgCaps0 = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities( + sharedResource, device, capabilities.getGLProfile(), hdc, + pformats[i], GLGraphicsConfigurationUtil.ALL_BITS); System.err.println("pixel format " + pformats[i] + " (index " + i + "): " + dbgCaps0); } } return pformats; } - static List <GLCapabilitiesImmutable> wglARBPFIDs2GLCapabilities(WindowsWGLDrawableFactory.SharedResource sharedResource, - AbstractGraphicsDevice device, GLProfile glp, long hdc, int[] pfdIDs, int winattrbits) { + static List <GLCapabilitiesImmutable> wglARBPFIDs2GLCapabilities(final WindowsWGLDrawableFactory.SharedResource sharedResource, + final AbstractGraphicsDevice device, final GLProfile glp, + final long hdc, final int[] pfdIDs, final int winattrbits, + final boolean onlyFirstValid) { if (!sharedResource.hasARBPixelFormat()) { return null; } final int numFormats = pfdIDs.length; - int[] iattributes = new int [2*MAX_ATTRIBS]; - int[] iresults = new int [2*MAX_ATTRIBS]; - int niattribs = fillAttribsForGeneralWGLARBQuery(sharedResource, iattributes); + final IntBuffer iattributes = Buffers.newDirectIntBuffer(2*MAX_ATTRIBS); + final IntBuffer iresults = Buffers.newDirectIntBuffer(2*MAX_ATTRIBS); + final int niattribs = fillAttribsForGeneralWGLARBQuery(sharedResource, iattributes); - ArrayList<GLCapabilitiesImmutable> bucket = new ArrayList<GLCapabilitiesImmutable>(); + final ArrayList<GLCapabilitiesImmutable> bucket = new ArrayList<GLCapabilitiesImmutable>(); for(int i = 0; i<numFormats; i++) { if ( pfdIDs[i] >= 1 && - ((WindowsWGLContext)sharedResource.getContext()).getWGLExt().wglGetPixelFormatAttribivARB(hdc, pfdIDs[i], 0, niattribs, iattributes, 0, iresults, 0) ) { - final GLCapabilitiesImmutable caps = AttribList2GLCapabilities(device, glp, hdc, pfdIDs[i], iattributes, niattribs, iresults, winattrbits); + ((WindowsWGLContext)sharedResource.getContext()).getWGLExt() + .wglGetPixelFormatAttribivARB(hdc, pfdIDs[i], 0, niattribs, iattributes, iresults) ) { + final GLCapabilitiesImmutable caps = + AttribList2GLCapabilities(device, glp, hdc, pfdIDs[i], iattributes, niattribs, iresults, winattrbits); if(null != caps) { bucket.add(caps); if(DEBUG) { - final int j = bucket.size() - 1; + final int j = bucket.size() - 1; System.err.println("wglARBPFIDs2GLCapabilities: bucket["+i+" -> "+j+"]: "+caps); } + if( onlyFirstValid ) { + break; + } } else if(DEBUG) { - GLCapabilitiesImmutable skipped = AttribList2GLCapabilities(device, glp, hdc, pfdIDs[i], iattributes, niattribs, iresults, GLGraphicsConfigurationUtil.ALL_BITS); + final GLCapabilitiesImmutable skipped = + AttribList2GLCapabilitiesNoCheck(device, glp, hdc, pfdIDs[i], + iattributes, niattribs, iresults, GLGraphicsConfigurationUtil.ALL_BITS); System.err.println("wglARBPFIDs2GLCapabilities: bucket["+i+" -> skip]: pfdID "+pfdIDs[i]+", "+skipped+", winattr "+GLGraphicsConfigurationUtil.winAttributeBits2String(null, winattrbits).toString()); } } else if (DEBUG) { @@ -413,29 +438,29 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio return bucket; } - static boolean GLCapabilities2AttribList(GLCapabilitiesImmutable caps, - int[] iattributes, - WindowsWGLDrawableFactory.SharedResource sharedResource, - int accelerationValue, - int[] floatMode) throws GLException { + static boolean GLCapabilities2AttribList(final WindowsWGLDrawableFactory.SharedResource sharedResource, + final GLCapabilitiesImmutable caps, + final IntBuffer iattributes, + final int accelerationValue, + final int[] floatMode) throws GLException { if (!sharedResource.hasARBPixelFormat()) { return false; } int niattribs = 0; - iattributes[niattribs++] = WGLExt.WGL_SUPPORT_OPENGL_ARB; - iattributes[niattribs++] = GL.GL_TRUE; + iattributes.put(niattribs++, WGLExt.WGL_SUPPORT_OPENGL_ARB); + iattributes.put(niattribs++, GL.GL_TRUE); if(accelerationValue>0) { - iattributes[niattribs++] = WGLExt.WGL_ACCELERATION_ARB; - iattributes[niattribs++] = accelerationValue; + iattributes.put(niattribs++, WGLExt.WGL_ACCELERATION_ARB); + iattributes.put(niattribs++, accelerationValue); } final boolean usePBuffer = caps.isPBuffer() && sharedResource.hasARBPBuffer() ; - + final int surfaceType; if( caps.isOnscreen() ) { - surfaceType = WGLExt.WGL_DRAW_TO_WINDOW_ARB; + surfaceType = WGLExt.WGL_DRAW_TO_WINDOW_ARB; } else if( caps.isFBO() ) { surfaceType = WGLExt.WGL_DRAW_TO_WINDOW_ARB; // native replacement! } else if( usePBuffer ) { @@ -445,169 +470,96 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio } else { throw new GLException("no surface type set in caps: "+caps); } - iattributes[niattribs++] = surfaceType; - iattributes[niattribs++] = GL.GL_TRUE; - - iattributes[niattribs++] = WGLExt.WGL_DOUBLE_BUFFER_ARB; + iattributes.put(niattribs++, surfaceType); + iattributes.put(niattribs++, GL.GL_TRUE); + + iattributes.put(niattribs++, WGLExt.WGL_DOUBLE_BUFFER_ARB); if (caps.getDoubleBuffered()) { - iattributes[niattribs++] = GL.GL_TRUE; + iattributes.put(niattribs++, GL.GL_TRUE); } else { - iattributes[niattribs++] = GL.GL_FALSE; + iattributes.put(niattribs++, GL.GL_FALSE); } - iattributes[niattribs++] = WGLExt.WGL_STEREO_ARB; + iattributes.put(niattribs++, WGLExt.WGL_STEREO_ARB); if (caps.getStereo()) { - iattributes[niattribs++] = GL.GL_TRUE; + iattributes.put(niattribs++, GL.GL_TRUE); } else { - iattributes[niattribs++] = GL.GL_FALSE; - } - - iattributes[niattribs++] = WGLExt.WGL_RED_BITS_ARB; - iattributes[niattribs++] = caps.getRedBits(); - iattributes[niattribs++] = WGLExt.WGL_GREEN_BITS_ARB; - iattributes[niattribs++] = caps.getGreenBits(); - iattributes[niattribs++] = WGLExt.WGL_BLUE_BITS_ARB; - iattributes[niattribs++] = caps.getBlueBits(); + iattributes.put(niattribs++, GL.GL_FALSE); + } + + iattributes.put(niattribs++, WGLExt.WGL_RED_BITS_ARB); + iattributes.put(niattribs++, caps.getRedBits()); + iattributes.put(niattribs++, WGLExt.WGL_GREEN_BITS_ARB); + iattributes.put(niattribs++, caps.getGreenBits()); + iattributes.put(niattribs++, WGLExt.WGL_BLUE_BITS_ARB); + iattributes.put(niattribs++, caps.getBlueBits()); if(caps.getAlphaBits()>0) { - iattributes[niattribs++] = WGLExt.WGL_ALPHA_BITS_ARB; - iattributes[niattribs++] = caps.getAlphaBits(); + iattributes.put(niattribs++, WGLExt.WGL_ALPHA_BITS_ARB); + iattributes.put(niattribs++, caps.getAlphaBits()); } if(caps.getStencilBits()>0) { - iattributes[niattribs++] = WGLExt.WGL_STENCIL_BITS_ARB; - iattributes[niattribs++] = caps.getStencilBits(); + iattributes.put(niattribs++, WGLExt.WGL_STENCIL_BITS_ARB); + iattributes.put(niattribs++, caps.getStencilBits()); } - iattributes[niattribs++] = WGLExt.WGL_DEPTH_BITS_ARB; - iattributes[niattribs++] = caps.getDepthBits(); - if (caps.getAccumRedBits() > 0 || + iattributes.put(niattribs++, WGLExt.WGL_DEPTH_BITS_ARB); + iattributes.put(niattribs++, caps.getDepthBits()); + + if( caps.getAccumRedBits() > 0 || caps.getAccumGreenBits() > 0 || caps.getAccumBlueBits() > 0 || - caps.getAccumAlphaBits() > 0) { - iattributes[niattribs++] = WGLExt.WGL_ACCUM_BITS_ARB; - iattributes[niattribs++] = (caps.getAccumRedBits() + - caps.getAccumGreenBits() + - caps.getAccumBlueBits() + - caps.getAccumAlphaBits()); - iattributes[niattribs++] = WGLExt.WGL_ACCUM_RED_BITS_ARB; - iattributes[niattribs++] = caps.getAccumRedBits(); - iattributes[niattribs++] = WGLExt.WGL_ACCUM_GREEN_BITS_ARB; - iattributes[niattribs++] = caps.getAccumGreenBits(); - iattributes[niattribs++] = WGLExt.WGL_ACCUM_BLUE_BITS_ARB; - iattributes[niattribs++] = caps.getAccumBlueBits(); - iattributes[niattribs++] = WGLExt.WGL_ACCUM_ALPHA_BITS_ARB; - iattributes[niattribs++] = caps.getAccumAlphaBits(); + caps.getAccumAlphaBits() > 0 ) { + final GLRendererQuirks sharedQuirks = sharedResource.getRendererQuirks(); + if ( !usePBuffer || null==sharedQuirks || !sharedQuirks.exist(GLRendererQuirks.NoPBufferWithAccum) ) { + iattributes.put(niattribs++, WGLExt.WGL_ACCUM_BITS_ARB); + iattributes.put(niattribs++, ( caps.getAccumRedBits() + + caps.getAccumGreenBits() + + caps.getAccumBlueBits() + + caps.getAccumAlphaBits() ) ); + iattributes.put(niattribs++, WGLExt.WGL_ACCUM_RED_BITS_ARB); + iattributes.put(niattribs++, caps.getAccumRedBits()); + iattributes.put(niattribs++, WGLExt.WGL_ACCUM_GREEN_BITS_ARB); + iattributes.put(niattribs++, caps.getAccumGreenBits()); + iattributes.put(niattribs++, WGLExt.WGL_ACCUM_BLUE_BITS_ARB); + iattributes.put(niattribs++, caps.getAccumBlueBits()); + iattributes.put(niattribs++, WGLExt.WGL_ACCUM_ALPHA_BITS_ARB); + iattributes.put(niattribs++, caps.getAccumAlphaBits()); + } } if (caps.getSampleBuffers() && sharedResource.hasARBMultisample()) { - iattributes[niattribs++] = WGLExt.WGL_SAMPLE_BUFFERS_ARB; - iattributes[niattribs++] = GL.GL_TRUE; - iattributes[niattribs++] = WGLExt.WGL_SAMPLES_ARB; - iattributes[niattribs++] = caps.getNumSamples(); - } - - boolean rtt = caps.getPbufferRenderToTexture(); - boolean rect = caps.getPbufferRenderToTextureRectangle(); - boolean useFloat = caps.getPbufferFloatingPointBuffers(); - boolean ati = false; - boolean nvidia = false; - if ( usePBuffer ) { - // Check some invariants and set up some state - if (rect && !rtt) { - throw new GLException("Render-to-texture-rectangle requires render-to-texture to be specified"); - } - - GLContextImpl sharedCtx = sharedResource.getContext(); - if (rect) { - if (!sharedCtx.isExtensionAvailable(GLExtensions.NV_texture_rectangle)) { - throw new GLException("Render-to-texture-rectangle requires GL_NV_texture_rectangle extension"); - } - } - - if (useFloat) { - // Prefer NVidia extension over ATI - nvidia = sharedCtx.isExtensionAvailable(WindowsWGLDrawableFactory.WGL_NV_float_buffer); - if(nvidia) { - floatMode[0] = GLPbuffer.NV_FLOAT; - } else { - ati = sharedCtx.isExtensionAvailable("WGL_ATI_pixel_format_float"); - if(ati) { - floatMode[0] = GLPbuffer.ATI_FLOAT; - } else { - throw new GLException("Floating-point pbuffers not supported by this hardware"); - } - } - - if (DEBUG) { - System.err.println("Using " + (ati ? "ATI" : ( nvidia ? "NVidia" : "NONE" ) ) + " floating-point extension"); - } - } - - // See whether we need to change the pixel type to support ATI's - // floating-point pbuffers - if (useFloat && ati) { - if (rtt) { - throw new GLException("Render-to-floating-point-texture not supported on ATI hardware"); - } else { - iattributes[niattribs++] = WGLExt.WGL_PIXEL_TYPE_ARB; - iattributes[niattribs++] = WGLExt.WGL_TYPE_RGBA_FLOAT_ARB; - } - } else { - if (!rtt) { - // Currently we don't support non-truecolor visuals in the - // GLCapabilities, so we don't offer the option of making - // color-index pbuffers. - iattributes[niattribs++] = WGLExt.WGL_PIXEL_TYPE_ARB; - iattributes[niattribs++] = WGLExt.WGL_TYPE_RGBA_ARB; - } - } - - if (useFloat && nvidia) { - iattributes[niattribs++] = WGLExt.WGL_FLOAT_COMPONENTS_NV; - iattributes[niattribs++] = GL.GL_TRUE; - } - - if (rtt) { - if (useFloat) { - assert(!ati); - assert(nvidia); - if (!rect) { - throw new GLException("Render-to-floating-point-texture only supported on NVidia hardware with render-to-texture-rectangle"); - } - iattributes[niattribs++] = WGLExt.WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV; - iattributes[niattribs++] = GL.GL_TRUE; - } else { - iattributes[niattribs++] = rect ? WGLExt.WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV : WGLExt.WGL_BIND_TO_TEXTURE_RGB_ARB; - iattributes[niattribs++] = GL.GL_TRUE; - } - } - } else { - iattributes[niattribs++] = WGLExt.WGL_PIXEL_TYPE_ARB; - iattributes[niattribs++] = WGLExt.WGL_TYPE_RGBA_ARB; + iattributes.put(niattribs++, WGLExt.WGL_SAMPLE_BUFFERS_ARB); + iattributes.put(niattribs++, GL.GL_TRUE); + iattributes.put(niattribs++, WGLExt.WGL_SAMPLES_ARB); + iattributes.put(niattribs++, caps.getNumSamples()); } - iattributes[niattribs++] = 0; + + iattributes.put(niattribs++, WGLExt.WGL_PIXEL_TYPE_ARB); + iattributes.put(niattribs++, WGLExt.WGL_TYPE_RGBA_ARB); + iattributes.put(niattribs++, 0); return true; } - static int AttribList2DrawableTypeBits(final int[] iattribs, - final int niattribs, final int[] iresults) { + static int AttribList2DrawableTypeBits(final IntBuffer iattribs, + final int niattribs, final IntBuffer iresults) { int val = 0; for (int i = 0; i < niattribs; i++) { - int attr = iattribs[i]; + final int attr = iattribs.get(i); switch (attr) { case WGLExt.WGL_DRAW_TO_WINDOW_ARB: - if(iresults[i] == GL.GL_TRUE) { + if(iresults.get(i) == GL.GL_TRUE) { val |= GLGraphicsConfigurationUtil.WINDOW_BIT | GLGraphicsConfigurationUtil.FBO_BIT; } break; case WGLExt.WGL_DRAW_TO_BITMAP_ARB: - if(iresults[i] == GL.GL_TRUE) { + if(iresults.get(i) == GL.GL_TRUE) { val |= GLGraphicsConfigurationUtil.BITMAP_BIT; } break; case WGLExt.WGL_DRAW_TO_PBUFFER_ARB: - if(iresults[i] == GL.GL_TRUE) { + if(iresults.get(i) == GL.GL_TRUE) { val |= GLGraphicsConfigurationUtil.PBUFFER_BIT; } break; @@ -616,20 +568,23 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio return val; } - static WGLGLCapabilities AttribList2GLCapabilities(final AbstractGraphicsDevice device, + static WGLGLCapabilities AttribList2GLCapabilities(final AbstractGraphicsDevice device, final GLProfile glp, final long hdc, final int pfdID, - final int[] iattribs, final int niattribs, final int[] iresults, final int winattrmask) { + final IntBuffer iattribs, final int niattribs, final IntBuffer iresults, + final int winattrmask) { final int allDrawableTypeBits = AttribList2DrawableTypeBits(iattribs, niattribs, iresults); int drawableTypeBits = winattrmask & allDrawableTypeBits; if( 0 == drawableTypeBits ) { return null; } - PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor(); + final PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor(); - if (WGLUtil.DescribePixelFormat(hdc, pfdID, PIXELFORMATDESCRIPTOR.size(), pfd) == 0) { + if ( WGLUtil.DescribePixelFormat(hdc, pfdID, PIXELFORMATDESCRIPTOR.size(), pfd) == 0 ) { // remove displayable bits, since pfdID is non displayable - drawableTypeBits = drawableTypeBits & ~(GLGraphicsConfigurationUtil.WINDOW_BIT | GLGraphicsConfigurationUtil.BITMAP_BIT | GLGraphicsConfigurationUtil.FBO_BIT ); + drawableTypeBits = drawableTypeBits & ~( GLGraphicsConfigurationUtil.WINDOW_BIT | + GLGraphicsConfigurationUtil.BITMAP_BIT | + GLGraphicsConfigurationUtil.FBO_BIT ); if( 0 == drawableTypeBits ) { return null; } @@ -637,30 +592,50 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio } final WGLGLCapabilities res = new WGLGLCapabilities(pfd, pfdID, glp); res.setValuesByARB(iattribs, niattribs, iresults); - return (WGLGLCapabilities) GLGraphicsConfigurationUtil.fixWinAttribBitsAndHwAccel(device, drawableTypeBits, res); + return (WGLGLCapabilities) GLGraphicsConfigurationUtil + .fixWinAttribBitsAndHwAccel(device, drawableTypeBits, res); } + static WGLGLCapabilities AttribList2GLCapabilitiesNoCheck(final AbstractGraphicsDevice device, final GLProfile glp, + final long hdc, final int pfdID, + final IntBuffer iattribs, final int niattribs, + final IntBuffer iresults, final int winattrmask) { + final int allDrawableTypeBits = AttribList2DrawableTypeBits(iattribs, niattribs, iresults); + final int drawableTypeBits = winattrmask & allDrawableTypeBits; + + if (0 == drawableTypeBits) { + return null; + } + final PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor(); + + WGLUtil.DescribePixelFormat(hdc, pfdID, PIXELFORMATDESCRIPTOR.size(), pfd); + final WGLGLCapabilities res = new WGLGLCapabilities(pfd, pfdID, glp); + res.setValuesByARB(iattribs, niattribs, iresults); + return (WGLGLCapabilities) GLGraphicsConfigurationUtil + .fixWinAttribBitsAndHwAccel(device, drawableTypeBits, res); + } + // // GDI PIXELFORMAT // - static int[] wglAllGDIPFIDs(long hdc) { - int numFormats = WGLUtil.DescribePixelFormat(hdc, 1, 0, null); + static int[] wglAllGDIPFIDs(final long hdc) { + final int numFormats = WGLUtil.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]; + final int[] pfdIDs = new int[numFormats]; for (int i = 0; i < numFormats; i++) { pfdIDs[i] = 1 + i; } return pfdIDs; } - static int PFD2DrawableTypeBits(PIXELFORMATDESCRIPTOR pfd) { + static int PFD2DrawableTypeBits(final PIXELFORMATDESCRIPTOR pfd) { int val = 0; - int dwFlags = pfd.getDwFlags(); + final int dwFlags = pfd.getDwFlags(); if( 0 != (GDI.PFD_DRAW_TO_WINDOW & dwFlags ) ) { val |= GLGraphicsConfigurationUtil.WINDOW_BIT | @@ -672,43 +647,59 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio return val; } - static WGLGLCapabilities PFD2GLCapabilities(AbstractGraphicsDevice device, final GLProfile glp, final long hdc, final int pfdID, final int winattrmask) { - PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor(hdc, pfdID); + static WGLGLCapabilities PFD2GLCapabilities(final AbstractGraphicsDevice device, final GLProfile glp, + final long hdc, final int pfdID, final int winattrmask) { + final PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor(hdc, pfdID); if(null == pfd) { return null; } - if ((pfd.getDwFlags() & GDI.PFD_SUPPORT_OPENGL) == 0) { + if ( (pfd.getDwFlags() & GDI.PFD_SUPPORT_OPENGL) == 0) { return null; } final int allDrawableTypeBits = PFD2DrawableTypeBits(pfd); final int drawableTypeBits = winattrmask & allDrawableTypeBits; if( 0 == drawableTypeBits ) { + if(DEBUG) { + System.err.println("Drop [drawableType mismatch]: " + WGLGLCapabilities.PFD2String(pfd, pfdID)); + } return null; } + if( GLGraphicsConfigurationUtil.BITMAP_BIT == drawableTypeBits ) { + // BITMAP exclusive PFD SafeGuard: Only accept BITMAP compatible color formats! + final int pfdColorBits = pfd.getCColorBits(); + if ( pfdColorBits != 24 || 0 < pfd.getCAlphaBits() ) { // Allowed: RGB888 && !alpha + if(DEBUG) { + System.err.println("Drop [color bits excl BITMAP]: " + WGLGLCapabilities.PFD2String(pfd, pfdID)); + } + return null; + } + } final WGLGLCapabilities res = new WGLGLCapabilities(pfd, pfdID, glp); res.setValuesByGDI(); - return (WGLGLCapabilities) GLGraphicsConfigurationUtil.fixWinAttribBitsAndHwAccel(device, drawableTypeBits, res); + return (WGLGLCapabilities) GLGraphicsConfigurationUtil.fixWinAttribBitsAndHwAccel(device, drawableTypeBits, res); } - static WGLGLCapabilities PFD2GLCapabilitiesNoCheck(AbstractGraphicsDevice device, final GLProfile glp, final long hdc, final int pfdID) { - PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor(hdc, pfdID); + static WGLGLCapabilities PFD2GLCapabilitiesNoCheck(final AbstractGraphicsDevice device, final GLProfile glp, + final long hdc, final int pfdID) { + final PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor(hdc, pfdID); return PFD2GLCapabilitiesNoCheck(device, glp, pfd, pfdID); } - - static WGLGLCapabilities PFD2GLCapabilitiesNoCheck(AbstractGraphicsDevice device, GLProfile glp, PIXELFORMATDESCRIPTOR pfd, int pfdID) { + + static WGLGLCapabilities PFD2GLCapabilitiesNoCheck(final AbstractGraphicsDevice device, final GLProfile glp, + final PIXELFORMATDESCRIPTOR pfd, final int pfdID) { if(null == pfd) { return null; } final WGLGLCapabilities res = new WGLGLCapabilities(pfd, pfdID, glp); res.setValuesByGDI(); - - return (WGLGLCapabilities) GLGraphicsConfigurationUtil.fixWinAttribBitsAndHwAccel(device, PFD2DrawableTypeBits(pfd), res); + + return (WGLGLCapabilities) GLGraphicsConfigurationUtil.fixWinAttribBitsAndHwAccel(device, PFD2DrawableTypeBits(pfd), res); } - - static PIXELFORMATDESCRIPTOR GLCapabilities2PFD(GLCapabilitiesImmutable caps, PIXELFORMATDESCRIPTOR pfd) { - int colorDepth = (caps.getRedBits() + + + static PIXELFORMATDESCRIPTOR GLCapabilities2PFD(final GLCapabilitiesImmutable caps, final PIXELFORMATDESCRIPTOR pfd) { + final int colorDepth = (caps.getRedBits() + caps.getGreenBits() + caps.getBlueBits()); if (colorDepth < 15) { @@ -735,7 +726,7 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio pfdFlags |= GDI.PFD_DOUBLEBUFFER; } } - + if (caps.getStereo()) { pfdFlags |= GDI.PFD_STEREO; } @@ -746,7 +737,7 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio pfd.setCGreenBits((byte) caps.getGreenBits()); pfd.setCBlueBits ((byte) caps.getBlueBits()); pfd.setCAlphaBits((byte) caps.getAlphaBits()); - int accumDepth = (caps.getAccumRedBits() + + final int accumDepth = (caps.getAccumRedBits() + caps.getAccumGreenBits() + caps.getAccumBlueBits()); pfd.setCAccumBits ((byte) accumDepth); @@ -765,8 +756,8 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio return pfd; } - static PIXELFORMATDESCRIPTOR createPixelFormatDescriptor(long hdc, int pfdID) { - PIXELFORMATDESCRIPTOR pfd = PIXELFORMATDESCRIPTOR.create(); + static PIXELFORMATDESCRIPTOR createPixelFormatDescriptor(final long hdc, final int pfdID) { + final PIXELFORMATDESCRIPTOR pfd = PIXELFORMATDESCRIPTOR.create(); pfd.setNSize((short) PIXELFORMATDESCRIPTOR.size()); pfd.setNVersion((short) 1); if(0 != hdc && 1 <= pfdID) { @@ -785,6 +776,7 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio return createPixelFormatDescriptor(0, 0); } + @Override public String toString() { return "WindowsWGLGraphicsConfiguration["+getScreen()+", pfdID " + getPixelFormatID() + ", ARB-Choosen " + isChoosenByARB() + ",\n\trequested " + getRequestedCapabilities() + @@ -792,4 +784,3 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio "]"; } } - diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java index d2d1dafc8..ea9b86712 100644 --- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java +++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java @@ -1,22 +1,22 @@ /* * 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 * 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 @@ -50,12 +50,17 @@ import javax.media.opengl.GLDrawableFactory; import javax.media.opengl.GLException; import javax.media.opengl.GLProfile; +import com.jogamp.common.nio.Buffers; +import com.jogamp.opengl.GLRendererQuirks; + import jogamp.nativewindow.windows.GDI; import jogamp.nativewindow.windows.PIXELFORMATDESCRIPTOR; import jogamp.opengl.GLDrawableImpl; import jogamp.opengl.GLGraphicsConfigurationFactory; import jogamp.opengl.GLGraphicsConfigurationUtil; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -69,13 +74,17 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat static VisualIDHolder.VIDComparator PfdIDComparator = new VisualIDHolder.VIDComparator(VisualIDHolder.VIDType.WIN32_PFD); static void registerFactory() { - GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.windows.WindowsGraphicsDevice.class, GLCapabilitiesImmutable.class, new WindowsWGLGraphicsConfigurationFactory()); + GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.windows.WindowsGraphicsDevice.class, + GLCapabilitiesImmutable.class, new WindowsWGLGraphicsConfigurationFactory()); } private WindowsWGLGraphicsConfigurationFactory() { } + @Override protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl( - CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested, CapabilitiesChooser chooser, AbstractGraphicsScreen absScreen, int nativeVisualID) { + final CapabilitiesImmutable capsChosen, final CapabilitiesImmutable capsRequested, final CapabilitiesChooser chooser, + final AbstractGraphicsScreen absScreen, final int nativeVisualID) + { if (! (capsChosen instanceof GLCapabilitiesImmutable) ) { throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilities objects - chosen"); @@ -88,65 +97,71 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat if (chooser != null && !(chooser instanceof GLCapabilitiesChooser)) { throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilitiesChooser objects"); } - - return chooseGraphicsConfigurationStatic((GLCapabilitiesImmutable)capsChosen, (GLCapabilitiesImmutable)capsRequested, (GLCapabilitiesChooser)chooser, absScreen); + + return chooseGraphicsConfigurationStatic( + (GLCapabilitiesImmutable)capsChosen, (GLCapabilitiesImmutable)capsRequested, (GLCapabilitiesChooser)chooser, absScreen); } - static WindowsWGLGraphicsConfiguration createDefaultGraphicsConfiguration(GLCapabilitiesImmutable caps, - AbstractGraphicsScreen absScreen) { + static WindowsWGLGraphicsConfiguration createDefaultGraphicsConfiguration(final GLCapabilitiesImmutable caps, + final AbstractGraphicsScreen absScreen) { return chooseGraphicsConfigurationStatic(caps, caps, null, absScreen); } static WindowsWGLGraphicsConfiguration chooseGraphicsConfigurationStatic(GLCapabilitiesImmutable capsChosen, - GLCapabilitiesImmutable capsReq, - GLCapabilitiesChooser chooser, + final GLCapabilitiesImmutable capsReq, + final GLCapabilitiesChooser chooser, AbstractGraphicsScreen absScreen) { if(null==absScreen) { absScreen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_WINDOWS); } final AbstractGraphicsDevice absDevice = absScreen.getDevice(); - final GLDrawableFactory factory = GLDrawableFactory.getDesktopFactory(); - capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( - capsChosen, GLContext.isFBOAvailable(absDevice, capsChosen.getGLProfile()), factory.canCreateGLPbuffer(absDevice) ); - - return new WindowsWGLGraphicsConfiguration( absScreen, capsChosen, capsReq, (GLCapabilitiesChooser)chooser ); + capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( capsChosen, GLDrawableFactory.getDesktopFactory(), absDevice); + return new WindowsWGLGraphicsConfiguration( absScreen, capsChosen, capsReq, chooser ); } - protected static List<GLCapabilitiesImmutable> getAvailableCapabilities(WindowsWGLDrawableFactory factory, AbstractGraphicsDevice device) { - final WindowsWGLDrawableFactory.SharedResource sharedResource = factory.getOrCreateSharedResource(device); + protected static List<GLCapabilitiesImmutable> getAvailableCapabilities(final WindowsWGLDrawableFactory factory, + final AbstractGraphicsDevice device) { + final WindowsWGLDrawableFactory.SharedResource sharedResource = factory.getOrCreateSharedResourceImpl(device); if(null == sharedResource) { throw new GLException("Shared resource for device n/a: "+device); } final GLDrawableImpl sharedDrawable = sharedResource.getDrawable(); - final GLContext sharedContext = sharedResource.getContext(); final GLProfile glp = GLProfile.getDefault(device); List<GLCapabilitiesImmutable> availableCaps = null; - - if ( sharedResource.needsCurrentContext4ARBPFDQueries() ) { + + final GLContext sharedContext; + if ( factory.hasRendererQuirk(device, GLRendererQuirks.NeedCurrCtx4ARBPixFmtQueries) ) { + sharedContext = sharedResource.getContext(); if(GLContext.CONTEXT_NOT_CURRENT == sharedContext.makeCurrent()) { throw new GLException("Could not make Shared Context current: "+device); } } else { + sharedContext = null; sharedDrawable.lockSurface(); } try { - long hdc = sharedDrawable.getHandle(); + final long hdc = sharedDrawable.getHandle(); if (0 == hdc) { throw new GLException("Error: HDC is null"); } if (sharedResource.hasARBPixelFormat()) { - availableCaps = WindowsWGLGraphicsConfigurationFactory.getAvailableGLCapabilitiesARB(sharedResource, sharedResource.getDevice(), glp, hdc); + availableCaps = WindowsWGLGraphicsConfigurationFactory.getAvailableGLCapabilitiesARB( + sharedResource, sharedResource.getDevice(), glp, hdc); } - if( null == availableCaps || availableCaps.isEmpty() ) { - availableCaps = getAvailableGLCapabilitiesGDI(device, glp, hdc); + final boolean hasARBCaps = null != availableCaps && !availableCaps.isEmpty() ; + final List<GLCapabilitiesImmutable> availableCapsGDI = getAvailableGLCapabilitiesGDI(device, glp, hdc, hasARBCaps); + if( !hasARBCaps ) { + availableCaps = availableCapsGDI; + } else { + availableCaps.addAll(availableCapsGDI); } } finally { - if ( sharedResource.needsCurrentContext4ARBPFDQueries() ) { - sharedContext.release(); + if ( null != sharedContext ) { + sharedContext.release(); } else { sharedDrawable.unlockSurface(); - } + } } if( null != availableCaps && availableCaps.size() > 1 ) { @@ -155,18 +170,25 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat return availableCaps; } - static List<GLCapabilitiesImmutable> getAvailableGLCapabilitiesARB(WindowsWGLDrawableFactory.SharedResource sharedResource, AbstractGraphicsDevice device, GLProfile glProfile, long hdc) { + private static List<GLCapabilitiesImmutable> getAvailableGLCapabilitiesARB( + final WindowsWGLDrawableFactory.SharedResource sharedResource, + final AbstractGraphicsDevice device, final GLProfile glProfile, final long hdc) + { final int pfdIDCount = WindowsWGLGraphicsConfiguration.wglARBPFDIDCount((WindowsWGLContext)sharedResource.getContext(), hdc); final int[] pformats = WindowsWGLGraphicsConfiguration.wglAllARBPFDIDs(pfdIDCount); - return WindowsWGLGraphicsConfiguration.wglARBPFIDs2GLCapabilities(sharedResource, device, glProfile, hdc, pformats, GLGraphicsConfigurationUtil.ALL_BITS); + return WindowsWGLGraphicsConfiguration.wglARBPFIDs2GLCapabilities(sharedResource, device, glProfile, hdc, pformats, + GLGraphicsConfigurationUtil.ALL_BITS & ~GLGraphicsConfigurationUtil.BITMAP_BIT, false); // w/o BITMAP } - static List<GLCapabilitiesImmutable> getAvailableGLCapabilitiesGDI(AbstractGraphicsDevice device, GLProfile glProfile, long hdc) { - int[] pformats = WindowsWGLGraphicsConfiguration.wglAllGDIPFIDs(hdc); - int numFormats = pformats.length; - List<GLCapabilitiesImmutable> bucket = new ArrayList<GLCapabilitiesImmutable>(numFormats); + private static List<GLCapabilitiesImmutable> getAvailableGLCapabilitiesGDI( + final AbstractGraphicsDevice device, final GLProfile glProfile, final long hdc, final boolean bitmapOnly) + { + final int[] pformats = WindowsWGLGraphicsConfiguration.wglAllGDIPFIDs(hdc); + final int numFormats = pformats.length; + final List<GLCapabilitiesImmutable> bucket = new ArrayList<GLCapabilitiesImmutable>(numFormats); for (int i = 0; i < numFormats; i++) { - final GLCapabilitiesImmutable caps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(device, glProfile, hdc, pformats[i], GLGraphicsConfigurationUtil.ALL_BITS); + final GLCapabilitiesImmutable caps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(device, glProfile, hdc, pformats[i], + bitmapOnly ? GLGraphicsConfigurationUtil.BITMAP_BIT : GLGraphicsConfigurationUtil.ALL_BITS ); if(null != caps) { bucket.add(caps); } @@ -181,8 +203,8 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat * @param ns * @param pfIDs optional pool of preselected PixelFormat IDs, maybe null for unrestricted selection */ - static void updateGraphicsConfiguration(CapabilitiesChooser chooser, - GLDrawableFactory factory, NativeSurface ns, int[] pfdIDs) { + static void updateGraphicsConfiguration(final CapabilitiesChooser chooser, + final GLDrawableFactory factory, final NativeSurface ns, final int[] pfdIDs) { if (chooser != null && !(chooser instanceof GLCapabilitiesChooser)) { throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilitiesChooser objects"); } @@ -197,11 +219,11 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat throw new GLException("Surface not ready (lockSurface)"); } try { - long hdc = ns.getSurfaceHandle(); + final long hdc = ns.getSurfaceHandle(); if (0 == hdc) { throw new GLException("Error: HDC is null"); } - WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration) ns.getGraphicsConfiguration(); + final WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration) ns.getGraphicsConfiguration(); if( !config.isExternal() ) { if( !config.isDetermined() ) { @@ -216,7 +238,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat " for device context " + toHexString(hdc) + ": error code " + GDI.GetLastError()); } - set = true; + set = true; } if (DEBUG) { System.err.println("setPixelFormat (post): hdc "+toHexString(hdc) +", "+pfdID+" -> "+config.getPixelFormatID()+", set: "+set); @@ -228,9 +250,9 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat } } - static void preselectGraphicsConfiguration(CapabilitiesChooser chooser, - GLDrawableFactory _factory, AbstractGraphicsDevice device, - WindowsWGLGraphicsConfiguration config, int[] pfdIDs) { + static void preselectGraphicsConfiguration(final CapabilitiesChooser chooser, + final GLDrawableFactory _factory, final AbstractGraphicsDevice device, + final WindowsWGLGraphicsConfiguration config, final int[] pfdIDs) { if (chooser != null && !(chooser instanceof GLCapabilitiesChooser)) { throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilitiesChooser objects"); } @@ -243,8 +265,8 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat if ( !(_factory instanceof WindowsWGLDrawableFactory) ) { throw new GLException("GLDrawableFactory is not a WindowsWGLDrawableFactory, but: "+_factory.getClass().getSimpleName()); } - WindowsWGLDrawableFactory factory = (WindowsWGLDrawableFactory) _factory; - WindowsWGLDrawable sharedDrawable = factory.getOrCreateSharedDrawable(device); + final WindowsWGLDrawableFactory factory = (WindowsWGLDrawableFactory) _factory; + final WindowsWGLDrawable sharedDrawable = factory.getOrCreateSharedDrawable(device); if(null == sharedDrawable) { throw new IllegalArgumentException("Shared Drawable is null"); } @@ -253,7 +275,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat throw new GLException("Shared Surface not ready (lockSurface): "+device+" -> "+sharedDrawable); } try { - long hdc = sharedDrawable.getHandle(); + final long hdc = sharedDrawable.getHandle(); if (0 == hdc) { throw new GLException("Error: HDC is null"); } @@ -263,8 +285,9 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat } } - private static void updateGraphicsConfiguration(WindowsWGLGraphicsConfiguration config, CapabilitiesChooser chooser, - GLDrawableFactory factory, long hdc, boolean extHDC, int[] pfdIDs) { + private static void updateGraphicsConfiguration(final WindowsWGLGraphicsConfiguration config, final CapabilitiesChooser chooser, + final GLDrawableFactory factory, final long hdc, final boolean extHDC, + final int[] pfdIDs) { if (DEBUG) { if(extHDC) { System.err.println("updateGraphicsConfiguration(using shared): hdc "+toHexString(hdc)); @@ -273,17 +296,24 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat } System.err.println("user chosen caps " + config.getChosenCapabilities()); } - AbstractGraphicsDevice device = config.getScreen().getDevice(); - WindowsWGLDrawableFactory.SharedResource sharedResource = ((WindowsWGLDrawableFactory)factory).getOrCreateSharedResource(device); - GLContext sharedContext = null; - if (null != sharedResource && sharedResource.needsCurrentContext4ARBPFDQueries()) { + final AbstractGraphicsDevice device = config.getScreen().getDevice(); + final WindowsWGLDrawableFactory.SharedResource sharedResource = ((WindowsWGLDrawableFactory)factory).getOrCreateSharedResourceImpl(device); + final GLContext sharedContext; + if ( factory.hasRendererQuirk(device, GLRendererQuirks.NeedCurrCtx4ARBPixFmtQueries) ) { sharedContext = sharedResource.getContext(); if(GLContext.CONTEXT_NOT_CURRENT == sharedContext.makeCurrent()) { throw new GLException("Could not make Shared Context current: "+device); } + } else { + sharedContext = null; } try { - if( !updateGraphicsConfigurationARB((WindowsWGLDrawableFactory)factory, config, chooser, hdc, extHDC, pfdIDs) ) { + final GLCapabilitiesImmutable capsChosen = (GLCapabilitiesImmutable) config.getChosenCapabilities(); + boolean done = false; + if( capsChosen.getHardwareAccelerated() && !capsChosen.isBitmap() ) { + done = updateGraphicsConfigurationARB((WindowsWGLDrawableFactory)factory, config, chooser, hdc, extHDC, pfdIDs); + } + if( !done ) { updateGraphicsConfigurationGDI(config, chooser, hdc, extHDC, pfdIDs); } } finally { @@ -293,10 +323,11 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat } } - private static boolean updateGraphicsConfigurationARB(WindowsWGLDrawableFactory factory, WindowsWGLGraphicsConfiguration config, CapabilitiesChooser chooser, - long hdc, boolean extHDC, int[] pformats) { + private static boolean updateGraphicsConfigurationARB(final WindowsWGLDrawableFactory factory, + final WindowsWGLGraphicsConfiguration config, final CapabilitiesChooser chooser, + final long hdc, final boolean extHDC, int[] pformats) { final AbstractGraphicsDevice device = config.getScreen().getDevice(); - final WindowsWGLDrawableFactory.SharedResource sharedResource = factory.getOrCreateSharedResource(device); + final WindowsWGLDrawableFactory.SharedResource sharedResource = factory.getOrCreateSharedResourceImpl(device); if (null == sharedResource) { if (DEBUG) { @@ -313,14 +344,17 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat final GLCapabilitiesImmutable capsChosen = (GLCapabilitiesImmutable) config.getChosenCapabilities(); final boolean isOpaque = capsChosen.isBackgroundOpaque() && GDI.DwmIsCompositionEnabled(); - final int winattrbits = GLGraphicsConfigurationUtil.getExclusiveWinAttributeBits(capsChosen); + final int winattrbits = GLGraphicsConfigurationUtil.getExclusiveWinAttributeBits(capsChosen) + & ~GLGraphicsConfigurationUtil.BITMAP_BIT; // w/o BITMAP final GLProfile glProfile = capsChosen.getGLProfile(); - + final int pfdIDCount = WindowsWGLGraphicsConfiguration.wglARBPFDIDCount((WindowsWGLContext)sharedResource.getContext(), hdc); - + if(DEBUG) { System.err.println("updateGraphicsConfigurationARB: hdc "+toHexString(hdc)+", pfdIDCount(hdc) "+pfdIDCount+", capsChosen "+capsChosen+", "+GLGraphicsConfigurationUtil.winAttributeBits2String(null, winattrbits).toString()); - System.err.println("isOpaque "+isOpaque+" (translucency requested: "+(!capsChosen.isBackgroundOpaque())+", compositioning enabled: "+GDI.DwmIsCompositionEnabled()+")"); + System.err.println("\tisOpaque "+isOpaque+" (translucency requested: "+(!capsChosen.isBackgroundOpaque())+", compositioning enabled: "+GDI.DwmIsCompositionEnabled()+")"); + final int pformatsNum = null != pformats ? pformats.length : -1; + System.err.println("\textHDC "+extHDC+", chooser "+(null!=chooser)+", pformatsNum "+pformatsNum); } if(0 >= pfdIDCount) { @@ -329,7 +363,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat } return false; } - + WGLGLCapabilities pixelFormatCaps = null; // chosen or preset PFD ID's caps boolean pixelFormatSet = false; // indicates a preset PFD ID [caps] final int presetPFDID = extHDC ? -1 : WGLUtil.GetPixelFormat(hdc) ; @@ -343,17 +377,17 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat + ", pixelformat " + presetPFDID); } pixelFormatSet = true; - pixelFormatCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedResource, device, glProfile, hdc, presetPFDID, winattrbits); + pixelFormatCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedResource, device, glProfile, + hdc, presetPFDID, winattrbits); pixelFormatCaps = (WGLGLCapabilities) GLGraphicsConfigurationUtil.fixOpaqueGLCapabilities(pixelFormatCaps, isOpaque); } 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]; + final IntBuffer iattributes = Buffers.newDirectIntBuffer(2*WindowsWGLGraphicsConfiguration.MAX_ATTRIBS); + final FloatBuffer fattributes = Buffers.newDirectFloatBuffer(1); int accelerationMode = WGLExt.WGL_FULL_ACCELERATION_ARB; pformats = WindowsWGLGraphicsConfiguration.wglChoosePixelFormatARB(sharedResource, device, capsChosen, hdc, iattributes, accelerationMode, fattributes); @@ -388,10 +422,12 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat return false; } } + final boolean skipCapsChooser = 0 <= recommendedIndex && null == chooser && capsChosen.isBackgroundOpaque(); // fast path: skip choosing if using recommended idx and null chooser is used and if not translucent + + final List<GLCapabilitiesImmutable> availableCaps = + WindowsWGLGraphicsConfiguration.wglARBPFIDs2GLCapabilities(sharedResource, device, glProfile, + hdc, pformats, winattrbits, skipCapsChooser /* onlyFirstValid */); - List<GLCapabilitiesImmutable> availableCaps = - WindowsWGLGraphicsConfiguration.wglARBPFIDs2GLCapabilities(sharedResource, device, glProfile, hdc, pformats, winattrbits); - if( null == availableCaps || 0 == availableCaps.size() ) { if (DEBUG) { System.err.println("updateGraphicsConfigurationARB: wglARBPFIDs2GLCapabilities failed with " + pformats.length + " pfd ids"); @@ -402,14 +438,19 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat if (DEBUG) { System.err.println("updateGraphicsConfigurationARB: " + pformats.length + - " pfd ids, " + GLGraphicsConfigurationUtil.winAttributeBits2String(null, winattrbits).toString() + ", " + availableCaps.size() + " glcaps"); + " pfd ids, skipCapsChooser " + skipCapsChooser + ", " + GLGraphicsConfigurationUtil.winAttributeBits2String(null, winattrbits).toString() + ", " + availableCaps.size() + " glcaps"); if(0 <= recommendedIndex) { System.err.println("updateGraphicsConfigurationARB: Used wglChoosePixelFormatARB to recommend pixel format " + pformats[recommendedIndex] + ", idx " + recommendedIndex +", "+availableCaps.get(recommendedIndex)); } } - int chosenIndex = chooseCapabilities(chooser, capsChosen, availableCaps, recommendedIndex); + final int chosenIndex; + if( skipCapsChooser ) { + chosenIndex = recommendedIndex; + } else { + chosenIndex = chooseCapabilities(chooser, capsChosen, availableCaps, recommendedIndex); + } if ( 0 > chosenIndex ) { if (DEBUG) { Thread.dumpStack(); @@ -420,12 +461,12 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat if( null == pixelFormatCaps) { throw new GLException("Null Capabilities with "+ " chosen pfdID: native recommended "+ (recommendedIndex+1) + - " chosen idx "+chosenIndex); + " chosen idx "+chosenIndex+", skipCapsChooser "+skipCapsChooser); } pixelFormatCaps = (WGLGLCapabilities) GLGraphicsConfigurationUtil.fixOpaqueGLCapabilities(pixelFormatCaps, isOpaque); if (DEBUG) { System.err.println("chosen pfdID (ARB): native recommended "+ (recommendedIndex+1) + - " chosen "+pixelFormatCaps); + " chosen "+pixelFormatCaps+", skipCapsChooser "+skipCapsChooser); } } @@ -437,9 +478,9 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat return true; } - private static boolean updateGraphicsConfigurationGDI(WindowsWGLGraphicsConfiguration config, CapabilitiesChooser chooser, long hdc, - boolean extHDC, int[] pformats) { - GLCapabilitiesImmutable capsChosen = (GLCapabilitiesImmutable) config.getChosenCapabilities(); + private static boolean updateGraphicsConfigurationGDI(final WindowsWGLGraphicsConfiguration config, final CapabilitiesChooser chooser, + final long hdc, final boolean extHDC, int[] pformats) { + final GLCapabilitiesImmutable capsChosen = (GLCapabilitiesImmutable) config.getChosenCapabilities(); if( !capsChosen.isOnscreen() && capsChosen.isPBuffer() ) { if (DEBUG) { System.err.println("updateGraphicsConfigurationGDI: no pbuffer supported on GDI: " + capsChosen); @@ -450,29 +491,30 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat // final boolean useFBO = capsChosen.isFBO(); final GLProfile glProfile = capsChosen.getGLProfile(); final int winattrmask = GLGraphicsConfigurationUtil.getExclusiveWinAttributeBits(capsChosen); - + if(DEBUG) { - System.err.println("updateGraphicsConfigurationGDI: capsChosen "+capsChosen+", "+GLGraphicsConfigurationUtil.winAttributeBits2String(null, winattrmask).toString()); + System.err.println("updateGraphicsConfigurationGDI: hdc "+toHexString(hdc)+", capsChosen "+capsChosen+", "+GLGraphicsConfigurationUtil.winAttributeBits2String(null, winattrmask).toString()); + final int pformatsNum = null != pformats ? pformats.length : -1; + System.err.println("\textHDC "+extHDC+", chooser "+(null!=chooser)+", pformatsNum "+pformatsNum); } - - AbstractGraphicsDevice device = config.getScreen().getDevice(); - int pfdID; // chosen or preset PFD ID + + final AbstractGraphicsDevice device = config.getScreen().getDevice(); WGLGLCapabilities pixelFormatCaps = null; // chosen or preset PFD ID's caps boolean pixelFormatSet = false; // indicates a preset PFD ID [caps] - - if ( !extHDC && 1 <= ( pfdID = WGLUtil.GetPixelFormat(hdc) ) ) { + final int presetPFDID = extHDC ? -1 : WGLUtil.GetPixelFormat(hdc) ; + if ( 1 <= presetPFDID ) { // 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("updateGraphicsConfigurationGDI: NOTE: pixel format already chosen for HDC: " + toHexString(hdc) - + ", pixelformat " + pfdID); + + ", pixelformat " + presetPFDID); } pixelFormatSet = true; - pixelFormatCaps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(device, glProfile, hdc, pfdID, winattrmask); + pixelFormatCaps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(device, glProfile, hdc, presetPFDID, winattrmask); if(null == pixelFormatCaps) { - throw new GLException("Could not map PFD2GLCaps w/ already chosen pfdID "+pfdID); + throw new GLException("Could not map PFD2GLCaps w/ already chosen pfdID "+presetPFDID); } } else { final boolean givenPFormats = null != pformats; @@ -480,43 +522,84 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat pformats = WindowsWGLGraphicsConfiguration.wglAllGDIPFIDs(hdc); } - List<GLCapabilitiesImmutable> availableCaps = new ArrayList<GLCapabilitiesImmutable>(); - for (int i = 0; i < pformats.length; i++) { - final GLCapabilitiesImmutable caps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(device, glProfile, hdc, pformats[i], winattrmask); - if(null != caps) { - availableCaps.add(caps); - if(DEBUG) { - final int j = availableCaps.size() - 1; - System.err.println("updateGraphicsConfigurationGDI: availableCaps["+i+" -> "+j+"]: "+caps); - } - } else if(DEBUG) { - GLCapabilitiesImmutable skipped = WindowsWGLGraphicsConfiguration.PFD2GLCapabilitiesNoCheck(device, glProfile, hdc, pformats[i]); - System.err.println("updateGraphicsConfigurationGDI: availableCaps["+i+" -> skip]: pfdID "+pformats[i]+", "+skipped); - } - } - // 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice + final List<GLCapabilitiesImmutable> availableCaps = new ArrayList<GLCapabilitiesImmutable>(); PIXELFORMATDESCRIPTOR pfd = WindowsWGLGraphicsConfiguration.createPixelFormatDescriptor(); pfd = WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(capsChosen, pfd); - pfdID = WGLUtil.ChoosePixelFormat(hdc, pfd); + int chosenPFDID = WGLUtil.ChoosePixelFormat(hdc, pfd); int recommendedIndex = -1 ; - if( 1 <= pfdID ) { + final boolean skipCapsChooser; + if( 1 <= chosenPFDID ) { + // _skipCapsChooser: fast path: skip choosing if using recommended idx and null chooser is used and if not translucent + final boolean _skipCapsChooser = null == chooser && capsChosen.isBackgroundOpaque(); // seek index .. in all formats _or_ in given formats! - for (recommendedIndex = availableCaps.size() - 1 ; - 0 <= recommendedIndex && pfdID != ((WGLGLCapabilities) availableCaps.get(recommendedIndex)).getPFDID(); - recommendedIndex--) - { /* nop */ } - if(DEBUG && 0 > recommendedIndex) { - final GLCapabilitiesImmutable reqPFDCaps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilitiesNoCheck(device, glProfile, pfd, pfdID); - final GLCapabilitiesImmutable chosenCaps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(device, glProfile, hdc, pfdID, winattrmask); - System.err.println("Chosen PFDID "+pfdID+", but not found in available caps (use given pfdIDs "+givenPFormats+", reqPFDCaps "+reqPFDCaps+", chosenCaps: "+chosenCaps); + int chosenIdx; + for (chosenIdx = pformats.length - 1 ; 0 <= chosenIdx && chosenPFDID != pformats[chosenIdx]; chosenIdx--) { /* nop */ } + if( 0 <= chosenIdx ) { + if( _skipCapsChooser ) { + final WGLGLCapabilities caps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(device, glProfile, hdc, + chosenPFDID, winattrmask); + if(null != caps) { + availableCaps.add(caps); + recommendedIndex = 0; + skipCapsChooser = true; + } else { + skipCapsChooser = false; + } + } else { + skipCapsChooser = false; + } + if( DEBUG ) { + System.err.println("Chosen PFDID "+chosenPFDID+" (idx "+chosenIdx+") -> recommendedIndex "+recommendedIndex+", skipCapsChooser "+skipCapsChooser); + } + } else { + if(DEBUG) { + final GLCapabilitiesImmutable reqPFDCaps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilitiesNoCheck(device, glProfile, pfd, chosenPFDID); + final GLCapabilitiesImmutable chosenCaps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(device, glProfile, hdc, chosenPFDID, winattrmask); + System.err.println("Chosen PFDID "+chosenPFDID+" (idx "+chosenIdx+"), but not found in available caps (use given pfdIDs "+givenPFormats+", reqPFDCaps "+reqPFDCaps+", chosenCaps: "+chosenCaps); + } + chosenPFDID = 0; // not found in pformats -> clear + skipCapsChooser = false; } + } else { + skipCapsChooser = false; } if (DEBUG) { - System.err.println("updateGraphicsConfigurationGDI: ChoosePixelFormat(HDC " + toHexString(hdc) + ") = pfdID " + pfdID + ", idx " + recommendedIndex + " (LastError: " + GDI.GetLastError() + ")"); + System.err.println("updateGraphicsConfigurationGDI: ChoosePixelFormat(HDC " + toHexString(hdc) + ") = pfdID " + chosenPFDID + ", skipCapsChooser "+skipCapsChooser+", idx " + recommendedIndex + " (LastError: " + GDI.GetLastError() + ")"); + } + + if( !skipCapsChooser ) { + for (int i = 0; i < pformats.length; i++) { + final int pfdid = pformats[i]; + final WGLGLCapabilities caps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(device, glProfile, + hdc, pfdid, winattrmask); + if(null != caps) { + availableCaps.add(caps); + if(DEBUG) { + final int j = availableCaps.size() - 1; + System.err.println("updateGraphicsConfigurationGDI: availableCaps["+i+" -> "+j+"]: "+caps); + } + } else if(DEBUG) { + final GLCapabilitiesImmutable skipped = WindowsWGLGraphicsConfiguration.PFD2GLCapabilitiesNoCheck(device, glProfile, hdc, pformats[i]); + System.err.println("updateGraphicsConfigurationGDI: availableCaps["+i+" -> skip]: pfdID "+pformats[i]+", "+skipped); + } + } + // seek recommendedIndex in all _or_ given formats! + if( 1 <= chosenPFDID && 0 > recommendedIndex) { + for (recommendedIndex = availableCaps.size() - 1 ; + 0 <= recommendedIndex && chosenPFDID != ((WGLGLCapabilities) availableCaps.get(recommendedIndex)).getPFDID(); + recommendedIndex--) + { /* nop */ } + } } + // 2nd choice: if no preferred recommendedIndex available - int chosenIndex = chooseCapabilities(chooser, capsChosen, availableCaps, recommendedIndex); + final int chosenIndex; + if( skipCapsChooser ) { + chosenIndex = recommendedIndex; + } else { + chosenIndex = chooseCapabilities(chooser, capsChosen, availableCaps, recommendedIndex); + } if ( 0 > chosenIndex ) { if (DEBUG) { System.err.println("updateGraphicsConfigurationGDI: failed, return false"); @@ -526,7 +609,8 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat } pixelFormatCaps = (WGLGLCapabilities) availableCaps.get(chosenIndex); if (DEBUG) { - System.err.println("chosen pfdID (GDI): chosenIndex "+ chosenIndex + ", caps " + pixelFormatCaps); + System.err.println("chosen pfdID (GDI): recommendedIndex "+recommendedIndex+" -> chosenIndex "+ chosenIndex + ", skipCapsChooser "+skipCapsChooser+", caps " + pixelFormatCaps + + " (" + WGLGLCapabilities.PFD2String(pixelFormatCaps.getPFD(), pixelFormatCaps.getPFDID()) +")"); } } @@ -538,4 +622,3 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat return true; } } - diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java index 3b2ff133a..9e784ad73 100644 --- a/src/jogl/classes/jogamp/opengl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java +++ b/src/jogl/classes/jogamp/opengl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java @@ -1,22 +1,22 @@ /* * 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 * 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 @@ -65,12 +65,13 @@ public class WindowsAWTWGLGraphicsConfigurationFactory extends GLGraphicsConfigu public static void registerFactory() { GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.awt.AWTGraphicsDevice.class, GLCapabilitiesImmutable.class, new WindowsAWTWGLGraphicsConfigurationFactory()); } - private WindowsAWTWGLGraphicsConfigurationFactory() { + private WindowsAWTWGLGraphicsConfigurationFactory() { } + @Override protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl( - CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested, - CapabilitiesChooser chooser, AbstractGraphicsScreen absScreen, int nativeVisualID) { + final CapabilitiesImmutable capsChosen, final CapabilitiesImmutable capsRequested, + final CapabilitiesChooser chooser, AbstractGraphicsScreen absScreen, final int nativeVisualID) { GraphicsDevice device = null; if (absScreen != null && !(absScreen instanceof AWTGraphicsScreen)) { @@ -83,7 +84,7 @@ public class WindowsAWTWGLGraphicsConfigurationFactory extends GLGraphicsConfigu System.err.println("WindowsAWTWGLGraphicsConfigurationFactory: creating default device: "+absScreen); } } - AWTGraphicsScreen awtScreen = (AWTGraphicsScreen) absScreen; + final AWTGraphicsScreen awtScreen = (AWTGraphicsScreen) absScreen; device = ((AWTGraphicsDevice)awtScreen.getDevice()).getGraphicsDevice(); if ( !(capsChosen instanceof GLCapabilitiesImmutable) ) { @@ -103,10 +104,10 @@ public class WindowsAWTWGLGraphicsConfigurationFactory extends GLGraphicsConfigu System.err.println("WindowsAWTWGLGraphicsConfigurationFactory: got "+absScreen); } - WindowsGraphicsDevice winDevice = new WindowsGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT); - DefaultGraphicsScreen winScreen = new DefaultGraphicsScreen(winDevice, awtScreen.getIndex()); - GraphicsConfigurationFactory configFactory = GraphicsConfigurationFactory.getFactory(winDevice, capsChosen); - WindowsWGLGraphicsConfiguration winConfig = (WindowsWGLGraphicsConfiguration) + final WindowsGraphicsDevice winDevice = new WindowsGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT); + final DefaultGraphicsScreen winScreen = new DefaultGraphicsScreen(winDevice, awtScreen.getIndex()); + final GraphicsConfigurationFactory configFactory = GraphicsConfigurationFactory.getFactory(winDevice, capsChosen); + final WindowsWGLGraphicsConfiguration winConfig = (WindowsWGLGraphicsConfiguration) configFactory.chooseGraphicsConfiguration(capsChosen, capsRequested, chooser, winScreen, nativeVisualID); @@ -114,7 +115,7 @@ public class WindowsAWTWGLGraphicsConfigurationFactory extends GLGraphicsConfigu throw new GLException("Unable to choose a GraphicsConfiguration: "+capsChosen+",\n\t"+chooser+"\n\t"+winScreen); } - GLDrawableFactory drawableFactory = GLDrawableFactory.getFactory(((GLCapabilitiesImmutable)capsChosen).getGLProfile()); + final GLDrawableFactory drawableFactory = GLDrawableFactory.getFactory(((GLCapabilitiesImmutable)capsChosen).getGLProfile()); GraphicsConfiguration chosenGC = null; if ( drawableFactory instanceof WindowsWGLDrawableFactory ) { @@ -132,13 +133,13 @@ public class WindowsAWTWGLGraphicsConfigurationFactory extends GLGraphicsConfigu System.err.println("WindowsAWTWGLGraphicsConfigurationFactory: Found new AWT PFD ID "+winConfig.getPixelFormatID()+" -> "+winConfig); } } - } catch (GLException gle0) { + } catch (final GLException gle0) { if(DEBUG) { gle0.printStackTrace(); } // go on .. } - + if( null == chosenGC ) { // 2nd Choice: Choose and match the GL Visual with AWT: // - collect all AWT PFDs @@ -147,15 +148,15 @@ public class WindowsAWTWGLGraphicsConfigurationFactory extends GLGraphicsConfigu // 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<Integer> pfdIDOSet = new ArrayHashSet<Integer>(); + final GraphicsConfiguration[] configs = device.getConfigurations(); + final int[] pfdIDs = new int[configs.length]; + final ArrayHashSet<Integer> pfdIDOSet = new ArrayHashSet<Integer>(); for (int i = 0; i < configs.length; i++) { - GraphicsConfiguration gc = configs[i]; + final GraphicsConfiguration gc = configs[i]; pfdIDs[i] = Win32SunJDKReflection.graphicsConfigurationGetPixelFormatID(gc); - pfdIDOSet.add(new Integer(pfdIDs[i])); + pfdIDOSet.add( Integer.valueOf(pfdIDs[i]) ); if(DEBUG) { System.err.println("AWT pfd["+i+"] "+pfdIDs[i]); } @@ -164,18 +165,18 @@ public class WindowsAWTWGLGraphicsConfigurationFactory extends GLGraphicsConfigu System.err.println("WindowsAWTWGLGraphicsConfigurationFactory: PFD IDs: "+pfdIDs.length+", unique: "+pfdIDOSet.size()); } winConfig.preselectGraphicsConfiguration(drawableFactory, pfdIDs); - int gcIdx = pfdIDOSet.indexOf(new Integer(winConfig.getPixelFormatID())); + final int gcIdx = pfdIDOSet.indexOf(Integer.valueOf(winConfig.getPixelFormatID())); if( 0 > gcIdx ) { chosenGC = configs[gcIdx]; if(DEBUG) { System.err.println("WindowsAWTWGLGraphicsConfigurationFactory: Found matching AWT PFD ID "+winConfig.getPixelFormatID()+" -> "+winConfig); } } - } + } } else { chosenGC = device.getDefaultConfiguration(); } - + if ( null == chosenGC ) { throw new GLException("Unable to determine GraphicsConfiguration: "+winConfig); } |