diff options
author | Sven Gothel <[email protected]> | 2014-02-23 14:51:06 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2014-02-23 14:51:06 +0100 |
commit | 3352601e0860584509adf2b76f993d03893ded4b (patch) | |
tree | 974fccc8c0eb2f5ad9d4ffd741dfc35869ed67b5 /src/jogl/classes/jogamp/opengl/windows | |
parent | f51933f0ebe9ae030c26c066e59a728ce08b8559 (diff) | |
parent | c67de337a8aaf52e36104c3f13e273aa19d21f1f (diff) |
Merge branch 'master' into stash_glyphcache
Conflicts:
make/scripts/tests.sh
src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java
src/jogl/classes/com/jogamp/graph/curve/Region.java
src/jogl/classes/com/jogamp/graph/curve/opengl/GLRegion.java
src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java
src/jogl/classes/com/jogamp/graph/curve/opengl/Renderer.java
src/jogl/classes/com/jogamp/graph/curve/opengl/TextRenderer.java
src/jogl/classes/com/jogamp/graph/font/Font.java
src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java
src/jogl/classes/jogamp/graph/curve/text/GlyphShape.java
src/jogl/classes/jogamp/graph/curve/text/GlyphString.java
src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java
src/jogl/classes/jogamp/graph/font/typecast/TypecastGlyph.java
src/jogl/classes/jogamp/graph/font/typecast/TypecastRenderer.java
Diffstat (limited to 'src/jogl/classes/jogamp/opengl/windows')
18 files changed, 1189 insertions, 1436 deletions
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WGLGLCapabilities.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WGLGLCapabilities.java index 5ff63d93b..feacdb951 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; @@ -52,6 +54,7 @@ public class WGLGLCapabilities extends GLCapabilities { public boolean setValuesByGDI() { arb_pixelformat = -1; + // ALPHA shall be set at last - due to it's auto setting by !opaque / samples setRedBits(pfd.getCRedBits()); setGreenBits(pfd.getCGreenBits()); setBlueBits(pfd.getCBlueBits()); @@ -62,10 +65,11 @@ public class WGLGLCapabilities extends GLCapabilities { 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 @@ -74,11 +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(PIXELFORMATDESCRIPTOR pfd, int pfdID) { + final int dwFlags = pfd.getDwFlags(); + 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: @@ -86,101 +128,99 @@ 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: - setAlphaBits(iresults[i]); + // ALPHA shall be set at last - due to it's auto setting by !opaque / samples + 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); return true; } + @Override public Object cloneMutable() { return clone(); } + @Override public Object clone() { try { return super.clone(); @@ -191,11 +231,11 @@ public class WGLGLCapabilities extends GLCapabilities { final public PIXELFORMATDESCRIPTOR getPFD() { return pfd; } final public int getPFDID() { return pfdID; } - + final public boolean isSetByARB() { return 0 < arb_pixelformat; } final public boolean isSetByGDI() { return 0 > arb_pixelformat; } final public boolean isSet() { return 0 != arb_pixelformat; } - + @Override final public int getVisualID(VIDType type) throws NativeWindowException { switch(type) { @@ -205,16 +245,17 @@ public class WGLGLCapabilities extends GLCapabilities { return getPFDID(); default: throw new NativeWindowException("Invalid type <"+type+">"); - } + } } - + + @Override public StringBuilder toString(StringBuilder sink) { 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: + case -1: sink.append("gdi"); break; case 0: @@ -229,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..6454a34b5 100644 --- a/src/jogl/classes/jogamp/opengl/windows/wgl/WGLUtil.java +++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WGLUtil.java @@ -33,15 +33,15 @@ 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,8 +49,9 @@ public class WGLUtil { * @see jogamp.nativewindow.windows.GDI#SwapBuffers(long) */ public static final boolean USE_WGLVersion_Of_5WGLGDIFuncSet; - + static { + Debug.initSingleton(); USE_WGLVersion_Of_5WGLGDIFuncSet = Debug.isPropertyDefined("jogl.windows.useWGLVersionOf5WGLGDIFuncSet", true); if(USE_WGLVersion_Of_5WGLGDIFuncSet) { System.err.println("Use WGL version of 5 WGL/GDI functions."); @@ -62,34 +63,34 @@ public class WGLUtil { return WGL.wglChoosePixelFormat(hdc, pfd); } else { return GDI.ChoosePixelFormat(hdc, pfd); - } + } } public static int DescribePixelFormat(long hdc, int pfdid, int pfdSize, 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) { 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(long hdc, int pfdid, 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(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 68b26b30d..000000000 --- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLContext.java +++ /dev/null @@ -1,64 +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); - } - - public int getOffscreenContextPixelDataType() { - return GL.GL_UNSIGNED_BYTE; - } - - public int getOffscreenContextReadBuffer() { - // On Windows these contexts are always single-buffered - return GL.GL_FRONT; - } - - 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 574226570..f658a3598 100644 --- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLDrawable.java +++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLDrawable.java @@ -1,22 +1,22 @@ /* * 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 @@ -29,41 +29,62 @@ * 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 com.jogamp.common.nio.PointerBuffer; +import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.NativeSurface; -import javax.media.nativewindow.SurfaceChangeable; +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 javax.media.opengl.GLCapabilitiesImmutable; +import jogamp.opengl.GLGraphicsConfigurationUtil; + +import com.jogamp.common.nio.PointerBuffer; public class WindowsBitmapWGLDrawable extends WindowsWGLDrawable { private long origbitmap; private long hbitmap; - protected WindowsBitmapWGLDrawable(GLDrawableFactory factory, NativeSurface target) { - super(factory, target, false); + private WindowsBitmapWGLDrawable(GLDrawableFactory factory, NativeSurface comp) { + super(factory, comp, false); } - protected void destroyImpl() { - setRealized(false); + protected static WindowsBitmapWGLDrawable create(GLDrawableFactory factory, 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 protected void setRealizedImpl() { if(realized) { createBitmap(); @@ -72,35 +93,44 @@ public class WindowsBitmapWGLDrawable extends WindowsWGLDrawable { } } + @Override public GLContext createContext(GLContext shareWith) { - return new WindowsBitmapWGLContext(this, 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 = getWidth(); + final int height = getHeight(); // // 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); @@ -109,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; 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) { @@ -140,9 +170,9 @@ public class WindowsBitmapWGLDrawable extends WindowsWGLDrawable { hbitmap = 0; throw new GLException("Error creating device context for offscreen OpenGL context, werr "+werr); } - ((SurfaceChangeable)ns).setSurfaceHandle(hdc); + ((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) { @@ -152,10 +182,10 @@ public class WindowsBitmapWGLDrawable extends WindowsWGLDrawable { hdc = 0; throw new GLException("Error selecting bitmap into new device context"); } - + config.updateGraphicsConfiguration(getFactory(), ns, null); } - + protected void destroyBitmap() { NativeSurface ns = getNativeSurface(); if (ns.getSurfaceHandle() != 0) { @@ -165,7 +195,7 @@ public class WindowsBitmapWGLDrawable extends WindowsWGLDrawable { GDI.DeleteDC(ns.getSurfaceHandle()); origbitmap = 0; hbitmap = 0; - ((SurfaceChangeable)ns).setSurfaceHandle(0); + ((MutableSurface)ns).setSurfaceHandle(0); } } } diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsDummyWGLDrawable.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsDummyWGLDrawable.java deleted file mode 100644 index 3ba5508ab..000000000 --- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsDummyWGLDrawable.java +++ /dev/null @@ -1,105 +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.GLContext; -import javax.media.opengl.GLDrawableFactory; -import javax.media.opengl.GLProfile; - -import javax.media.nativewindow.AbstractGraphicsScreen; -import jogamp.nativewindow.windows.GDI; -import jogamp.nativewindow.windows.GDIUtil; - -import javax.media.nativewindow.NativeSurface; -import javax.media.opengl.GLCapabilities; -import javax.media.opengl.GLException; -import jogamp.nativewindow.windows.GDISurface; - -public class WindowsDummyWGLDrawable extends WindowsWGLDrawable { - private long hwnd; - private boolean handleHwndLifecycle; - - private WindowsDummyWGLDrawable(GLDrawableFactory factory, GDISurface ns, boolean handleHwndLifecycle) { - super(factory, ns, true); - this.handleHwndLifecycle = handleHwndLifecycle; - - if(NativeSurface.LOCK_SURFACE_NOT_READY >= ns.lockSurface()) { - throw new GLException("WindowsDummyWGLDrawable: surface not ready (lockSurface)"); - } - try { - WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration)ns.getGraphicsConfiguration(); - config.updateGraphicsConfiguration(factory, ns, null); - if (DEBUG) { - System.err.println("WindowsDummyWGLDrawable: "+config); - } - } catch (Throwable t) { - destroyImpl(); - throw new GLException(t); - } finally { - unlockSurface(); - } - } - - public static WindowsDummyWGLDrawable create(GLDrawableFactory factory, GLProfile glp, AbstractGraphicsScreen absScreen, - long windowHandle, int width, int height, boolean handleWindowLifecycle) { - if(0 == windowHandle) { - throw new GLException("Error windowHandle 0, werr: "+GDI.GetLastError()); - } - GLCapabilities caps = new GLCapabilities(glp); - WindowsWGLGraphicsConfiguration cfg = WindowsWGLGraphicsConfigurationFactory.createDefaultGraphicsConfiguration(caps, absScreen); - GDISurface ns = new GDISurface(cfg, windowHandle); - ns.surfaceSizeChanged(width, height); - return new WindowsDummyWGLDrawable(factory, ns, handleWindowLifecycle); - } - - public GLContext createContext(GLContext shareWith) { - // FIXME: figure out how to hook back in the Java 2D / JOGL bridge - return new WindowsWGLContext(this, shareWith); - } - - protected void destroyImpl() { - if (handleHwndLifecycle && hwnd != 0) { - GDI.ShowWindow(hwnd, GDI.SW_HIDE); - GDIUtil.DestroyDummyWindow(hwnd); - hwnd = 0; - } - } -} diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java index 745782085..c46b3c9dd 100644 --- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java +++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java @@ -1,22 +1,22 @@ /* * 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 @@ -29,11 +29,11 @@ * 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. */ @@ -50,14 +50,11 @@ import javax.media.opengl.GLDrawableFactory; import javax.media.opengl.GLException; import javax.media.opengl.GLProfile; -import com.jogamp.nativewindow.WrappedSurface; - +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) { super(drawable, null); @@ -66,7 +63,9 @@ public class WindowsExternalWGLContext extends WindowsWGLContext { 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 } @@ -103,32 +102,18 @@ public class WindowsExternalWGLContext extends WindowsWGLContext { System.err.println("WindowsExternalWGLContext valid hdc/pfd, retrieved cfg: " + cfg); } } - return new WindowsExternalWGLContext(new Drawable(factory, new WrappedSurface(cfg, hdc)), ctx, cfg); - } - - 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(); - } - - public void release() throws GLException { - super.release(); - setCurrent(lastContext); - lastContext = null; + return new WindowsExternalWGLContext(new Drawable(factory, new WrappedSurface(cfg, hdc, 64, 64, true)), ctx, cfg); } + @Override protected void makeCurrentImpl() throws GLException { } + @Override protected void releaseImpl() throws GLException { } + @Override protected void destroyImpl() throws GLException { } @@ -138,14 +123,17 @@ public class WindowsExternalWGLContext extends WindowsWGLContext { super(factory, comp, true); } + @Override public GLContext createContext(GLContext shareWith) { throw new GLException("Should not call this"); } + @Override public int getWidth() { throw new GLException("Should not call this"); } + @Override public int getHeight() { 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 ad2e91bed..f8c237c9e 100644 --- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLDrawable.java +++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLDrawable.java @@ -1,22 +1,22 @@ /* * 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 @@ -29,11 +29,11 @@ * 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. */ @@ -49,9 +49,10 @@ import javax.media.opengl.GLDrawableFactory; import javax.media.opengl.GLException; import javax.media.opengl.GLProfile; -import com.jogamp.nativewindow.WrappedSurface; - +import jogamp.nativewindow.WrappedSurface; import jogamp.nativewindow.windows.GDI; +import jogamp.nativewindow.windows.GDIUtil; + public class WindowsExternalWGLDrawable extends WindowsWGLDrawable { @@ -69,25 +70,28 @@ public class WindowsExternalWGLDrawable extends WindowsWGLDrawable { throw new GLException("Error: attempted to make an external GLContext without a valid pixelformat, werr " + GDI.GetLastError()); } - AbstractGraphicsScreen aScreen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_WINDOWS); - WindowsWGLGraphicsConfiguration cfg = WindowsWGLGraphicsConfiguration.createFromExternal(factory, hdc, pfdID, glp, aScreen, true); - return new WindowsExternalWGLDrawable(factory, new WrappedSurface(cfg, hdc)); + final AbstractGraphicsScreen aScreen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_WINDOWS); + final WindowsWGLGraphicsConfiguration cfg = WindowsWGLGraphicsConfiguration.createFromExternal(factory, hdc, pfdID, glp, aScreen, true); + return new WindowsExternalWGLDrawable(factory, new WrappedSurface(cfg, hdc, 64, 64, true)); } + @Override public GLContext createContext(GLContext shareWith) { return new WindowsWGLContext(this, shareWith); } - + public void setSize(int newWidth, int newHeight) { throw new GLException("Should not call this"); } + @Override public int getWidth() { throw new GLException("Should not call this"); - } + } + @Override public int getHeight() { 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 a06ab8f0e..000000000 --- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsOnscreenWGLContext.java +++ /dev/null @@ -1,53 +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 java.util.*; - -import javax.media.nativewindow.*; -import javax.media.opengl.*; -import jogamp.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 6ad330ccc..61fb787c6 100644 --- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsOnscreenWGLDrawable.java +++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsOnscreenWGLDrawable.java @@ -1,22 +1,22 @@ /* * 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 @@ -29,27 +29,29 @@ * 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.nativewindow.*; -import javax.media.opengl.*; +import javax.media.nativewindow.NativeSurface; +import javax.media.opengl.GLContext; +import javax.media.opengl.GLDrawableFactory; public class WindowsOnscreenWGLDrawable extends WindowsWGLDrawable { protected WindowsOnscreenWGLDrawable(GLDrawableFactory factory, NativeSurface component) { super(factory, component, false); } + @Override public GLContext createContext(GLContext shareWith) { - return new WindowsOnscreenWGLContext(this, 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 0f610495d..000000000 --- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLContext.java +++ /dev/null @@ -1,150 +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 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); - } - - 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(). - } - - 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()); - } - } - } - - 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("GL_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 = GL2.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; - } - - 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 0988f3eca..2e60c682b 100644 --- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java +++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java @@ -1,22 +1,22 @@ /* * 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 @@ -29,48 +29,47 @@ * 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 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.SurfaceChangeable; -import javax.media.opengl.GL; +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.GLPbuffer; 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.GLCapabilitiesImmutable; - 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) { super(factory, target, false); } - protected void destroyImpl() { - setRealized(false); - } - + @Override protected void setRealizedImpl() { if(realized) { createPbuffer(); @@ -79,8 +78,9 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable { } } + @Override public GLContext createContext(GLContext shareWith) { - return new WindowsPbufferWGLContext(this, shareWith); + return new WindowsWGLContext(this, shareWith); } protected void destroyPbuffer() { @@ -95,7 +95,7 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable { if (wglExt.wglReleasePbufferDCARB(buffer, ns.getSurfaceHandle()) == 0) { throw new GLException("Error releasing pbuffer device context: error code " + GDI.GetLastError()); } - ((SurfaceChangeable)ns).setSurfaceHandle(0); + ((MutableSurface)ns).setSurfaceHandle(0); } if (!wglExt.wglDestroyPbufferARB(buffer)) { throw new GLException("Error destroying pbuffer: error code " + GDI.GetLastError()); @@ -111,139 +111,106 @@ 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()); + SharedResource sharedResource = ((WindowsWGLDrawableFactory)factory).getOrCreateSharedResourceImpl(config.getScreen().getDevice()); 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 = sharedResource.getContext().getWGLExt(); - + WGLExt wglExt = ((WindowsWGLContext)sharedResource.getContext()).getWGLExt(); + if (DEBUG) { - System.out.println("Pbuffer config: " + config); + System.out.println(getThreadName()+": Pbuffer config: " + config); } - - int[] iattributes = new int [2*WindowsWGLGraphicsConfiguration.MAX_ATTRIBS]; - float[] fattributes = new float[1]; + + final int winattrPbuffer = GLGraphicsConfigurationUtil.getExclusiveWinAttributeBits(false /* onscreen */, false /* fbo */, true /* pbuffer */, false /* bitmap */); + + final IntBuffer iattributes = Buffers.newDirectIntBuffer(2*WindowsWGLGraphicsConfiguration.MAX_ATTRIBS); + final FloatBuffer fattributes = Buffers.newDirectFloatBuffer(1); int[] floatModeTmp = new int[1]; int niattribs = 0; - int width, height; - - GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable)config.getChosenCapabilities(); - GLProfile glProfile = chosenCaps.getGLProfile(); - + + final GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable)config.getChosenCapabilities(); + final GLProfile glProfile = chosenCaps.getGLProfile(); + final AbstractGraphicsDevice device = config.getScreen().getDevice(); + if (DEBUG) { - System.out.println("Pbuffer parentHdc = " + toHexString(sharedHdc)); - System.out.println("Pbuffer chosenCaps: " + chosenCaps); + System.out.println(getThreadName()+": Pbuffer parentHdc = " + toHexString(sharedHdc)); + System.out.println(getThreadName()+": Pbuffer chosenCaps: " + chosenCaps); } - + if(!WindowsWGLGraphicsConfiguration.GLCapabilities2AttribList(chosenCaps, iattributes, sharedResource, -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"); } - + if (DEBUG) { System.err.println("" + nformats + " suitable pixel formats found"); for (int i = 0; i < nformats; i++) { - WGLGLCapabilities dbgCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedResource, sharedHdc, pformats[i], glProfile, false, true); - System.err.println("pixel format " + pformats[i] + " (index " + i + "): " + dbgCaps); + WGLGLCapabilities dbgCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedResource, device, glProfile, + sharedHdc, pformats.get(i), winattrPbuffer); + System.err.println("pixel format " + pformats.get(i) + " (index " + i + "): " + dbgCaps); } } - + int pfdid = 0; long tmpBuffer = 0; { int whichFormat; // Loop is a workaround for bugs in NVidia's recent drivers for (whichFormat = 0; whichFormat < nformats; whichFormat++) { - int format = pformats[whichFormat]; - + 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; - iattributes[niattribs++] = GL.GL_FALSE; - } - - iattributes[niattribs++] = 0; - - tmpBuffer = wglExt.wglCreatePbufferARB(sharedHdc, format, getWidth(), getHeight(), iattributes, 0); + + iattributes.put(niattribs++, 0); + + tmpBuffer = wglExt.wglCreatePbufferARB(sharedHdc, format, getWidth(), getHeight(), iattributes); if (tmpBuffer != 0) { // Done break; } } - + if (0 == tmpBuffer) { 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); if (tmpHdc == 0) { throw new GLException("pbuffer creation error: wglGetPbufferDC() failed"); } - + NativeSurface ns = getNativeSurface(); // Set up instance variables buffer = tmpBuffer; - ((SurfaceChangeable)ns).setSurfaceHandle(tmpHdc); - cachedWGLExt = wglExt; - + ((MutableSurface)ns).setSurfaceHandle(tmpHdc); + cachedWGLExt = wglExt; + // Re-query chosen pixel format { - WGLGLCapabilities newCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedResource, sharedHdc, pfdid, glProfile, false, true); + 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)); } @@ -252,14 +219,6 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable { } config.setCapsPFD(newCaps); } - - // Determine the actual width and height we were able to create. - int[] tmp = new int[1]; - wglExt.wglQueryPbufferARB( buffer, WGLExt.WGL_PBUFFER_WIDTH_ARB, tmp, 0 ); - width = tmp[0]; - wglExt.wglQueryPbufferARB( buffer, WGLExt.WGL_PBUFFER_HEIGHT_ARB, tmp, 0 ); - height = tmp[0]; - ((SurfaceChangeable)ns).surfaceSizeChanged(width, height); } finally { sharedSurface.unlockSurface(); } diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java index 217d88f3c..b214252c1 100644 --- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java +++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java @@ -1,22 +1,22 @@ /* * 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 @@ -29,11 +29,11 @@ * 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. */ @@ -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; @@ -51,8 +52,12 @@ import javax.media.opengl.GLContext; import javax.media.opengl.GLException; import javax.media.opengl.GLCapabilitiesImmutable; +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; import jogamp.opengl.GLDrawableImpl; @@ -77,8 +82,8 @@ public class WindowsWGLContext extends GLContextImpl { functionNameMap.put("glFreeMemoryNV", "wglFreeMemoryNV"); extensionNameMap = new HashMap<String, String>(); - extensionNameMap.put("GL_ARB_pbuffer", "WGL_ARB_pbuffer"); - extensionNameMap.put("GL_ARB_pixel_format", "WGL_ARB_pixel_format"); + extensionNameMap.put(GLExtensions.ARB_pbuffer, WindowsWGLDrawableFactory.WGL_ARB_pbuffer); + extensionNameMap.put(GLExtensions.ARB_pixel_format, WindowsWGLDrawableFactory.WGL_ARB_pixel_format); } // FIXME: figure out how to hook back in the Java 2D / JOGL bridge @@ -88,7 +93,7 @@ public class WindowsWGLContext extends GLContextImpl { } @Override - protected void resetStates() { + protected void resetStates(boolean isInit) { wglGetExtensionsStringEXTInitialized=false; wglGetExtensionsStringEXTAvailable=false; wglGLReadDrawableAvailableSet=false; @@ -96,10 +101,11 @@ public class WindowsWGLContext extends GLContextImpl { // no inner state _wglExt=null; wglExtProcAddressTable=null; hasSwapIntervalSGI = 0; - hasSwapGroupNV = 0; - super.resetStates(); + hasSwapGroupNV = 0; + super.resetStates(isInit); } - + + @Override public Object getPlatformGLExtensions() { return getWGLExt(); } @@ -114,6 +120,7 @@ public class WindowsWGLContext extends GLContextImpl { return _wglExt; } + @Override public final boolean isGLReadDrawableAvailable() { if(!wglGLReadDrawableAvailableSet && null != getWGLExtProcAddressTable()) { WindowsWGLDrawableFactory factory = (WindowsWGLDrawableFactory)drawable.getFactoryImpl(); @@ -159,6 +166,7 @@ public class WindowsWGLContext extends GLContextImpl { return ok; } + @Override public final ProcAddressTable getPlatformExtProcAddressTable() { return getWGLExtProcAddressTable(); } @@ -167,15 +175,19 @@ public class WindowsWGLContext extends GLContextImpl { return wglExtProcAddressTable; } + @Override protected Map<String, String> getFunctionNameMap() { return functionNameMap; } + @Override protected Map<String, String> getExtensionNameMap() { return extensionNameMap; } + @Override protected void destroyContextARBImpl(long context) { WGL.wglMakeCurrent(0, 0); WGL.wglDeleteContext(context); } + @Override protected long createContextARBImpl(long share, boolean direct, int ctp, int major, int minor) { if( null == getWGLExtProcAddressTable()) { updateGLXProcAddressTable(); @@ -207,14 +219,13 @@ 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; } else { attribs[idx_profile+1] = WGLExt.WGL_CONTEXT_CORE_PROFILE_BIT_ARB; - } - } + } + } if ( major >= 3 ) { if( !ctBwdCompat && ctFwdCompat ) { @@ -226,7 +237,8 @@ public class WindowsWGLContext extends GLContextImpl { } try { - ctx = _wglExt.wglCreateContextAttribsARB(drawable.getHandle(), share, attribs, 0); + final IntBuffer attribsNIO = Buffers.newDirectIntBuffer(attribs); + ctx = _wglExt.wglCreateContextAttribsARB(drawable.getHandle(), share, attribsNIO); } catch (RuntimeException re) { if(DEBUG) { Throwable t = new Throwable("Info: WindowWGLContext.createContextARBImpl wglCreateContextAttribsARB failed with "+getGLVersion(major, minor, ctp, "@creation"), re); @@ -255,74 +267,92 @@ public class WindowsWGLContext extends GLContextImpl { * Creates and initializes an appropriate OpenGL context. Should only be * called by {@link #makeCurrentImpl()}. */ - 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(); + @Override + 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 */, false /* 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"); + 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 ) { // 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); } } + } 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)) { @@ -330,10 +360,10 @@ public class WindowsWGLContext extends GLContextImpl { } } } else { - if(glCaps.getGLProfile().isGL3()) { + if( glCaps.getGLProfile().isGL3() ) { WGL.wglMakeCurrent(0, 0); WGL.wglDeleteContext(temp_ctx); - throw new GLException("WindowsWGLContext.createContext ctx !ARB, context > GL2 requested "+getGLVersion()); + throw new GLException(getThreadName()+": WindowsWGLContex.createContextImpl ctx !ARB, 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()); @@ -341,41 +371,49 @@ public class WindowsWGLContext extends GLContextImpl { // continue with temp context for GL < 3.0 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) { - // Only utilize the classic GDI 'wglShareLists' shared context method + 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)); } } return true; } - + + @Override 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); } } } + @Override protected void releaseImpl() throws GLException { if (!wglMakeContextCurrent(0, 0, 0)) { throw new GLException("Error freeing OpenGL context, werr: " + GDI.GetLastError()); } } + @Override protected void destroyImpl() throws GLException { WGL.wglMakeCurrent(0, 0); if (!WGL.wglDeleteContext(contextHandle)) { @@ -383,12 +421,14 @@ public class WindowsWGLContext extends GLContextImpl { } } + @Override protected void copyImpl(GLContext source, int mask) throws GLException { if (!WGL.wglCopyContext(source.getHandle(), getHandle(), mask)) { throw new GLException("wglCopyContext failed"); } } + @Override protected final void updateGLXProcAddressTable() { final AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration(); final AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice(); @@ -421,10 +461,11 @@ public class WindowsWGLContext extends GLContextImpl { } } } - + + @Override protected final StringBuilder getPlatformExtensionsStringImpl() { StringBuilder sb = new StringBuilder(); - + if (!wglGetExtensionsStringEXTInitialized) { wglGetExtensionsStringEXTAvailable = (WGL.wglGetProcAddress("wglGetExtensionsStringEXT") != 0); wglGetExtensionsStringEXTInitialized = true; @@ -434,7 +475,7 @@ public class WindowsWGLContext extends GLContextImpl { } return sb; } - + @Override protected boolean setSwapIntervalImpl(int interval) { WGLExt wglExt = getWGLExt(); @@ -450,7 +491,7 @@ public class WindowsWGLContext extends GLContextImpl { } return false; } - + private final int initSwapGroupImpl(WGLExt wglExt) { if(0==hasSwapGroupNV) { try { @@ -462,7 +503,7 @@ public class WindowsWGLContext extends GLContextImpl { } return hasSwapGroupNV; } - + @Override protected final boolean queryMaxSwapGroupsImpl(int[] maxGroups, int maxGroups_offset, int[] maxBarriers, int maxBarriers_offset) { @@ -471,16 +512,19 @@ public class WindowsWGLContext extends GLContextImpl { 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; } } return res; } - + @Override protected final boolean joinSwapGroupImpl(int group) { boolean res = false; @@ -495,7 +539,7 @@ public class WindowsWGLContext extends GLContextImpl { } return res; } - + @Override protected final boolean bindSwapBarrierImpl(int group, int barrier) { boolean res = false; @@ -507,31 +551,17 @@ public class WindowsWGLContext extends GLContextImpl { } } catch (Throwable t) { hasSwapGroupNV=-1; } } - return res; - } - - public ByteBuffer glAllocateMemoryNV(int arg0, float arg1, float arg2, float arg3) { - return getWGLExt().wglAllocateMemoryNV(arg0, arg1, arg2, arg3); - } - - public int getOffscreenContextPixelDataType() { - throw new GLException("Should not call this"); - } - - public int getOffscreenContextReadBuffer() { - throw new GLException("Should not call this"); - } - - public boolean offscreenImageNeedsVerticalFlip() { - throw new GLException("Should not call this"); + return res; } - public void bindPbufferToTexture() { - throw new GLException("Should not call this"); + @Override + public final ByteBuffer glAllocateMemoryNV(int size, float readFrequency, float writeFrequency, float priority) { + return getWGLExt().wglAllocateMemoryNV(size, readFrequency, writeFrequency, priority); } - public void releasePbufferFromTexture() { - throw new GLException("Should not call this"); + @Override + public final void glFreeMemoryNV(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 579b11940..66071cbe1 100644 --- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawable.java +++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawable.java @@ -1,22 +1,22 @@ /* * 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 @@ -29,11 +29,11 @@ * 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. */ @@ -51,7 +51,13 @@ 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 = Debug.isPropertyDefined("jogl.debug.GLDrawable.profiling", true); + } + private static final int PROFILING_TICKS = 200; private int profilingSwapBuffersTicks; private long profilingSwapBuffersTime; @@ -60,43 +66,45 @@ public abstract class WindowsWGLDrawable extends GLDrawableImpl { super(factory, comp, realized); } + @Override protected void setRealizedImpl() { - if(!realized) { - return; // nothing todo .. - } - - NativeSurface ns = getNativeSurface(); - WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration)ns.getGraphicsConfiguration(); - config.updateGraphicsConfiguration(getFactory(), ns, null); - if (DEBUG) { - System.err.println("WindowsWGLDrawable.setRealized(true): "+config); + if(realized) { + NativeSurface ns = getNativeSurface(); + WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration)ns.getGraphicsConfiguration(); + config.updateGraphicsConfiguration(getFactory(), ns, null); + if (DEBUG) { + System.err.println(getThreadName()+": WindowsWGLDrawable.setRealized(true): "+config); + } } } - protected final void swapBuffersImpl() { - // single-buffer is already filtered out @ GLDrawableImpl#swapBuffers() - final long t0; - if (PROFILING) { - t0 = System.currentTimeMillis(); - } else { - t0 = 0; - } + @Override + protected final void swapBuffersImpl(boolean doubleBuffered) { + if(doubleBuffered) { + final long t0; + if (PROFILING) { + t0 = System.currentTimeMillis(); + } else { + t0 = 0; + } - if (!WGLUtil.SwapBuffers(getHandle()) && (GDI.GetLastError() != GDI.ERROR_SUCCESS)) { - throw new GLException("Error swapping buffers"); - } + 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) { - System.err.println("SwapBuffers calls: " + profilingSwapBuffersTime + " ms / " + PROFILING_TICKS + " calls (" + - ((float) profilingSwapBuffersTime / (float) PROFILING_TICKS) + " ms/call)"); - profilingSwapBuffersTime = 0; - profilingSwapBuffersTicks = 0; - } + if (PROFILING) { + profilingSwapBuffersTime += System.currentTimeMillis() - t0; + if (++profilingSwapBuffersTicks == PROFILING_TICKS) { + System.err.println("SwapBuffers calls: " + profilingSwapBuffersTime + " ms / " + PROFILING_TICKS + " calls (" + + ((float) profilingSwapBuffersTime / (float) PROFILING_TICKS) + " ms/call)"); + profilingSwapBuffersTime = 0; + profilingSwapBuffersTicks = 0; + } + } } } + @Override public GLDynamicLookupHelper getGLDynamicLookupHelper() { return getFactoryImpl().getGLDynamicLookupHelper(0); } diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java index 494bb307e..7fa8775cf 100644 --- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java +++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java @@ -1,22 +1,22 @@ /* * 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 @@ -29,11 +29,11 @@ * 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. */ @@ -42,82 +42,90 @@ 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; +import javax.media.nativewindow.AbstractGraphicsConfiguration; import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.AbstractGraphicsScreen; import javax.media.nativewindow.DefaultGraphicsScreen; import javax.media.nativewindow.NativeSurface; -import javax.media.nativewindow.NativeWindowFactory; -import javax.media.nativewindow.AbstractGraphicsConfiguration; import javax.media.nativewindow.ProxySurface; -import javax.media.opengl.GL; -import javax.media.opengl.GLCapabilitiesImmutable; +import javax.media.nativewindow.UpstreamSurfaceHook; +import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLCapabilitiesChooser; +import javax.media.opengl.GLCapabilitiesImmutable; import javax.media.opengl.GLContext; import javax.media.opengl.GLDrawable; import javax.media.opengl.GLException; import javax.media.opengl.GLProfile; -import javax.media.opengl.GLProfile.ShutdownType; - -import com.jogamp.common.JogampRuntimeException; -import com.jogamp.common.nio.PointerBuffer; -import com.jogamp.common.os.Platform; -import com.jogamp.common.util.ReflectionUtil; -import com.jogamp.common.util.VersionNumber; -import com.jogamp.nativewindow.WrappedSurface; -import com.jogamp.nativewindow.windows.WindowsGraphicsDevice; +import jogamp.nativewindow.WrappedSurface; import jogamp.nativewindow.windows.GDI; -import jogamp.nativewindow.windows.GDIUtil; +import jogamp.nativewindow.windows.GDIDummyUpstreamSurfaceHook; import jogamp.nativewindow.windows.GDISurface; import jogamp.nativewindow.windows.RegisteredClassFactory; import jogamp.opengl.DesktopGLDynamicLookupHelper; +import jogamp.opengl.GLContextImpl; import jogamp.opengl.GLDrawableFactoryImpl; import jogamp.opengl.GLDrawableImpl; import jogamp.opengl.GLDynamicLookupHelper; +import jogamp.opengl.GLGraphicsConfigurationUtil; import jogamp.opengl.SharedResourceRunner; +import com.jogamp.common.nio.PointerBuffer; +import com.jogamp.common.util.ReflectionUtil; +import com.jogamp.nativewindow.windows.WindowsGraphicsDevice; +import com.jogamp.opengl.GLExtensions; +import com.jogamp.opengl.GLRendererQuirks; + public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { private static DesktopGLDynamicLookupHelper windowsWGLDynamicLookupHelper = null; - + public WindowsWGLDrawableFactory() { super(); 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 (Exception ex) { + tmp = null; + if(DEBUG) { + ex.printStackTrace(); + } + } + return tmp; } - } - if(null!=tmp && tmp.isLibComplete()) { - windowsWGLDynamicLookupHelper = tmp; - WGL.getWGLProcAddressTable().reset(windowsWGLDynamicLookupHelper); - } + } ); } } - + defaultDevice = new WindowsGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT); - + if(null!=windowsWGLDynamicLookupHelper) { // Register our GraphicsConfigurationFactory implementations // The act of constructing them causes them to be registered WindowsWGLGraphicsConfigurationFactory.registerFactory(); if(GLProfile.isAWTAvailable()) { try { - ReflectionUtil.callStaticMethod("jogamp.opengl.windows.wgl.awt.WindowsAWTWGLGraphicsConfigurationFactory", - "registerFactory", null, null, getClass().getClassLoader()); - } catch (JogampRuntimeException jre) { /* n/a .. */ } + ReflectionUtil.callStaticMethod("jogamp.opengl.windows.wgl.awt.WindowsAWTWGLGraphicsConfigurationFactory", + "registerFactory", null, null, getClass().getClassLoader()); + } catch (Exception jre) { /* n/a .. */ } } - + sharedMap = new HashMap<String, SharedResourceRunner.Resource>(); - + // Init shared resources off thread // Will be released via ShutdownHook sharedResourceRunner = new SharedResourceRunner(new SharedResourceImplementation()); @@ -125,7 +133,17 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { } } - protected final void destroy(ShutdownType shutdownType) { + @Override + protected final boolean isComplete() { + return null != windowsWGLDynamicLookupHelper; + } + + + @Override + protected final void shutdownImpl() { + if( DEBUG ) { + System.err.println("WindowsWGLDrawableFactory.shutdown"); + } if(null != sharedResourceRunner) { sharedResourceRunner.stop(); sharedResourceRunner = null; @@ -137,15 +155,15 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { defaultDevice = null; /** * Pulling away the native library may cause havoc .. - * - if(ShutdownType.COMPLETE == shutdownType && null != windowsWGLDynamicLookupHelper) { - windowsWGLDynamicLookupHelper.destroy(); - windowsWGLDynamicLookupHelper = null; - } */ - + * + windowsWGLDynamicLookupHelper.destroy(); + */ + windowsWGLDynamicLookupHelper = null; + RegisteredClassFactory.shutdownSharedClasses(); } + @Override public GLDynamicLookupHelper getGLDynamicLookupHelper(int profile) { return windowsWGLDynamicLookupHelper; } @@ -155,16 +173,17 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { private HashMap<String /*connection*/, SharedResourceRunner.Resource> sharedMap; private long processAffinityChanges = 0; - private PointerBuffer procMask = PointerBuffer.allocateDirect(1); - private PointerBuffer sysMask = PointerBuffer.allocateDirect(1); + private final PointerBuffer procMask = PointerBuffer.allocateDirect(1); + private final 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()); + System.err.println("WindowsWGLDrawableFactory.enterThreadCriticalZone() - 0x" + Long.toHexString(pid) + " - " + getThreadName()); // Thread.dumpStack(); } processAffinityChanges = pid; @@ -174,6 +193,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { } } + @Override protected void leaveThreadCriticalZone() { synchronized (sysMask) { if( 0 != processAffinityChanges) { @@ -183,35 +203,25 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { " this PID 0x" + Long.toHexString(pid) ); } if(DEBUG) { - System.err.println("WindowsWGLDrawableFactory.leaveThreadCriticalZone() - 0x" + Long.toHexString(pid) + " - " + Thread.currentThread().getName()); + System.err.println("WindowsWGLDrawableFactory.leaveThreadCriticalZone() - 0x" + Long.toHexString(pid) + " - " + getThreadName()); } GDI.SetProcessAffinityMask(pid, sysMask.get(0)); } } } - /** - * 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 WindowsDummyWGLDrawable drawable; - private WindowsWGLContext 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, WindowsDummyWGLDrawable draw, WindowsWGLContext ctx, - boolean arbPixelFormat, boolean arbMultisample, boolean arbPBuffer, boolean arbReadDrawable, String glVendor) { + private GLDrawableImpl drawable; + private GLContextImpl context; + + SharedResource(WindowsGraphicsDevice dev, AbstractGraphicsScreen scrn, GLDrawableImpl draw, GLContextImpl ctx, + boolean arbPixelFormat, boolean arbMultisample, boolean arbPBuffer, boolean arbReadDrawable) { device = dev; screen = scrn; drawable = draw; @@ -220,90 +230,71 @@ 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; } - final public WindowsWGLDrawable getDrawable() { return drawable; } - final public WindowsWGLContext getContext() { return context; } + @Override + 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); - } + return sharedMap.put(connection, resource); } + @Override public SharedResourceRunner.Resource mapGet(String connection) { - synchronized(sharedMap) { - return sharedMap.get(connection); - } + return sharedMap.get(connection); } + @Override public Collection<SharedResourceRunner.Resource> mapValues() { synchronized(sharedMap) { return sharedMap.values(); } } + @Override + public boolean isDeviceSupported(String connection) { + return true; + } + + @Override public SharedResourceRunner.Resource createSharedResource(String connection) { - WindowsGraphicsDevice sharedDevice = new WindowsGraphicsDevice(connection, AbstractGraphicsDevice.DEFAULT_UNIT); + final WindowsGraphicsDevice sharedDevice = new WindowsGraphicsDevice(connection, AbstractGraphicsDevice.DEFAULT_UNIT); sharedDevice.lock(); try { - AbstractGraphicsScreen absScreen = new DefaultGraphicsScreen(sharedDevice, 0); - GLProfile glp = GLProfile.get(sharedDevice, GLProfile.GL_PROFILE_LIST_MIN_DESKTOP, false); + final AbstractGraphicsScreen absScreen = new DefaultGraphicsScreen(sharedDevice, 0); + final GLProfile glp = GLProfile.get(sharedDevice, GLProfile.GL_PROFILE_LIST_MIN_DESKTOP, false); if (null == glp) { throw new GLException("Couldn't get default GLProfile for device: "+sharedDevice); } - final int f_dim = 64; - long hwnd = GDIUtil.CreateDummyWindow(0, 0, f_dim, f_dim); - WindowsDummyWGLDrawable sharedDrawable = WindowsDummyWGLDrawable.create(WindowsWGLDrawableFactory.this, glp, absScreen, hwnd, f_dim, f_dim, true); - if (null == sharedDrawable) { - throw new GLException("Couldn't create shared drawable for screen: "+absScreen+", "+glp); - } - WindowsWGLContext sharedContext = (WindowsWGLContext) sharedDrawable.createContext(null); + 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); } @@ -311,15 +302,13 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { boolean hasARBMultisample; boolean hasARBPBuffer; boolean hasARBReadDrawableAvailable; - String vendor; sharedContext.makeCurrent(); try { hasARBPixelFormat = sharedContext.isExtensionAvailable(WGL_ARB_pixel_format); hasARBMultisample = sharedContext.isExtensionAvailable(WGL_ARB_multisample); - hasARBPBuffer = sharedContext.isExtensionAvailable(GL_ARB_pbuffer); + 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(); } @@ -331,11 +320,10 @@ 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, + return new SharedResource(sharedDevice, absScreen, sharedDrawable, sharedContext, hasARBPixelFormat, hasARBMultisample, - hasARBPBuffer, hasARBReadDrawableAvailable, vendor); + hasARBPBuffer, hasARBReadDrawableAvailable); } catch (Throwable t) { throw new GLException("WindowsWGLDrawableFactory - Could not initialize shared resources for "+connection, t); } finally { @@ -343,6 +331,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { } } + @Override public void releaseSharedResource(SharedResourceRunner.Resource shared) { SharedResource sr = (SharedResource) shared; if (DEBUG) { @@ -359,7 +348,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { } if (null != sr.drawable) { - sr.drawable.destroy(); + sr.drawable.setRealized(false); sr.drawable = null; } @@ -374,10 +363,12 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { } } + @Override public final AbstractGraphicsDevice getDefaultDevice() { return defaultDevice; } + @Override public final boolean getIsDeviceCompatible(AbstractGraphicsDevice device) { if(null!=windowsWGLDynamicLookupHelper && device instanceof WindowsGraphicsDevice) { return true; @@ -385,64 +376,37 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { return false; } - final static String GL_ARB_pbuffer = "GL_ARB_pbuffer"; + final static String WGL_ARB_pbuffer = "WGL_ARB_pbuffer"; final static String WGL_ARB_pixel_format = "WGL_ARB_pixel_format"; final static String WGL_ARB_multisample = "WGL_ARB_multisample"; final static String WGL_NV_float_buffer = "WGL_NV_float_buffer"; final static String WGL_ARB_make_current_read = "WGL_ARB_make_current_read"; final static String wglMakeContextCurrent = "wglMakeContextCurrent"; + @Override protected final Thread getSharedResourceThread() { return sharedResourceRunner.start(); } - - 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; - } - - protected final GLContext getOrCreateSharedContextImpl(AbstractGraphicsDevice device) { - SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device); - if(null!=sr) { - return sr.getContext(); - } - return null; - } - protected AbstractGraphicsDevice getOrCreateSharedDeviceImpl(AbstractGraphicsDevice device) { - SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device); - if(null!=sr) { - return sr.getDevice(); - } - return null; + @Override + protected final SharedResource getOrCreateSharedResourceImpl(AbstractGraphicsDevice device) { + return (SharedResource) sharedResourceRunner.getOrCreateShared(device); } - protected WindowsWGLDrawable getOrCreateSharedDrawable(AbstractGraphicsDevice device) { - SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device); + protected final WindowsWGLDrawable getOrCreateSharedDrawable(AbstractGraphicsDevice device) { + 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) { return WindowsWGLGraphicsConfigurationFactory.getAvailableCapabilities(this, device); } + @Override protected final GLDrawableImpl createOnscreenDrawableImpl(NativeSurface target) { if (target == null) { throw new IllegalArgumentException("Null target"); @@ -450,6 +414,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { return new WindowsOnscreenWGLDrawable(this, target); } + @Override protected final GLDrawableImpl createOffscreenDrawableImpl(final NativeSurface target) { if (target == null) { throw new IllegalArgumentException("Null target"); @@ -457,7 +422,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { AbstractGraphicsConfiguration config = target.getGraphicsConfiguration(); GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities(); if(!chosenCaps.isPBuffer()) { - return new WindowsBitmapWGLDrawable(this, target); + return WindowsBitmapWGLDrawable.create(this, target); } // PBuffer GLDrawable Creation @@ -468,7 +433,7 @@ 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(); if (lastContext != null) { @@ -494,46 +459,77 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { * 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); + SharedResource sr = getOrCreateSharedResourceImpl( ( null != device ) ? device : defaultDevice ); if(null!=sr) { return sr.hasReadDrawable() ? 1 : 0 ; } return -1; // undefined } - public final boolean canCreateGLPbuffer(AbstractGraphicsDevice device) { - SharedResource sr = (SharedResource) sharedResourceRunner.getOrCreateShared((null!=device)?device:defaultDevice); + @Override + public final boolean canCreateGLPbuffer(AbstractGraphicsDevice device, GLProfile glp) { + SharedResource sr = getOrCreateSharedResourceImpl( ( null != device ) ? device : defaultDevice ); if(null!=sr) { return sr.hasARBPBuffer(); } return false; } - protected final NativeSurface createOffscreenSurfaceImpl(AbstractGraphicsDevice device, GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, int width, int height) { - AbstractGraphicsScreen screen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_WINDOWS); - WrappedSurface ns = new WrappedSurface(WindowsWGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic( - capsChosen, capsRequested, chooser, screen) ); - ns.surfaceSizeChanged(width, height); - return ns; + @Override + protected final ProxySurface createMutableSurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice, + GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, + GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstreamHook) { + final WindowsGraphicsDevice device; + if(createNewDevice || !(deviceReq instanceof WindowsGraphicsDevice)) { + device = new WindowsGraphicsDevice(deviceReq.getConnection(), deviceReq.getUnitID()); + } else { + device = (WindowsGraphicsDevice)deviceReq; + } + 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); + } + return new WrappedSurface(config, 0, upstreamHook, createNewDevice); + } + + @Override + public final ProxySurface createDummySurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice, + GLCapabilitiesImmutable chosenCaps, GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height) { + final WindowsGraphicsDevice device; + if( createNewDevice || !(deviceReq instanceof WindowsGraphicsDevice) ) { + device = new WindowsGraphicsDevice(deviceReq.getConnection(), deviceReq.getUnitID()); + } else { + device = (WindowsGraphicsDevice)deviceReq; + } + final AbstractGraphicsScreen screen = new DefaultGraphicsScreen(device, 0); + chosenCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(chosenCaps); + final WindowsWGLGraphicsConfiguration config = WindowsWGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(chosenCaps, requestedCaps, chooser, screen); + if(null == config) { + throw new GLException("Choosing GraphicsConfiguration failed w/ "+chosenCaps+" on "+screen); + } + return new GDISurface(config, 0, new GDIDummyUpstreamSurfaceHook(width, height), createNewDevice); } - - protected final ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice adevice, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser) { - // FIXME device/windowHandle -> screen ?! - WindowsGraphicsDevice device = (WindowsGraphicsDevice) adevice; - AbstractGraphicsScreen screen = new DefaultGraphicsScreen(device, 0); - WindowsWGLGraphicsConfiguration cfg = WindowsWGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsRequested, capsRequested, chooser, screen); - GDISurface ns = new GDISurface(cfg, windowHandle); - return ns; + + @Override + protected final ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice deviceReq, int screenIdx, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, 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); + return new GDISurface(cfg, windowHandle, upstream, true); } - + + @Override protected final GLContext createExternalGLContextImpl() { return WindowsExternalWGLContext.create(this, null); } + @Override public final boolean canCreateExternalGLDrawable(AbstractGraphicsDevice device) { return true; } + @Override protected final GLDrawable createExternalGLDrawableImpl() { return WindowsExternalWGLDrawable.create(this, null); } @@ -553,25 +549,18 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { return detail; } - public final boolean canCreateContextOnJava2DSurface(AbstractGraphicsDevice device) { - return false; - } - - public final GLContext createContextOnJava2DSurface(Object graphics, GLContext shareWith) - throws GLException { - throw new GLException("Unimplemented on this platform"); - } - //------------------------------------------------------ // Gamma-related functionality // private static final int GAMMA_RAMP_LENGTH = 256; + @Override protected final int getGammaRampLength() { return GAMMA_RAMP_LENGTH; } + @Override protected final boolean setGammaRamp(float[] ramp) { short[] rampData = new short[3 * GAMMA_RAMP_LENGTH]; for (int i = 0; i < GAMMA_RAMP_LENGTH; i++) { @@ -587,6 +576,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { return res; } + @Override protected final Buffer getGammaRamp() { ShortBuffer rampData = ShortBuffer.wrap(new short[3 * GAMMA_RAMP_LENGTH]); long screenDC = GDI.GetDC(0); @@ -598,6 +588,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { return rampData; } + @Override protected final void resetGammaRamp(Buffer originalGammaRamp) { if (originalGammaRamp == null) { // getGammaRamp failed earlier diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDynamicLibraryBundleInfo.java index a553bd4c2..6098cde7f 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,31 +20,31 @@ * 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>(); diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java index 5682b35e8..5dd9f88b2 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,26 +46,27 @@ 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 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.GLGraphicsConfigurationUtil; -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, + WindowsWGLGraphicsConfiguration(AbstractGraphicsScreen screen, GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser) { super(screen, capsChosen, capsRequested); @@ -96,15 +99,15 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio } WindowsWGLDrawableFactory factory = (WindowsWGLDrawableFactory) _factory; AbstractGraphicsDevice device = screen.getDevice(); - WindowsWGLDrawableFactory.SharedResource sharedResource = factory.getOrCreateSharedResource(device); + WindowsWGLDrawableFactory.SharedResource sharedResource = factory.getOrCreateSharedResourceImpl(device); boolean hasARB = null != sharedResource && sharedResource.hasARBPixelFormat(); WGLGLCapabilities caps = null; if(hasARB) { - caps = wglARBPFID2GLCapabilities(sharedResource, hdc, pfdID, glp, onscreen, true /* pbuffer */); + caps = wglARBPFID2GLCapabilities(sharedResource, device, glp, hdc, pfdID, GLGraphicsConfigurationUtil.ALL_BITS); } else { - caps = PFD2GLCapabilities(glp, hdc, pfdID, onscreen); + caps = PFD2GLCapabilities(device, glp, hdc, pfdID, GLGraphicsConfigurationUtil.ALL_BITS); } if(null==caps) { throw new GLException("Couldn't choose Capabilities by: HDC 0x"+Long.toHexString(hdc)+ @@ -116,6 +119,7 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio return cfg; } + @Override public Object clone() { return super.clone(); } @@ -158,19 +162,19 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio 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 + + 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); + bb.setDwFlags(GDI.DWM_BB_ENABLE| GDI.DWM_BB_TRANSITIONONMAXIMIZED); + bb.setFEnable( 1 ); boolean ok = GDI.DwmEnableBlurBehindWindow(hwnd, bb); - if(ok) { + if( ok ) { MARGINS m = MARGINS.create(); m.setCxLeftWidth(-1); m.setCxRightWidth(-1); @@ -179,15 +183,17 @@ 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) { - System.err.println("setPixelFormat (ARB): hdc "+toHexString(hdc) +", "+caps); + System.err.println("setPixelFormat: hdc "+toHexString(hdc) +", "+caps); } setCapsPFD(caps); } - + /** * Only sets this configuration's capabilities and marks it as determined, * the actual pixelformat is not set. @@ -204,130 +210,120 @@ 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(WindowsWGLDrawableFactory.SharedResource sharedResource, 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; - } - - if(sharedResource.hasARBPBuffer()) { - WindowsWGLContext sharedCtx = sharedResource.getContext(); - if(null != sharedCtx && sharedCtx.isExtensionAvailable(WindowsWGLDrawableFactory.WGL_NV_float_buffer)) { - // pbo float buffer - iattributes[niattribs++] = WGLExt.WGL_FLOAT_COMPONENTS_NV; // nvidia - } + iattributes.put(niattribs++, WGLExt.WGL_SAMPLE_BUFFERS_ARB); + iattributes.put(niattribs++, WGLExt.WGL_SAMPLES_ARB); } - 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)) { + 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[] wglAllARBPFIDs(WindowsWGLContext sharedCtx, long hdc) { - int[] iattributes = new int[1]; - int[] iresults = new int[1]; + static int wglARBPFDIDCount(WindowsWGLContext sharedCtx, 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; - if (!wglExt.wglGetPixelFormatAttribivARB(hdc, 0, 0, 1, iattributes, 0, iresults, 0)) { + // 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, iresults)) { if(DEBUG) { System.err.println("GetPixelFormatAttribivARB: Failed - HDC 0x" + Long.toHexString(hdc) + + ", value "+iresults.get(0)+ ", LastError: " + GDI.GetLastError()); Thread.dumpStack(); } - return null; + return 0; } - int numFormats = iresults[0]; - if(0 == numFormats) { + final int pfdIDCount = iresults.get(0); + if(0 == pfdIDCount) { if(DEBUG) { System.err.println("GetPixelFormatAttribivARB: No formats - HDC 0x" + Long.toHexString(hdc) + ", LastError: " + GDI.GetLastError()); Thread.dumpStack(); } - return null; } - int[] pfdIDs = new int[numFormats]; - for (int i = 0; i < numFormats; i++) { + return pfdIDCount; + } + + static int[] wglAllARBPFDIDs(int pfdIDCount) { + int[] pfdIDs = new int[pfdIDCount]; + for (int i = 0; i < pfdIDCount; i++) { pfdIDs[i] = 1 + i; } return pfdIDs; } static WGLGLCapabilities wglARBPFID2GLCapabilities(WindowsWGLDrawableFactory.SharedResource sharedResource, - long hdc, int pfdID, - GLProfile glp, boolean onscreen, boolean usePBuffer) { + AbstractGraphicsDevice device, GLProfile glp, + long hdc, int pfdID, 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 (!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()); } - ArrayList<WGLGLCapabilities> bucket = new ArrayList<WGLGLCapabilities>(1); - final int winattrbits = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer); - if(AttribList2GLCapabilities(bucket, glp, hdc, pfdID, iattributes, niattribs, iresults, winattrbits)) { - return bucket.get(0); - } - return null; + return AttribList2GLCapabilities(device, glp, hdc, pfdID, iattributes, niattribs, iresults, winattrbits); } - static int[] wglChoosePixelFormatARB(long hdc, WindowsWGLDrawableFactory.SharedResource sharedResource, + static int[] wglChoosePixelFormatARB(WindowsWGLDrawableFactory.SharedResource sharedResource, AbstractGraphicsDevice device, GLCapabilitiesImmutable capabilities, - int[] iattributes, int accelerationMode, float[] fattributes) + long hdc, IntBuffer iattributes, int accelerationMode, FloatBuffer fattributes) { if ( !WindowsWGLGraphicsConfiguration.GLCapabilities2AttribList(capabilities, @@ -340,77 +336,83 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio return null; } - int[] pformatsTmp = new int[WindowsWGLGraphicsConfiguration.MAX_PFORMATS]; - int[] numFormatsTmp = new int[1]; - if ( !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, hdc, pformats[i], - capabilities.getGLProfile(), capabilities.isOnscreen(), capabilities.isPBuffer()); + 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, - long hdc, int[] pfdIDs, GLProfile glp, boolean onscreen, boolean usePBuffer) { - final int winattrbits = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer); - return wglARBPFIDs2GLCapabilitiesImpl(sharedResource, hdc, pfdIDs, glp, winattrbits); - } - - static List /*<GLCapabilitiesImmutable>*/ wglARBPFIDs2AllGLCapabilities(WindowsWGLDrawableFactory.SharedResource sharedResource, - long hdc, int[] pfdIDs, GLProfile glp) { - return wglARBPFIDs2GLCapabilitiesImpl(sharedResource, hdc, pfdIDs, glp, GLGraphicsConfigurationUtil.ALL_BITS); - } - - private static List /*<GLCapabilitiesImmutable>*/ wglARBPFIDs2GLCapabilitiesImpl(WindowsWGLDrawableFactory.SharedResource sharedResource, - long hdc, int[] pfdIDs, GLProfile glp, int winattrbits) { + static List <GLCapabilitiesImmutable> wglARBPFIDs2GLCapabilities(WindowsWGLDrawableFactory.SharedResource sharedResource, + AbstractGraphicsDevice device, GLProfile glp, long hdc, int[] pfdIDs, int winattrbits, 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>(); for(int i = 0; i<numFormats; i++) { if ( pfdIDs[i] >= 1 && - sharedResource.getContext().getWGLExt().wglGetPixelFormatAttribivARB(hdc, pfdIDs[i], 0, niattribs, iattributes, 0, iresults, 0) ) { - AttribList2GLCapabilities(bucket, 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; + 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); + System.err.println("wglARBPFIDs2GLCapabilities: bucket["+i+" -> skip]: pfdID "+pfdIDs[i]+", "+skipped+", winattr "+GLGraphicsConfigurationUtil.winAttributeBits2String(null, winattrbits).toString()); + } } else if (DEBUG) { - System.err.println("wglARBPFIDs2GLCapabilities: Cannot get pixel format attributes for pixel format " + - i + "/" + numFormats + ": " + pfdIDs[i] + ", " + - GLGraphicsConfigurationUtil.winAttributeBits2String(null, winattrbits).toString()); + if( 1 > pfdIDs[i] ) { + System.err.println("wglARBPFIDs2GLCapabilities: Invalid pfdID " + i + "/" + numFormats + ": " + pfdIDs[i]); + } else { + System.err.println("wglARBPFIDs2GLCapabilities: Cannot get pixel format attributes for pixel format " + + i + "/" + numFormats + ": " + pfdIDs[i] + ", hdc " + toHexString(hdc)); + } } } return bucket; } static boolean GLCapabilities2AttribList(GLCapabilitiesImmutable caps, - int[] iattributes, + IntBuffer iattributes, WindowsWGLDrawableFactory.SharedResource sharedResource, int accelerationValue, int[] floatMode) throws GLException { @@ -418,212 +420,145 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio return false; } - boolean onscreen = caps.isOnscreen(); - boolean pbuffer = caps.isPBuffer(); - 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; - } - if (onscreen) { - iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_WINDOW_ARB; - iattributes[niattribs++] = GL.GL_TRUE; - } else if (pbuffer && sharedResource.hasARBPBuffer()) { - iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_PBUFFER_ARB; - iattributes[niattribs++] = GL.GL_TRUE; + 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; + } else if( caps.isFBO() ) { + surfaceType = WGLExt.WGL_DRAW_TO_WINDOW_ARB; // native replacement! + } else if( usePBuffer ) { + surfaceType = WGLExt.WGL_DRAW_TO_PBUFFER_ARB; + } else if( caps.isBitmap() ) { + surfaceType = WGLExt.WGL_DRAW_TO_BITMAP_ARB; } else { - iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_BITMAP_ARB; - iattributes[niattribs++] = GL.GL_TRUE; + throw new GLException("no surface type set in caps: "+caps); } + iattributes.put(niattribs++, surfaceType); + iattributes.put(niattribs++, GL.GL_TRUE); - iattributes[niattribs++] = WGLExt.WGL_DOUBLE_BUFFER_ARB; + 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(); + 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(); + 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 (pbuffer && sharedResource.hasARBPBuffer()) { - // 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"); - } - - WindowsWGLContext sharedCtx = sharedResource.getContext(); - if (rect) { - if (!sharedCtx.isExtensionAvailable("GL_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) val |= GLGraphicsConfigurationUtil.WINDOW_BIT; + 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) val |= GLGraphicsConfigurationUtil.BITMAP_BIT; + 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) val |= GLGraphicsConfigurationUtil.PBUFFER_BIT; + if(iresults.get(i) == GL.GL_TRUE) { + val |= GLGraphicsConfigurationUtil.PBUFFER_BIT; + } break; } } return val; } - static boolean AttribList2GLCapabilities( ArrayList<? extends GLCapabilitiesImmutable> capsBucket, - final GLProfile glp, final long hdc, final int pfdID, final int[] iattribs, - final int niattribs, - final int[] iresults, final int winattrmask) { + static WGLGLCapabilities AttribList2GLCapabilities(final AbstractGraphicsDevice device, + final GLProfile glp, final long hdc, final int pfdID, + final IntBuffer iattribs, final int niattribs, IntBuffer iresults, final int winattrmask) { final int allDrawableTypeBits = AttribList2DrawableTypeBits(iattribs, niattribs, iresults); int drawableTypeBits = winattrmask & allDrawableTypeBits; if( 0 == drawableTypeBits ) { - return false; + return null; } PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor(); 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); + drawableTypeBits = drawableTypeBits & ~(GLGraphicsConfigurationUtil.WINDOW_BIT | GLGraphicsConfigurationUtil.BITMAP_BIT | GLGraphicsConfigurationUtil.FBO_BIT ); if( 0 == drawableTypeBits ) { - return false; + return null; } // non displayable requested (pbuffer) } - WGLGLCapabilities res = new WGLGLCapabilities(pfd, pfdID, glp); + final WGLGLCapabilities res = new WGLGLCapabilities(pfd, pfdID, glp); res.setValuesByARB(iattribs, niattribs, iresults); - - return GLGraphicsConfigurationUtil.addGLCapabilitiesPermutations(capsBucket, res, drawableTypeBits ); + return (WGLGLCapabilities) GLGraphicsConfigurationUtil.fixWinAttribBitsAndHwAccel(device, drawableTypeBits, res); } // @@ -649,7 +584,8 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio int dwFlags = pfd.getDwFlags(); if( 0 != (GDI.PFD_DRAW_TO_WINDOW & dwFlags ) ) { - val |= GLGraphicsConfigurationUtil.WINDOW_BIT; + val |= GLGraphicsConfigurationUtil.WINDOW_BIT | + GLGraphicsConfigurationUtil.FBO_BIT; } if( 0 != (GDI.PFD_DRAW_TO_BITMAP & dwFlags ) ) { val |= GLGraphicsConfigurationUtil.BITMAP_BIT; @@ -657,107 +593,138 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio return val; } - static WGLGLCapabilities PFD2GLCapabilities(GLProfile glp, long hdc, int pfdID, boolean onscreen) { - final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, false); - ArrayList<WGLGLCapabilities> capsBucket = new ArrayList<WGLGLCapabilities>(1); - if( PFD2GLCapabilities(capsBucket, glp, hdc, pfdID, winattrmask) ) { - return capsBucket.get(0); - } - return null; - } - - static boolean PFD2GLCapabilities(ArrayList<? extends GLCapabilitiesImmutable> capsBucket, final GLProfile glp, final long hdc, final int pfdID, final int winattrmask) { + static WGLGLCapabilities PFD2GLCapabilities(AbstractGraphicsDevice device, final GLProfile glp, final long hdc, final int pfdID, final int winattrmask) { PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor(hdc, pfdID); if(null == pfd) { - return false; + return null; } - if ((pfd.getDwFlags() & GDI.PFD_SUPPORT_OPENGL) == 0) { - return false; + if ( (pfd.getDwFlags() & GDI.PFD_SUPPORT_OPENGL) == 0) { + return null; } final int allDrawableTypeBits = PFD2DrawableTypeBits(pfd); final int drawableTypeBits = winattrmask & allDrawableTypeBits; if( 0 == drawableTypeBits ) { - return false; + 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; + } } - WGLGLCapabilities res = new WGLGLCapabilities(pfd, pfdID, glp); + final WGLGLCapabilities res = new WGLGLCapabilities(pfd, pfdID, glp); res.setValuesByGDI(); + return (WGLGLCapabilities) GLGraphicsConfigurationUtil.fixWinAttribBitsAndHwAccel(device, drawableTypeBits, res); + } - return GLGraphicsConfigurationUtil.addGLCapabilitiesPermutations(capsBucket, res, drawableTypeBits ); - } + static WGLGLCapabilities PFD2GLCapabilitiesNoCheck(AbstractGraphicsDevice device, final GLProfile glp, final long hdc, final int pfdID) { + PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor(hdc, pfdID); + return PFD2GLCapabilitiesNoCheck(device, glp, pfd, pfdID); + } - static PIXELFORMATDESCRIPTOR GLCapabilities2PFD(GLCapabilitiesImmutable caps, PIXELFORMATDESCRIPTOR pfd) { - int colorDepth = (caps.getRedBits() + - caps.getGreenBits() + - caps.getBlueBits()); - if (colorDepth < 15) { - throw new GLException("Bit depths < 15 (i.e., non-true-color) not supported"); - } - int pfdFlags = (GDI.PFD_SUPPORT_OPENGL | - GDI.PFD_GENERIC_ACCELERATED); - if (caps.getDoubleBuffered()) { - pfdFlags |= GDI.PFD_DOUBLEBUFFER; - } - if (caps.isOnscreen()) { - pfdFlags |= GDI.PFD_DRAW_TO_WINDOW; - } else { - pfdFlags |= GDI.PFD_DRAW_TO_BITMAP; - } - if (caps.getStereo()) { - pfdFlags |= GDI.PFD_STEREO; - } - pfd.setDwFlags(pfdFlags); - pfd.setIPixelType((byte) GDI.PFD_TYPE_RGBA); - pfd.setCColorBits((byte) colorDepth); - pfd.setCRedBits ((byte) caps.getRedBits()); - pfd.setCGreenBits((byte) caps.getGreenBits()); - pfd.setCBlueBits ((byte) caps.getBlueBits()); - pfd.setCAlphaBits((byte) caps.getAlphaBits()); - int accumDepth = (caps.getAccumRedBits() + - caps.getAccumGreenBits() + - caps.getAccumBlueBits()); - pfd.setCAccumBits ((byte) accumDepth); - pfd.setCAccumRedBits ((byte) caps.getAccumRedBits()); - pfd.setCAccumGreenBits((byte) caps.getAccumGreenBits()); - pfd.setCAccumBlueBits ((byte) caps.getAccumBlueBits()); - pfd.setCAccumAlphaBits((byte) caps.getAccumAlphaBits()); - pfd.setCDepthBits((byte) caps.getDepthBits()); - pfd.setCStencilBits((byte) caps.getStencilBits()); - pfd.setILayerType((byte) GDI.PFD_MAIN_PLANE); - - // n/a with non ARB/GDI method: - // multisample - // opaque - // pbuffer - return pfd; - } - - static PIXELFORMATDESCRIPTOR createPixelFormatDescriptor(long hdc, int pfdID) { - PIXELFORMATDESCRIPTOR pfd = PIXELFORMATDESCRIPTOR.create(); - pfd.setNSize((short) PIXELFORMATDESCRIPTOR.size()); - pfd.setNVersion((short) 1); - if(0 != hdc && 1 <= pfdID) { - if (WGLUtil.DescribePixelFormat(hdc, pfdID, PIXELFORMATDESCRIPTOR.size(), pfd) == 0) { - // Accelerated pixel formats that are non displayable - if(DEBUG) { - System.err.println("Info: Non displayable pixel format " + pfdID + " of device context: error code " + GDI.GetLastError()); - } + static WGLGLCapabilities PFD2GLCapabilitiesNoCheck(AbstractGraphicsDevice device, GLProfile glp, PIXELFORMATDESCRIPTOR pfd, int pfdID) { + if(null == pfd) { return null; } - } - return pfd; - } - - static PIXELFORMATDESCRIPTOR createPixelFormatDescriptor() { - return createPixelFormatDescriptor(0, 0); - } - - public String toString() { - return "WindowsWGLGraphicsConfiguration["+getScreen()+", pfdID " + getPixelFormatID() + ", ARB-Choosen " + isChoosenByARB() + - ",\n\trequested " + getRequestedCapabilities() + - ",\n\tchosen " + getChosenCapabilities() + - "]"; - } + final WGLGLCapabilities res = new WGLGLCapabilities(pfd, pfdID, glp); + res.setValuesByGDI(); + + return (WGLGLCapabilities) GLGraphicsConfigurationUtil.fixWinAttribBitsAndHwAccel(device, PFD2DrawableTypeBits(pfd), res); + } + + static PIXELFORMATDESCRIPTOR GLCapabilities2PFD(GLCapabilitiesImmutable caps, PIXELFORMATDESCRIPTOR pfd) { + int colorDepth = (caps.getRedBits() + + caps.getGreenBits() + + caps.getBlueBits()); + if (colorDepth < 15) { + throw new GLException("Bit depths < 15 (i.e., non-true-color) not supported"); + } + int pfdFlags = ( GDI.PFD_SUPPORT_OPENGL | GDI.PFD_GENERIC_ACCELERATED ); + + if( caps.isOnscreen() ) { + pfdFlags |= GDI.PFD_DRAW_TO_WINDOW; + } else if( caps.isFBO() ) { + pfdFlags |= GDI.PFD_DRAW_TO_WINDOW; // native replacement! + } else if( caps.isPBuffer() ) { + pfdFlags |= GDI.PFD_DRAW_TO_BITMAP; // pbuffer n/a, use bitmap + } else if( caps.isBitmap() ) { + pfdFlags |= GDI.PFD_DRAW_TO_BITMAP; + } else { + throw new GLException("no surface type set in caps: "+caps); + } + + if ( caps.getDoubleBuffered() ) { + if( caps.isBitmap() || caps.isPBuffer() ) { + pfdFlags |= GDI.PFD_DOUBLEBUFFER_DONTCARE; // bitmaps probably don't have dbl buffering + } else { + pfdFlags |= GDI.PFD_DOUBLEBUFFER; + } + } + + if (caps.getStereo()) { + pfdFlags |= GDI.PFD_STEREO; + } + pfd.setDwFlags(pfdFlags); + pfd.setIPixelType((byte) GDI.PFD_TYPE_RGBA); + pfd.setCColorBits((byte) colorDepth); + pfd.setCRedBits ((byte) caps.getRedBits()); + pfd.setCGreenBits((byte) caps.getGreenBits()); + pfd.setCBlueBits ((byte) caps.getBlueBits()); + pfd.setCAlphaBits((byte) caps.getAlphaBits()); + int accumDepth = (caps.getAccumRedBits() + + caps.getAccumGreenBits() + + caps.getAccumBlueBits()); + pfd.setCAccumBits ((byte) accumDepth); + pfd.setCAccumRedBits ((byte) caps.getAccumRedBits()); + pfd.setCAccumGreenBits((byte) caps.getAccumGreenBits()); + pfd.setCAccumBlueBits ((byte) caps.getAccumBlueBits()); + pfd.setCAccumAlphaBits((byte) caps.getAccumAlphaBits()); + pfd.setCDepthBits((byte) caps.getDepthBits()); + pfd.setCStencilBits((byte) caps.getStencilBits()); + pfd.setILayerType((byte) GDI.PFD_MAIN_PLANE); + + // n/a with non ARB/GDI method: + // multisample + // opaque + // pbuffer + return pfd; + } + + static PIXELFORMATDESCRIPTOR createPixelFormatDescriptor(long hdc, int pfdID) { + PIXELFORMATDESCRIPTOR pfd = PIXELFORMATDESCRIPTOR.create(); + pfd.setNSize((short) PIXELFORMATDESCRIPTOR.size()); + pfd.setNVersion((short) 1); + if(0 != hdc && 1 <= pfdID) { + if (WGLUtil.DescribePixelFormat(hdc, pfdID, PIXELFORMATDESCRIPTOR.size(), pfd) == 0) { + // Accelerated pixel formats that are non displayable + if(DEBUG) { + System.err.println("Info: Non displayable pixel format " + pfdID + " of device context: error code " + GDI.GetLastError()); + } + return null; + } + } + return pfd; + } + + static PIXELFORMATDESCRIPTOR createPixelFormatDescriptor() { + return createPixelFormatDescriptor(0, 0); + } + + @Override + public String toString() { + return "WindowsWGLGraphicsConfiguration["+getScreen()+", pfdID " + getPixelFormatID() + ", ARB-Choosen " + isChoosenByARB() + + ",\n\trequested " + getRequestedCapabilities() + + ",\n\tchosen " + getChosenCapabilities() + + "]"; + } } diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java index 2c8c03185..969e45ed8 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,11 +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; @@ -68,13 +74,14 @@ 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, 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) { + CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested, CapabilitiesChooser chooser, AbstractGraphicsScreen absScreen, int nativeVisualID) { if (! (capsChosen instanceof GLCapabilitiesImmutable) ) { throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilities objects - chosen"); @@ -84,7 +91,11 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilities objects - requested"); } - return chooseGraphicsConfigurationStatic((GLCapabilitiesImmutable)capsChosen, (GLCapabilitiesImmutable)capsRequested, chooser, absScreen); + if (chooser != null && !(chooser instanceof GLCapabilitiesChooser)) { + throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilitiesChooser objects"); + } + + return chooseGraphicsConfigurationStatic((GLCapabilitiesImmutable)capsChosen, (GLCapabilitiesImmutable)capsRequested, (GLCapabilitiesChooser)chooser, absScreen); } static WindowsWGLGraphicsConfiguration createDefaultGraphicsConfiguration(GLCapabilitiesImmutable caps, @@ -94,34 +105,34 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat static WindowsWGLGraphicsConfiguration chooseGraphicsConfigurationStatic(GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsReq, - CapabilitiesChooser chooser, + GLCapabilitiesChooser chooser, AbstractGraphicsScreen absScreen) { if(null==absScreen) { absScreen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_WINDOWS); } - AbstractGraphicsDevice absDevice = absScreen.getDevice(); - - capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( - capsChosen, GLDrawableFactory.getDesktopFactory().canCreateGLPbuffer(absDevice) ); - - return new WindowsWGLGraphicsConfiguration( absScreen, capsChosen, capsReq, (GLCapabilitiesChooser)chooser ); + final AbstractGraphicsDevice absDevice = absScreen.getDevice(); + capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( capsChosen, GLDrawableFactory.getDesktopFactory(), absDevice); + return new WindowsWGLGraphicsConfiguration( absScreen, capsChosen, capsReq, chooser ); } protected static List<GLCapabilitiesImmutable> getAvailableCapabilities(WindowsWGLDrawableFactory factory, AbstractGraphicsDevice device) { - WindowsWGLDrawableFactory.SharedResource sharedResource = factory.getOrCreateSharedResource(device); + final WindowsWGLDrawableFactory.SharedResource sharedResource = factory.getOrCreateSharedResourceImpl(device); if(null == sharedResource) { throw new GLException("Shared resource for device n/a: "+device); } - WindowsWGLDrawable sharedDrawable = sharedResource.getDrawable(); - GLCapabilitiesImmutable capsChosen = sharedDrawable.getChosenGLCapabilities(); - WindowsWGLContext sharedContext = sharedResource.getContext(); - List/*<GLCapabilitiesImmutable>*/ availableCaps = null; - - if ( sharedResource.needsCurrentContext4ARBPFDQueries() ) { + final GLDrawableImpl sharedDrawable = sharedResource.getDrawable(); + final GLProfile glp = GLProfile.getDefault(device); + + List<GLCapabilitiesImmutable> availableCaps = null; + + 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 { @@ -130,17 +141,21 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat throw new GLException("Error: HDC is null"); } if (sharedResource.hasARBPixelFormat()) { - availableCaps = getAvailableGLCapabilitiesARB(hdc, sharedResource, capsChosen.getGLProfile()); + availableCaps = WindowsWGLGraphicsConfigurationFactory.getAvailableGLCapabilitiesARB(sharedResource, sharedResource.getDevice(), glp, hdc); } - if( null == availableCaps || availableCaps.isEmpty() ) { - availableCaps = getAvailableGLCapabilitiesGDI(hdc, capsChosen.getGLProfile()); + 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 ) { @@ -149,17 +164,23 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat return availableCaps; } - static List/*<GLCapabilitiesImmutable>*/ getAvailableGLCapabilitiesARB(long hdc, WindowsWGLDrawableFactory.SharedResource sharedResource, GLProfile glProfile) { - int[] pformats = WindowsWGLGraphicsConfiguration.wglAllARBPFIDs(sharedResource.getContext(), hdc); - return WindowsWGLGraphicsConfiguration.wglARBPFIDs2AllGLCapabilities(sharedResource, hdc, pformats, glProfile); + private static List<GLCapabilitiesImmutable> getAvailableGLCapabilitiesARB(WindowsWGLDrawableFactory.SharedResource sharedResource, AbstractGraphicsDevice device, GLProfile glProfile, 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 & ~GLGraphicsConfigurationUtil.BITMAP_BIT, false); // w/o BITMAP } - static List/*<GLCapabilitiesImmutable>*/ getAvailableGLCapabilitiesGDI(long hdc, GLProfile glProfile) { + private static List<GLCapabilitiesImmutable> getAvailableGLCapabilitiesGDI(AbstractGraphicsDevice device, GLProfile glProfile, long hdc, boolean bitmapOnly) { int[] pformats = WindowsWGLGraphicsConfiguration.wglAllGDIPFIDs(hdc); int numFormats = pformats.length; - ArrayList<GLCapabilitiesImmutable> bucket = new ArrayList<GLCapabilitiesImmutable>(numFormats); + List<GLCapabilitiesImmutable> bucket = new ArrayList<GLCapabilitiesImmutable>(numFormats); for (int i = 0; i < numFormats; i++) { - WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(bucket, 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); + } } return bucket; } @@ -206,7 +227,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); @@ -264,17 +285,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); - WindowsWGLContext sharedContext = null; - if (null != sharedResource && sharedResource.needsCurrentContext4ARBPFDQueries()) { + 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(hdc, extHDC, config, chooser, (WindowsWGLDrawableFactory)factory, pfdIDs) ) { - updateGraphicsConfigurationGDI(hdc, extHDC, config, chooser, 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 { if (null != sharedContext) { @@ -283,10 +311,10 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat } } - private static boolean updateGraphicsConfigurationARB(long hdc, boolean extHDC, WindowsWGLGraphicsConfiguration config, - CapabilitiesChooser chooser, WindowsWGLDrawableFactory factory, int[] pformats) { - AbstractGraphicsDevice device = config.getScreen().getDevice(); - WindowsWGLDrawableFactory.SharedResource sharedResource = factory.getOrCreateSharedResource(device); + private static boolean updateGraphicsConfigurationARB(WindowsWGLDrawableFactory factory, WindowsWGLGraphicsConfiguration config, CapabilitiesChooser chooser, + long hdc, boolean extHDC, int[] pformats) { + final AbstractGraphicsDevice device = config.getScreen().getDevice(); + final WindowsWGLDrawableFactory.SharedResource sharedResource = factory.getOrCreateSharedResourceImpl(device); if (null == sharedResource) { if (DEBUG) { @@ -301,14 +329,25 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat return false; } - GLCapabilitiesImmutable capsChosen = (GLCapabilitiesImmutable) config.getChosenCapabilities(); - boolean isOpaque = capsChosen.isBackgroundOpaque() && GDI.DwmIsCompositionEnabled(); - boolean onscreen = capsChosen.isOnscreen(); - boolean usePBuffer = capsChosen.isPBuffer(); - GLProfile glProfile = capsChosen.getGLProfile(); - + final GLCapabilitiesImmutable capsChosen = (GLCapabilitiesImmutable) config.getChosenCapabilities(); + final boolean isOpaque = capsChosen.isBackgroundOpaque() && GDI.DwmIsCompositionEnabled(); + 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("translucency requested: "+(!capsChosen.isBackgroundOpaque())+", compositioning enabled: "+GDI.DwmIsCompositionEnabled()+" -> translucency "+(!isOpaque)); + System.err.println("updateGraphicsConfigurationARB: hdc "+toHexString(hdc)+", pfdIDCount(hdc) "+pfdIDCount+", capsChosen "+capsChosen+", "+GLGraphicsConfigurationUtil.winAttributeBits2String(null, winattrbits).toString()); + 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) { + if (DEBUG) { + System.err.println("updateGraphicsConfigurationARB: failed due to 0 pfdIDs for hdc "+toHexString(hdc)+" - hdc incompatible w/ ARB ext."); + } + return false; } WGLGLCapabilities pixelFormatCaps = null; // chosen or preset PFD ID's caps @@ -324,29 +363,28 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat + ", pixelformat " + presetPFDID); } pixelFormatSet = true; - pixelFormatCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedResource, hdc, presetPFDID, glProfile, onscreen, usePBuffer); + 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(hdc, sharedResource, capsChosen, - iattributes, accelerationMode, fattributes); + pformats = WindowsWGLGraphicsConfiguration.wglChoosePixelFormatARB(sharedResource, device, capsChosen, + hdc, iattributes, accelerationMode, fattributes); if (null == pformats) { accelerationMode = WGLExt.WGL_GENERIC_ACCELERATION_ARB; - pformats = WindowsWGLGraphicsConfiguration.wglChoosePixelFormatARB(hdc, sharedResource, capsChosen, - iattributes, accelerationMode, fattributes); + pformats = WindowsWGLGraphicsConfiguration.wglChoosePixelFormatARB(sharedResource, device, capsChosen, + hdc, iattributes, accelerationMode, fattributes); } if (null == pformats) { accelerationMode = -1; // use what we are offered .. - pformats = WindowsWGLGraphicsConfiguration.wglChoosePixelFormatARB(hdc, sharedResource, capsChosen, - iattributes, accelerationMode, fattributes); + pformats = WindowsWGLGraphicsConfiguration.wglChoosePixelFormatARB(sharedResource, device, capsChosen, + hdc, iattributes, accelerationMode, fattributes); } if (null != pformats) { recommendedIndex = 0; @@ -355,7 +393,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat System.err.println("updateGraphicsConfigurationARB: wglChoosePixelFormatARB failed with: "+capsChosen); } // 2nd choice: get all GLCapabilities available, no preferred recommendedIndex available - pformats = WindowsWGLGraphicsConfiguration.wglAllARBPFIDs(sharedResource.getContext(), hdc); + pformats = WindowsWGLGraphicsConfiguration.wglAllARBPFDIDs(pfdIDCount); if (DEBUG) { final int len = ( null != pformats ) ? pformats.length : 0; System.err.println("updateGraphicsConfigurationARB: NumFormats (wglAllARBPFIDs) " + len); @@ -369,14 +407,14 @@ 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 /*<WGLGLCapabilities>*/ availableCaps = - WindowsWGLGraphicsConfiguration.wglARBPFIDs2GLCapabilities(sharedResource, hdc, pformats, - glProfile, onscreen, usePBuffer); if( null == availableCaps || 0 == availableCaps.size() ) { if (DEBUG) { - System.err.println("updateGraphicsConfigurationARB: wglARBPFIDs2GLCapabilities failed with " + pformats.length + - " pfd ids, onscreen " + onscreen + ", pbuffer " + usePBuffer); + System.err.println("updateGraphicsConfigurationARB: wglARBPFIDs2GLCapabilities failed with " + pformats.length + " pfd ids"); Thread.dumpStack(); } return false; @@ -384,14 +422,19 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat if (DEBUG) { System.err.println("updateGraphicsConfigurationARB: " + pformats.length + - " pfd ids, onscreen " + onscreen + ", pbuffer " + usePBuffer + ", " + 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(); @@ -402,12 +445,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); } } @@ -419,61 +462,121 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat return true; } - private static boolean updateGraphicsConfigurationGDI(long hdc, boolean extHDC, WindowsWGLGraphicsConfiguration config, - CapabilitiesChooser chooser, int[] pformats) { - GLCapabilitiesImmutable capsChosen = (GLCapabilitiesImmutable) config.getChosenCapabilities(); - if(capsChosen.isPBuffer()) { + private static boolean updateGraphicsConfigurationGDI(WindowsWGLGraphicsConfiguration config, CapabilitiesChooser chooser, long hdc, + 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); } return false; } - boolean onscreen = capsChosen.isOnscreen(); - GLProfile glProfile = capsChosen.getGLProfile(); + // final boolean onscreen = capsChosen.isOnscreen(); + // final boolean useFBO = capsChosen.isFBO(); + final GLProfile glProfile = capsChosen.getGLProfile(); + final int winattrmask = GLGraphicsConfigurationUtil.getExclusiveWinAttributeBits(capsChosen); + + if(DEBUG) { + 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); + } - ArrayList<WGLGLCapabilities> availableCaps = new ArrayList<WGLGLCapabilities>(); - 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(glProfile, hdc, pfdID, onscreen); + pixelFormatCaps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(device, glProfile, hdc, presetPFDID, winattrmask); + if(null == pixelFormatCaps) { + throw new GLException("Could not map PFD2GLCaps w/ already chosen pfdID "+presetPFDID); + } } else { - if(null == pformats) { + final boolean givenPFormats = null != pformats; + if( !givenPFormats ) { pformats = WindowsWGLGraphicsConfiguration.wglAllGDIPFIDs(hdc); } - final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, false); - - for (int i = 0; i < pformats.length; i++) { - WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(availableCaps, glProfile, hdc, pformats[i], winattrmask); - } // 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 ) { - // seek index .. - for (recommendedIndex = availableCaps.size() - 1 ; - 0 <= recommendedIndex && pfdID != ((WGLGLCapabilities) availableCaps.get(recommendedIndex)).getPFDID(); - recommendedIndex--) - { /* nop */ } + final boolean skipCapsChooser; + if( 1 <= chosenPFDID ) { + final boolean _skipCapsChooser = null == chooser && capsChosen.isBackgroundOpaque(); // fast path: skip choosing if using recommended idx and null chooser is used and if not translucent + // seek index .. in all formats _or_ in given formats! + 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); + availableCaps.add(caps); + recommendedIndex = 0; + skipCapsChooser = true; + } 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; } - // 2nd choice: if no preferred recommendedIndex available if (DEBUG) { - System.err.println("updateGraphicsConfigurationGDI: ChoosePixelFormat(HDC " + toHexString(hdc) + ") = " + 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) { + 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 + final int chosenIndex; + if( skipCapsChooser ) { + chosenIndex = recommendedIndex; + } else { + chosenIndex = chooseCapabilities(chooser, capsChosen, availableCaps, recommendedIndex); } - int chosenIndex = chooseCapabilities(chooser, capsChosen, availableCaps, recommendedIndex); if ( 0 > chosenIndex ) { if (DEBUG) { System.err.println("updateGraphicsConfigurationGDI: failed, return false"); @@ -481,10 +584,10 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat } return false; } - pixelFormatCaps = availableCaps.get(chosenIndex); + pixelFormatCaps = (WGLGLCapabilities) availableCaps.get(chosenIndex); if (DEBUG) { - System.err.println("chosen pfdID (GDI): native recommended "+ (recommendedIndex+1) + - ", caps " + pixelFormatCaps); + System.err.println("chosen pfdID (GDI): recommendedIndex "+recommendedIndex+" -> chosenIndex "+ chosenIndex + ", skipCapsChooser "+skipCapsChooser+", caps " + pixelFormatCaps + + " (" + WGLGLCapabilities.PFD2String(pixelFormatCaps.getPFD(), pixelFormatCaps.getPFDID()) +")"); } } 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 bd64b58a4..96bd0bdd0 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 @@ -63,14 +63,15 @@ import javax.media.opengl.GLDrawableFactory; public class WindowsAWTWGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactory { public static void registerFactory() { - GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.awt.AWTGraphicsDevice.class, new WindowsAWTWGLGraphicsConfigurationFactory()); + 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) { + CapabilitiesChooser chooser, AbstractGraphicsScreen absScreen, int nativeVisualID) { GraphicsDevice device = null; if (absScreen != null && !(absScreen instanceof AWTGraphicsScreen)) { @@ -105,16 +106,16 @@ public class WindowsAWTWGLGraphicsConfigurationFactory extends GLGraphicsConfigu WindowsGraphicsDevice winDevice = new WindowsGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT); DefaultGraphicsScreen winScreen = new DefaultGraphicsScreen(winDevice, awtScreen.getIndex()); - GraphicsConfigurationFactory configFactory = GraphicsConfigurationFactory.getFactory(winDevice); + GraphicsConfigurationFactory configFactory = GraphicsConfigurationFactory.getFactory(winDevice, capsChosen); WindowsWGLGraphicsConfiguration winConfig = (WindowsWGLGraphicsConfiguration) configFactory.chooseGraphicsConfiguration(capsChosen, capsRequested, - chooser, winScreen); + chooser, winScreen, nativeVisualID); if (winConfig == null) { throw new GLException("Unable to choose a GraphicsConfiguration: "+capsChosen+",\n\t"+chooser+"\n\t"+winScreen); } - GLDrawableFactory drawableFactory = GLDrawableFactory.getFactory(((GLCapabilitiesImmutable)capsChosen).getGLProfile()); + GLDrawableFactory drawableFactory = GLDrawableFactory.getFactory(((GLCapabilitiesImmutable)capsChosen).getGLProfile()); GraphicsConfiguration chosenGC = null; if ( drawableFactory instanceof WindowsWGLDrawableFactory ) { @@ -138,7 +139,7 @@ public class WindowsAWTWGLGraphicsConfigurationFactory extends GLGraphicsConfigu } // go on .. } - + if( null == chosenGC ) { // 2nd Choice: Choose and match the GL Visual with AWT: // - collect all AWT PFDs @@ -147,7 +148,7 @@ 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]; @@ -171,11 +172,11 @@ public class WindowsAWTWGLGraphicsConfigurationFactory extends GLGraphicsConfigu 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); } |