diff options
author | Sven Gothel <[email protected]> | 2011-02-08 06:20:35 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2011-02-08 06:20:35 +0100 |
commit | 4cda4b70dbcd21cf57e1e253ddba32b88bcaec18 (patch) | |
tree | 6f16d211cb80ebf5dcc8cab6424c70079a38ea7f /src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java | |
parent | eb7986963c87bc6f33e7f18bb90ddf898b7dd63a (diff) |
Move implementation private files from com.jogamp.<module>.impl. to jogamp.<module> (1/2) - rename task
- com.jogamp.opengl.impl -> jogamp.opengl
- com.jogamp.opengl.util.glsl.fixedfunc.impl -> jogamp.opengl.util.glsl.fixedfunc
- com.jogamp.nativewindow.impl -> jogamp.nativewindow
- com.jogamp.newt.impl -> jogamp.newt
This sorts implementation details from the top level, ie skipping the public 'com',
allowing a better seperation of public classes and implementation details
and also reduces strings.
This approach of public/private seperation is also used in the OpenJDK.
Diffstat (limited to 'src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java')
-rw-r--r-- | src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java | 478 |
1 files changed, 478 insertions, 0 deletions
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java new file mode 100644 index 000000000..7d38f8ee8 --- /dev/null +++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java @@ -0,0 +1,478 @@ +/* + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for use + * in the design, construction, operation or maintenance of any nuclear + * facility. + * + * Sun gratefully acknowledges that this software was originally authored + * and developed by Kenneth Bradley Russell and Christopher John Kline. + */ + +package com.jogamp.opengl.impl.windows.wgl; + +import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.Map; + +import javax.media.nativewindow.AbstractGraphicsConfiguration; +import javax.media.nativewindow.AbstractGraphicsDevice; +import javax.media.opengl.GLContext; +import javax.media.opengl.GLException; +import javax.media.opengl.GLCapabilitiesImmutable; + +import com.jogamp.gluegen.runtime.ProcAddressTable; +import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver; +import com.jogamp.nativewindow.impl.windows.GDI; +import com.jogamp.opengl.impl.GLContextImpl; +import com.jogamp.opengl.impl.GLContextShareSet; +import com.jogamp.opengl.impl.GLDrawableImpl; + +public class WindowsWGLContext extends GLContextImpl { + static final Map/*<String, String>*/ functionNameMap; + static final Map/*<String, String>*/ extensionNameMap; + private boolean wglGetExtensionsStringEXTInitialized; + private boolean wglGetExtensionsStringEXTAvailable; + private boolean wglGLReadDrawableAvailableSet; + private boolean wglGLReadDrawableAvailable; + private WGLExt wglExt; + // Table that holds the addresses of the native C-language entry points for + // WGL extension functions. + private WGLExtProcAddressTable wglExtProcAddressTable; + + static { + functionNameMap = new HashMap(); + functionNameMap.put("glAllocateMemoryNV", "wglAllocateMemoryNV"); + functionNameMap.put("glFreeMemoryNV", "wglFreeMemoryNV"); + + extensionNameMap = new HashMap(); + extensionNameMap.put("GL_ARB_pbuffer", "WGL_ARB_pbuffer"); + extensionNameMap.put("GL_ARB_pixel_format", "WGL_ARB_pixel_format"); + } + + // FIXME: figure out how to hook back in the Java 2D / JOGL bridge + WindowsWGLContext(GLDrawableImpl drawable, + GLContext shareWith) { + super(drawable, shareWith); + } + + protected void resetState() { + wglGetExtensionsStringEXTInitialized=false; + wglGetExtensionsStringEXTAvailable=false; + wglGLReadDrawableAvailableSet=false; + wglGLReadDrawableAvailable=false; + // no inner state _wglExt=null; + wglExtProcAddressTable=null; + } + + public Object getPlatformGLExtensions() { + return getWGLExt(); + } + + /* package private */ final WGLExt getWGLExt() { + if( null == getWGLExtProcAddressTable()) { + throw new InternalError("Null WGLExtProcAddressTable"); + } + if (wglExt == null) { + wglExt = new WGLExtImpl(this); + } + return wglExt; + } + + public final boolean isGLReadDrawableAvailable() { + if(!wglGLReadDrawableAvailableSet && null != getWGLExtProcAddressTable()) { + WindowsWGLDrawableFactory factory = (WindowsWGLDrawableFactory)drawable.getFactoryImpl(); + AbstractGraphicsConfiguration config = drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + AbstractGraphicsDevice device = config.getScreen().getDevice(); + switch( factory.isReadDrawableAvailable(device) ) { + case 1: + wglGLReadDrawableAvailable = true; + wglGLReadDrawableAvailableSet=true; + break; + case 0: + wglGLReadDrawableAvailable = false; + wglGLReadDrawableAvailableSet=true; + break; + } + } + return wglGLReadDrawableAvailable; + } + + private final boolean wglMakeContextCurrent(long hDrawDC, long hReadDC, long ctx) { + boolean ok = false; + if(wglGLReadDrawableAvailable) { + // needs initilized WGL ProcAddress table + ok = getWGLExt().wglMakeContextCurrent(hDrawDC, hReadDC, ctx); + } else if ( hDrawDC == hReadDC ) { + ok = WGL.wglMakeCurrent(hDrawDC, ctx); + } else { + // should not happen due to 'isGLReadDrawableAvailable()' query in GLContextImpl + throw new InternalError("Given readDrawable but no driver support"); + } + int werr = ( !ok ) ? GDI.GetLastError() : GDI.ERROR_SUCCESS; + if(DEBUG && !ok) { + Throwable t = new Throwable ("Info: wglMakeContextCurrent draw "+ + this.toHexString(hDrawDC) + ", read " + this.toHexString(hReadDC) + + ", ctx " + this.toHexString(ctx) + ", werr " + werr); + t.printStackTrace(); + } + if(!ok && 0==hDrawDC && 0==hReadDC) { + // Some GPU's falsely fails with a zero error code (success), + // in case this is a release context request we tolerate this + return werr == GDI.ERROR_SUCCESS ; + } + return ok; + } + + public final ProcAddressTable getPlatformExtProcAddressTable() { + return getWGLExtProcAddressTable(); + } + + public final WGLExtProcAddressTable getWGLExtProcAddressTable() { + return wglExtProcAddressTable; + } + + protected Map/*<String, String>*/ getFunctionNameMap() { return functionNameMap; } + + protected Map/*<String, String>*/ getExtensionNameMap() { return extensionNameMap; } + + protected void destroyContextARBImpl(long context) { + WGL.wglMakeCurrent(0, 0); + WGL.wglDeleteContext(context); + } + + protected long createContextARBImpl(long share, boolean direct, int ctp, int major, int minor) { + if( null == getWGLExtProcAddressTable()) { + updateGLXProcAddressTable(); + } + WGLExt _wglExt = getWGLExt(); + if(DEBUG) { + System.err.println(getThreadName()+" - WindowWGLContext.createContextARBImpl: "+getGLVersion(major, minor, ctp, "@creation") + + ", handle "+toHexString(drawable.getHandle()) + ", share "+toHexString(share)+", direct "+direct+ + ", wglCreateContextAttribsARB: "+toHexString(wglExtProcAddressTable._addressof_wglCreateContextAttribsARB)); + Thread.dumpStack(); + } + + boolean ctBwdCompat = 0 != ( CTX_PROFILE_COMPAT & ctp ) ; + boolean ctFwdCompat = 0 != ( CTX_OPTION_FORWARD & ctp ) ; + boolean ctDebug = 0 != ( CTX_OPTION_DEBUG & ctp ) ; + + long ctx=0; + + final int idx_flags = 4; + final int idx_profile = 6; + + /* WGLExt.WGL_CONTEXT_LAYER_PLANE_ARB, WGLExt.WGL_CONTEXT_LAYER_PLANE_ARB, */ + + int attribs[] = { + /* 0 */ WGLExt.WGL_CONTEXT_MAJOR_VERSION_ARB, major, + /* 2 */ WGLExt.WGL_CONTEXT_MINOR_VERSION_ARB, minor, + /* 4 */ WGLExt.WGL_CONTEXT_FLAGS_ARB, 0, + /* 6 */ 0, 0, + /* 8 */ 0 + }; + + 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 ) { + attribs[idx_flags+1] |= WGLExt.WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; + } + if( ctDebug) { + attribs[idx_flags+1] |= WGLExt.WGL_CONTEXT_DEBUG_BIT_ARB; + } + } + + try { + ctx = _wglExt.wglCreateContextAttribsARB(drawable.getHandle(), share, attribs, 0); + } catch (RuntimeException re) { + if(DEBUG) { + Throwable t = new Throwable("Info: WindowWGLContext.createContextARBImpl wglCreateContextAttribsARB failed with "+getGLVersion(major, minor, ctp, "@creation"), re); + t.printStackTrace(); + } + } + + if(0!=ctx) { + if (!wglMakeContextCurrent(drawable.getHandle(), drawableRead.getHandle(), ctx)) { + if(DEBUG) { + System.err.println("WindowsWGLContext.createContextARB couldn't make current "+getGLVersion(major, minor, ctp, "@creation")); + } + WGL.wglMakeCurrent(0, 0); + WGL.wglDeleteContext(ctx); + ctx = 0; + } else { + if (DEBUG) { + System.err.println(getThreadName() + ": createContextARBImpl: OK "+getGLVersion(major, minor, ctp, "@creation")+", share "+share+", direct "+direct); + } + // the following is issued by the caller 'GLContextImpl.createContextARB()' + // setGLFunctionAvailability(true, major, minor, ctp); + } + } else if (DEBUG) { + System.err.println(getThreadName() + ": createContextARBImpl: NO "+getGLVersion(major, minor, ctp, "@creation")); + } + return ctx; + } + + /** + * Creates and initializes an appropriate OpenGL context. Should only be + * called by {@link #makeCurrentImpl()}. + */ + protected boolean createImpl() { + WindowsWGLDrawableFactory factory = (WindowsWGLDrawableFactory)drawable.getFactoryImpl(); + AbstractGraphicsConfiguration config = drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + AbstractGraphicsDevice device = config.getScreen().getDevice(); + WindowsWGLContext sharedContext = (WindowsWGLContext) factory.getOrCreateSharedContextImpl(device); + GLCapabilitiesImmutable glCaps = drawable.getChosenGLCapabilities(); + + isGLReadDrawableAvailable(); // trigger setup wglGLReadDrawableAvailable + + // Windows can set up sharing of display lists after creation time + WindowsWGLContext other = (WindowsWGLContext) GLContextShareSet.getShareContext(this); + long share = 0; + if (other != null) { + share = other.getHandle(); + if (share == 0) { + throw new GLException("GLContextShareSet returned an invalid OpenGL context"); + } + } + + int minor[] = new int[1]; + int major[] = new int[1]; + int ctp[] = new int[1]; + 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, major, minor, ctp); + createContextARBTried = true; + if (DEBUG && 0!=contextHandle) { + System.err.println(getThreadName() + ": createImpl: OK (ARB, using sharedContext) share "+share); + } + } + + long temp_ctx = 0; + 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) { + throw new GLException("Unable to create temp OpenGL context for device context " + toHexString(drawable.getHandle())); + } + 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|CTX_OPTION_ANY); // use GL_VERSION + boolean isCreateContextAttribsARBAvailable = isFunctionAvailable("wglCreateContextAttribsARB"); + WGL.wglMakeCurrent(0, 0); // release temp context + + if( !createContextARBTried) { + if(isCreateContextAttribsARBAvailable && + isExtensionAvailable("WGL_ARB_create_context") ) { + // initial ARB context creation + contextHandle = createContextARB(share, true, major, minor, ctp); + createContextARBTried=true; + if (DEBUG) { + if(0!=contextHandle) { + System.err.println(getThreadName() + ": createContextImpl: OK (ARB, initial) share "+share); + } else { + System.err.println(getThreadName() + ": createContextImpl: NOT OK (ARB, initial) - creation failed - share "+share); + } + } + } else if (DEBUG) { + System.err.println(getThreadName() + ": createContextImpl: NOT OK (ARB, initial) - extension not available - share "+share); + } + } + } + + if(0!=contextHandle) { + share = 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)) { + throw new GLException("Cannot make previous verified context current: 0x" + toHexString(contextHandle) + ", werr: " + GDI.GetLastError()); + } + } + } else { + if(glCaps.getGLProfile().isGL3()) { + WGL.wglMakeCurrent(0, 0); + WGL.wglDeleteContext(temp_ctx); + throw new GLException("WindowsWGLContext.createContext failed, but context > GL2 requested "+getGLVersion(major[0], minor[0], ctp[0], "@creation")+", "); + } + if(DEBUG) { + System.err.println("WindowsWGLContext.createContext failed, fall back to !ARB context "+getGLVersion(major[0], minor[0], ctp[0], "@creation")); + } + + // continue with temp context for GL < 3.0 + contextHandle = temp_ctx; + 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 (DEBUG) { + System.err.println(getThreadName() + ": createImpl: OK (old) share "+share); + } + } + + if(0!=share) { + if (!WGL.wglShareLists(share, contextHandle)) { + throw new GLException("wglShareLists(" + toHexString(share) + + ", " + toHexString(contextHandle) + ") failed: werr " + GDI.GetLastError()); + } + } + return true; + } + + protected void makeCurrentImpl(boolean newCreated) 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); + } else { + if (DEBUG && newCreated) { + System.err.println(getThreadName() + ": wglMakeCurrent(hdc " + toHexString(drawable.getHandle()) + + ", contextHandle " + toHexString(contextHandle) + ") succeeded"); + } + } + } + } + + protected void releaseImpl() throws GLException { + if (!wglMakeContextCurrent(0, 0, 0)) { + throw new GLException("Error freeing OpenGL context, werr: " + GDI.GetLastError()); + } + } + + protected void destroyImpl() throws GLException { + WGL.wglMakeCurrent(0, 0); + if (!WGL.wglDeleteContext(contextHandle)) { + throw new GLException("Unable to delete OpenGL context"); + } + } + + protected void copyImpl(GLContext source, int mask) throws GLException { + if (!WGL.wglCopyContext(source.getHandle(), getHandle(), mask)) { + throw new GLException("wglCopyContext failed"); + } + } + + protected final void updateGLXProcAddressTable() { + AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice(); + String key = adevice.getUniqueID(); + if (DEBUG) { + System.err.println(getThreadName() + ": !!! Initializing WGL extension address table: "+key); + } + wglGetExtensionsStringEXTInitialized=false; + wglGetExtensionsStringEXTAvailable=false; + wglGLReadDrawableAvailableSet=false; + wglGLReadDrawableAvailable=false; + + WGLExtProcAddressTable table = null; + synchronized(mappedContextTypeObjectLock) { + table = (WGLExtProcAddressTable) mappedGLXProcAddress.get( key ); + } + if(null != table) { + wglExtProcAddressTable = table; + if(DEBUG) { + System.err.println(getThreadName() + ": !!! GLContext WGL ProcAddressTable reusing key("+key+") -> "+table.hashCode()); + } + } else { + if (wglExtProcAddressTable == null) { + // FIXME: cache ProcAddressTables by OpenGL context type bits so we can + // share them among contexts classes (GL4, GL4bc, GL3, GL3bc, ..) + wglExtProcAddressTable = new WGLExtProcAddressTable(new GLProcAddressResolver()); + } + resetProcAddressTable(wglExtProcAddressTable); + synchronized(mappedContextTypeObjectLock) { + mappedGLXProcAddress.put(key, getWGLExtProcAddressTable()); + if(DEBUG) { + System.err.println(getThreadName() + ": !!! GLContext WGL ProcAddressTable mapping key("+key+") -> "+getWGLExtProcAddressTable().hashCode()); + } + } + } + } + + public String getPlatformExtensionsString() { + if (!wglGetExtensionsStringEXTInitialized) { + wglGetExtensionsStringEXTAvailable = (WGL.wglGetProcAddress("wglGetExtensionsStringEXT") != 0); + wglGetExtensionsStringEXTInitialized = true; + } + if (wglGetExtensionsStringEXTAvailable) { + return getWGLExt().wglGetExtensionsStringEXT(); + } else { + return ""; + } + } + + protected void setSwapIntervalImpl(int interval) { + WGLExt wglExt = getWGLExt(); + if (wglExt.isExtensionAvailable("WGL_EXT_swap_control")) { + if ( wglExt.wglSwapIntervalEXT(interval) ) { + currentSwapInterval = interval ; + } + } + } + + 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"); + } + + public void bindPbufferToTexture() { + throw new GLException("Should not call this"); + } + + public void releasePbufferFromTexture() { + throw new GLException("Should not call this"); + } + +} |