diff options
Diffstat (limited to 'src/nativewindow/classes/jogamp')
7 files changed, 227 insertions, 39 deletions
diff --git a/src/nativewindow/classes/jogamp/nativewindow/BcmVCArtifacts.java b/src/nativewindow/classes/jogamp/nativewindow/BcmVCArtifacts.java new file mode 100644 index 000000000..216c55a3a --- /dev/null +++ b/src/nativewindow/classes/jogamp/nativewindow/BcmVCArtifacts.java @@ -0,0 +1,76 @@ +/** + * Copyright 2018 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package jogamp.nativewindow; + +import java.io.File; +import java.security.AccessController; +import java.security.PrivilegedAction; + +/** + * Heuristics about Broadcom (BCM) VideoCore (VC) existence and usage + */ +public class BcmVCArtifacts { + static final boolean hasVCLib; + static final boolean hasVC4ModLocation; + static final boolean hasDriCard0File; + + static { + final File vcLibLocation = new File( + "/opt/vc/lib/libbcm_host.so"); + final File vc4ModLocation = new File( + "/sys/module/vc4"); + final File driCard0Location = new File( + "/dev/dri/card0"); + final boolean[] res = new boolean [3]; + AccessController.doPrivileged(new PrivilegedAction<Object>() { + @Override + public Object run() { + res[0] = vcLibLocation.isFile(); + res[1] = vc4ModLocation.isDirectory(); + res[2] = driCard0Location.isFile(); + return null; + } } ); + hasVCLib = res[0]; + hasVC4ModLocation = res[1]; + hasDriCard0File = res[2]; + } + + /** + * @return True if proprietary BCM VC IV is probably being present + */ + public static final boolean guessVCIVPresent() { + return hasVCLib; + } + /** + * @return True if proprietary BCM VC IV is probably being used and not Xorg drivers + */ + public static final boolean guessVCIVUsed() { + return hasVCLib && !hasVC4ModLocation && !hasDriCard0File; + } +} diff --git a/src/nativewindow/classes/jogamp/nativewindow/NWJNILibLoader.java b/src/nativewindow/classes/jogamp/nativewindow/NWJNILibLoader.java index 8d0d04161..1284974bf 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/NWJNILibLoader.java +++ b/src/nativewindow/classes/jogamp/nativewindow/NWJNILibLoader.java @@ -43,7 +43,7 @@ public class NWJNILibLoader extends JNILibLoaderBase { public Boolean run() { Platform.initSingleton(); final String libName = "nativewindow_"+ossuffix ; - if(TempJarCache.isInitialized() && null == TempJarCache.findLibrary(libName)) { + if( TempJarCache.isInitialized(true) && null == TempJarCache.findLibrary(libName) ) { JNILibLoaderBase.addNativeJarLibsJoglCfg(new Class<?>[] { jogamp.nativewindow.Debug.class }); } return Boolean.valueOf(loadLibrary(libName, false, NWJNILibLoader.class.getClassLoader())); diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java index 264bdf9d3..5a0c8a79a 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java +++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java @@ -101,14 +101,15 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface { OSXUtil.RunOnMainThread(false, true /* kickNSApp */, new Runnable() { @Override public void run() { + if( 0 != jawtSurfaceLayersHandle) { + // null rootSurfaceLayer OK + UnsetJAWTRootSurfaceLayer0(jawtSurfaceLayersHandle, rootSurfaceLayer); + } + jawtSurfaceLayersHandle = 0; if( 0 != rootSurfaceLayer ) { - if( 0 != jawtSurfaceLayersHandle) { - UnsetJAWTRootSurfaceLayer0(jawtSurfaceLayersHandle, rootSurfaceLayer); - } OSXUtil.DestroyCALayer(rootSurfaceLayer); rootSurfaceLayer = 0; } - jawtSurfaceLayersHandle = 0; } }); } diff --git a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java index 8ad089a56..b1bf248ce 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java +++ b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java @@ -31,9 +31,9 @@ import com.jogamp.nativewindow.NativeWindowException; import com.jogamp.nativewindow.NativeWindowFactory; import com.jogamp.nativewindow.util.Insets; import com.jogamp.nativewindow.util.Point; - import com.jogamp.common.util.Function; import com.jogamp.common.util.FunctionTask; +import com.jogamp.common.util.InterruptedRuntimeException; import com.jogamp.common.util.RunnableTask; import jogamp.nativewindow.Debug; @@ -123,10 +123,16 @@ public class OSXUtil implements ToolkitProperties { } public static long CreateNSWindow(final int x, final int y, final int width, final int height) { - return CreateNSWindow0(x, y, width, height); + final long res[] = { 0 }; + RunOnMainThread(true, false /* kickNSApp */, new Runnable() { + @Override + public void run() { + res[0] = CreateNSWindow0(x, y, width, height); + } } ); + return res[0]; } public static void DestroyNSWindow(final long nsWindow) { - DestroyNSWindow0(nsWindow); + DestroyNSWindow0(nsWindow); } public static long GetNSView(final long nsWindow) { return GetNSView0(nsWindow); @@ -267,22 +273,21 @@ public class OSXUtil implements ToolkitProperties { } else { // Utilize Java side lock/wait and simply pass the Runnable async to OSX main thread, // otherwise we may freeze the OSX main thread. - Throwable throwable = null; final Object sync = new Object(); final RunnableTask rt = new RunnableTask( runnable, waitUntilDone ? sync : null, true, waitUntilDone ? null : System.err ); synchronized(sync) { RunOnMainThread0(kickNSApp, rt); if( waitUntilDone ) { - try { - sync.wait(); - } catch (final InterruptedException ie) { - throwable = ie; - } - if(null==throwable) { - throwable = rt.getThrowable(); - } - if(null!=throwable) { - throw new RuntimeException(throwable); + while( rt.isInQueue() ) { + try { + sync.wait(); + } catch (final InterruptedException ie) { + throw new InterruptedRuntimeException(ie); + } + final Throwable throwable = rt.getThrowable(); + if(null!=throwable) { + throw new RuntimeException(throwable); + } } } } @@ -341,23 +346,22 @@ public class OSXUtil implements ToolkitProperties { } else { // Utilize Java side lock/wait and simply pass the Runnable async to OSX main thread, // otherwise we may freeze the OSX main thread. - Throwable throwable = null; final Object sync = new Object(); final FunctionTask<R,A> rt = new FunctionTask<R,A>( func, waitUntilDone ? sync : null, true, waitUntilDone ? null : System.err ); synchronized(sync) { rt.setArgs(args); RunOnMainThread0(kickNSApp, rt); if( waitUntilDone ) { - try { - sync.wait(); - } catch (final InterruptedException ie) { - throwable = ie; - } - if(null==throwable) { - throwable = rt.getThrowable(); - } - if(null!=throwable) { - throw new RuntimeException(throwable); + while( rt.isInQueue() ) { + try { + sync.wait(); + } catch (final InterruptedException ie) { + throw new InterruptedRuntimeException(ie); + } + final Throwable throwable = rt.getThrowable(); + if(null!=throwable) { + throw new RuntimeException(throwable); + } } } } diff --git a/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java b/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java index bdf9630af..c0f277f09 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java +++ b/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java @@ -32,6 +32,8 @@ import com.jogamp.nativewindow.NativeWindowException; import com.jogamp.nativewindow.NativeWindowFactory; import com.jogamp.common.ExceptionUtils; +import com.jogamp.common.os.Platform; +import com.jogamp.common.util.VersionNumber; import jogamp.nativewindow.NWJNILibLoader; import jogamp.nativewindow.Debug; @@ -122,6 +124,107 @@ public class GDIUtil implements ToolkitProperties { return (Point) GetRelativeLocation0(src_win, dest_win, src_x, src_y); } + /** + * Windows >= 8, even if not manifested + * @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms724832%28v=vs.85%29.aspx + */ + public static final VersionNumber Win8Version = new VersionNumber(6, 2, 0); + + /** + * Windows >= 10, manifested + * @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms724832%28v=vs.85%29.aspx + */ + public static final VersionNumber Win10Version = new VersionNumber(10, 0, 0); + + /** + * Wrapper for {@link GDI#DwmIsCompositionEnabled()} + * taking the Windows 8 version into account. + * <p> + * If Windows version >= {@link #Win8Version} method always returns {@code true}, + * otherwise value of {@link GDI#DwmIsCompositionEnabled()} is returned. + * </p> + * @see https://msdn.microsoft.com/en-us/library/windows/desktop/aa969518%28v=vs.85%29.aspx + */ + public static boolean DwmIsCompositionEnabled() { + final VersionNumber winVer = Platform.getOSVersionNumber(); + if( winVer.compareTo(Win8Version) >= 0 ) { + return true; + } else { + return GDI.DwmIsCompositionEnabled(); + } + } + + public static boolean DwmSetupTranslucency(final long hwnd, final boolean enable) { + if( !GDI.DwmIsExtensionAvailable() ) { + if(DEBUG) { + System.err.println("GDIUtil.DwmSetupTranslucency on wnd 0x"+Long.toHexString(hwnd)+": enable "+enable+" -> failed, extension not available"); + } + return !enable; + } + final VersionNumber winVer = Platform.getOSVersionNumber(); + final boolean isWin8 = winVer.compareTo(Win8Version) >= 0; + if( !isWin8 && !GDI.DwmIsCompositionEnabled() ) { + if(DEBUG) { + System.err.println("GDIUtil.DwmSetupTranslucency on wnd 0x"+Long.toHexString(hwnd)+": enable "+enable+" -> failed, composition disabled"); + } + return !enable; + } + final boolean hasWinCompEXT = GDI.IsWindowCompositionExtensionAvailable(); + final boolean useWinCompEXT = isWin8 && hasWinCompEXT; + final boolean isUndecorated = IsUndecorated(hwnd); + boolean ok; + if( useWinCompEXT && !isUndecorated ) { + final AccentPolicy accentPolicy = AccentPolicy.create(); + if( enable ) { + // For undecorated windows, this would also enable the Glass effect! + accentPolicy.setAccentState(GDI.ACCENT_ENABLE_BLURBEHIND); + } else { + accentPolicy.setAccentState(GDI.ACCENT_DISABLED); + } + ok = GDI.SetWindowCompositionAccentPolicy(hwnd, accentPolicy); + } else { + // Works even for >= Win8, if undecorated + final DWM_BLURBEHIND bb = DWM_BLURBEHIND.create(); + final int dwFlags = enable ? GDI.DWM_BB_ENABLE | GDI.DWM_BB_BLURREGION | GDI.DWM_BB_TRANSITIONONMAXIMIZED : GDI.DWM_BB_ENABLE; + // final int dwFlags = GDI.DWM_BB_ENABLE; + bb.setDwFlags( dwFlags ); + bb.setFEnable( enable ? 1 : 0 ); + bb.setHRgnBlur(0); + bb.setFTransitionOnMaximized(1); + ok = GDI.DwmEnableBlurBehindWindow(hwnd, bb); + if( ok ) { + final MARGINS m = MARGINS.create(); + m.setCxLeftWidth(-1); + m.setCxRightWidth(-1); + m.setCyBottomHeight(-1); + m.setCyTopHeight(-1); + ok = GDI.DwmExtendFrameIntoClientArea(hwnd, m); + } + } + /*** + * Not required .. + * + if( ok && isWin8 && !isUndecorated ) { + final IntBuffer pvAttribute = Buffers.newDirectIntBuffer(1); + if( enable ) { + // Glass Effect even if undecorated, hence not truly 100% translucent! + pvAttribute.put(0, GDI.DWMNCRP_ENABLED); + } else { + pvAttribute.put(0, GDI.DWMNCRP_DISABLED); + } + final int err = GDI.DwmSetWindowAttribute(hwnd, GDI.DWMWA_NCRENDERING_POLICY, + pvAttribute, + Buffers.sizeOfBufferElem(pvAttribute)*pvAttribute.capacity()); + ok = 0 == err; // S_OK + } */ + if(DEBUG) { + final boolean isChild = IsChild(hwnd); + System.err.println("GDIUtil.DwmSetupTranslucency on wnd 0x"+Long.toHexString(hwnd)+": enable "+enable+", isUndecorated "+isUndecorated+", isChild "+isChild+ + ", version "+winVer+", isWin8 "+isWin8+", hasWinCompEXT "+hasWinCompEXT+", useWinCompEXT "+useWinCompEXT+" -> ok: "+ok); + } + return ok; + } + public static boolean IsUndecorated(final long win) { return IsUndecorated0(win); } diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/X11GraphicsConfigurationFactory.java b/src/nativewindow/classes/jogamp/nativewindow/x11/X11GraphicsConfigurationFactory.java index f8a11f91e..4257376a0 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/x11/X11GraphicsConfigurationFactory.java +++ b/src/nativewindow/classes/jogamp/nativewindow/x11/X11GraphicsConfigurationFactory.java @@ -42,6 +42,7 @@ import com.jogamp.nativewindow.NativeWindowException; import com.jogamp.nativewindow.VisualIDHolder; import com.jogamp.nativewindow.x11.X11GraphicsConfiguration; +import com.jogamp.nativewindow.x11.X11GraphicsDevice; import com.jogamp.nativewindow.x11.X11GraphicsScreen; public class X11GraphicsConfigurationFactory extends GraphicsConfigurationFactory { @@ -59,15 +60,17 @@ public class X11GraphicsConfigurationFactory extends GraphicsConfigurationFactor if(!(screen instanceof X11GraphicsScreen)) { throw new NativeWindowException("Only valid X11GraphicsScreen are allowed"); } - final X11Capabilities x11CapsChosen; + final XVisualInfo x11VisualInfo; if(VisualIDHolder.VID_UNDEFINED == nativeVisualID) { - x11CapsChosen = new X11Capabilities(getXVisualInfo(screen, capsChosen)); + x11VisualInfo = getXVisualInfo(screen, capsChosen); } else { - x11CapsChosen = new X11Capabilities(getXVisualInfo(screen, nativeVisualID)); + x11VisualInfo = getXVisualInfo(screen, nativeVisualID); } + + final X11Capabilities x11CapsChosen = X11GraphicsConfiguration.XVisualInfo2X11Capabilities((X11GraphicsDevice)screen.getDevice(), x11VisualInfo); final AbstractGraphicsConfiguration res = new X11GraphicsConfiguration((X11GraphicsScreen)screen, x11CapsChosen, capsRequested, x11CapsChosen.getXVisualInfo()); if(DEBUG) { - System.err.println("X11GraphicsConfigurationFactory.chooseGraphicsConfigurationImpl(visualID 0x"+Integer.toHexString(nativeVisualID)+", "+screen+","+capsChosen+"): "+res); + System.err.println("X11GraphicsConfigurationFactory.chooseGraphicsConfigurationImpl(visualID 0x"+Integer.toHexString(nativeVisualID)+", "+x11VisualInfo+", "+screen+","+capsChosen+"): "+res); } return res; } @@ -85,7 +88,6 @@ public class X11GraphicsConfigurationFactory extends GraphicsConfigurationFactor if(xvis==null || num[0]<1) { return null; } - return XVisualInfo.create(xvis[0]); } diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java index e59ff2ea8..6af5467f0 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java +++ b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java @@ -463,10 +463,12 @@ public class X11Util implements ToolkitProperties { if(markAllDisplaysUnclosable) { namedDpy.setUncloseable(true); } - } - if(DEBUG) { - System.err.println("X11Util.Display: openDisplay [reuse "+reused+"] "+namedDpy+". Thread "+Thread.currentThread().getName()); - // Thread.dumpStack(); + if(DEBUG) { + System.err.println("X11Util.Display: openDisplay [reuse "+reused+"] "+namedDpy+ + ". Open[reuseable "+reusableDisplayList.size()+", pending "+pendingDisplayList.size()+ + "]. Thread "+Thread.currentThread().getName()); + // Thread.dumpStack(); + } } return namedDpy.getHandle(); } |