/** * Cleanup resources. * * <p>Called by {@link NativeWindowFactory#shutdown()} * * @see ToolkitProperties */ public static void shutdown() { if (isInit) { synchronized (X11Util.class) { if (isInit) { final boolean isJVMShuttingDown = NativeWindowFactory.isJVMShuttingDown(); if (DEBUG || ((openDisplayMap.size() > 0 || reusableDisplayList.size() > 0 || pendingDisplayList.size() > 0) && (reusableDisplayList.size() != pendingDisplayList.size() || !markAllDisplaysUnclosable))) { System.err.println( "X11Util.Display: Shutdown (JVM shutdown: " + isJVMShuttingDown + ", open (no close attempt): " + openDisplayMap.size() + "/" + openDisplayList.size() + ", reusable (open, marked uncloseable): " + reusableDisplayList.size() + ", pending (open in creation order): " + pendingDisplayList.size() + ")"); if (DEBUG) { Thread.dumpStack(); } if (openDisplayList.size() > 0) { X11Util.dumpOpenDisplayConnections(); } if (DEBUG) { if (reusableDisplayList.size() > 0 || pendingDisplayList.size() > 0) { X11Util.dumpPendingDisplayConnections(); } } } // Only at JVM shutdown time, since AWT impl. seems to // dislike closing of X11 Display's (w/ ATI driver). if (isJVMShuttingDown) { synchronized (globalLock) { isInit = false; closePendingDisplayConnections(); openDisplayList.clear(); reusableDisplayList.clear(); pendingDisplayList.clear(); openDisplayMap.clear(); displayXineramaEnabledMap.clear(); shutdown0(); } } } } } }
protected static X11GLXGraphicsConfiguration createDefaultGraphicsConfiguration( AbstractGraphicsScreen absScreen, boolean onscreen, boolean usePBuffer) { if (absScreen == null) { throw new IllegalArgumentException("AbstractGraphicsScreen is null"); } if (!(absScreen instanceof X11GraphicsScreen)) { throw new IllegalArgumentException("Only X11GraphicsScreen are allowed here"); } X11GraphicsScreen x11Screen = (X11GraphicsScreen) absScreen; GLProfile glProfile = GLProfile.getDefault(); GLCapabilities caps = null; XVisualInfo xvis = null; long fbcfg = 0; int fbid = -1; // Utilizing FBConfig // GLCapabilities capsFB = null; long display = x11Screen.getDevice().getHandle(); try { NativeWindowFactory.getDefaultFactory().getToolkitLock().lock(); X11Lib.XLockDisplay(display); int screen = x11Screen.getIndex(); boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display); long visID = X11Lib.DefaultVisualID(display, x11Screen.getIndex()); xvis = X11GLXGraphicsConfiguration.XVisualID2XVisualInfo(display, visID); caps = X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities( glProfile, display, xvis, onscreen, usePBuffer, isMultisampleAvailable); int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList( caps, true, isMultisampleAvailable, display, screen); int[] count = {-1}; PointerBuffer fbcfgsL = GLX.glXChooseFBConfigCopied(display, screen, attribs, 0, count, 0); if (fbcfgsL == null || fbcfgsL.limit() < 1) { throw new Exception("Could not fetch FBConfig for " + caps); } fbcfg = fbcfgsL.get(0); capsFB = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities( glProfile, display, fbcfg, true, onscreen, usePBuffer, isMultisampleAvailable); fbid = X11GLXGraphicsConfiguration.glXFBConfig2FBConfigID(display, fbcfg); xvis = GLX.glXGetVisualFromFBConfigCopied(display, fbcfg); if (xvis == null) { throw new GLException("Error: Choosen FBConfig has no visual"); } } catch (Throwable t) { } finally { X11Lib.XUnlockDisplay(display); NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock(); } return new X11GLXGraphicsConfiguration( x11Screen, (null != capsFB) ? capsFB : caps, caps, null, xvis, fbcfg, fbid); }
static { NativeWindowFactory.initSingleton(); NEWTJNILibLoader.loadNEWT(); HINT_USE_MAIN_THREAD = !NativeWindowFactory.isAWTAvailable() || Debug.getBooleanProperty("newt.MainThread.force", true); osType = Platform.getOSType(); isMacOSX = osType == Platform.OSType.MACOS; rootThreadGroup = getRootThreadGroup(); }
public boolean isCurrentThreadEDT() { if (NativeWindowFactory.isAWTAvailable()) { initAWTReflection(); return ((Boolean) ReflectionUtil.callMethod(null, mAWTIsDispatchThread, null)).booleanValue(); } return isRunning() && mainThread == Thread.currentThread(); }
@Override public synchronized void setVisibleActionPost(boolean visible, boolean nativeWindowCreated) { long t0; if (Window.DEBUG_IMPLEMENTATION) { t0 = System.nanoTime(); System.err.println( "GLWindow.setVisibleActionPost(" + visible + ", " + nativeWindowCreated + ") " + WindowImpl.getThreadName() + ", start"); } else { t0 = 0; } /* if (nativeWindowCreated && null != context) { throw new GLException("InternalError: Native Windows has been just created, but context wasn't destroyed (is not null)"); } */ if (null == context && visible && 0 != window.getWindowHandle() && 0 < getWidth() * getHeight()) { NativeWindow nw; if (window.getWrappedWindow() != null) { nw = NativeWindowFactory.getNativeWindow( window.getWrappedWindow(), window.getPrivateGraphicsConfiguration()); } else { nw = window; } GLCapabilitiesImmutable glCaps = (GLCapabilitiesImmutable) nw.getGraphicsConfiguration().getChosenCapabilities(); if (null == factory) { factory = GLDrawableFactory.getFactory(glCaps.getGLProfile()); } if (null == drawable) { drawable = (GLDrawableImpl) factory.createGLDrawable(nw); } drawable.setRealized(true); context = (GLContextImpl) drawable.createContext(sharedContext); context.setContextCreationFlags(additionalCtxCreationFlags); } if (Window.DEBUG_IMPLEMENTATION) { System.err.println( "GLWindow.setVisibleActionPost(" + visible + ", " + nativeWindowCreated + ") " + WindowImpl.getThreadName() + ", fin: dt " + (System.nanoTime() - t0) / 1e6 + "ms"); } }
/** invokes the given Runnable */ public void invoke(boolean wait, Runnable r) { if (r == null) { return; } if (NativeWindowFactory.isAWTAvailable()) { initAWTReflection(); // handover to AWT MainThread .. try { if (((Boolean) ReflectionUtil.callMethod(null, mAWTIsDispatchThread, null)) .booleanValue()) { r.run(); return; } if (wait) { ReflectionUtil.callMethod(null, mAWTInvokeAndWait, new Object[] {r}); } else { ReflectionUtil.callMethod(null, mAWTInvokeLater, new Object[] {r}); } } catch (Exception e) { throw new NativeWindowException(e); } return; } // if this main thread is not being used or // if this is already the main thread .. just execute. if (!isRunning() || mainThread == Thread.currentThread()) { r.run(); return; } boolean doWait = wait && isRunning() && mainThread != Thread.currentThread(); Object lock = new Object(); RunnableTask rTask = new RunnableTask(r, doWait ? lock : null, true); Throwable throwable = null; synchronized (lock) { invokeLater(rTask); if (doWait) { try { lock.wait(); } catch (InterruptedException ie) { throwable = ie; } } } if (null == throwable) { throwable = rTask.getThrowable(); } if (null != throwable) { throw new RuntimeException(throwable); } }
/** Your new java application main entry, which pipelines your application */ public static void main(String[] args) { useMainThread = MAIN_THREAD_CRITERIA; if (DEBUG) System.err.println( "MainThread.main(): " + Thread.currentThread().getName() + " useMainThread " + useMainThread); if (args.length == 0) { return; } String mainClassName = args[0]; String[] mainClassArgs = new String[args.length - 1]; if (args.length > 1) { System.arraycopy(args, 1, mainClassArgs, 0, args.length - 1); } NEWTJNILibLoader.loadNEWT(); mainAction = new MainAction(mainClassName, mainClassArgs); if (NativeWindowFactory.TYPE_MACOSX.equals(NativeWindowFactory.getNativeWindowType(false))) { ReflectionUtil.callStaticMethod( "com.jogamp.newt.impl.macosx.MacDisplay", "initSingleton", null, null, MainThread.class.getClassLoader()); } if (useMainThread) { shouldStop = false; tasks = new ArrayList(); mainThread = Thread.currentThread(); // dispatch user's main thread .. mainAction.start(); // do our main thread task scheduling singletonMainThread.run(); } else { // run user's main in this thread mainAction.run(); } }
private static void shutdownImpl() { // Following code will _always_ remain in shutdown hook // due to special semantics of native utils, i.e. X11Utils. // The latter requires shutdown at JVM-Shutdown only. synchronized (glDrawableFactories) { for (int i = 0; i < glDrawableFactories.size(); i++) { glDrawableFactories.get(i).destroy(); } glDrawableFactories.clear(); // both were members of glDrawableFactories and are shutdown already nativeOSFactory = null; eglFactory = null; } GLContext.shutdown(); NativeWindowFactory.shutdown(isJVMShuttingDown); }
private static final void initSingletonImpl() { registerFactoryShutdownHook(); final String nwt = NativeWindowFactory.getNativeWindowType(true); GLDrawableFactory tmp = null; String factoryClassName = Debug.getProperty("jogl.gldrawablefactory.class.name", true); ClassLoader cl = GLDrawableFactory.class.getClassLoader(); if (null == factoryClassName) { if (nwt == NativeWindowFactory.TYPE_X11) { factoryClassName = "jogamp.opengl.x11.glx.X11GLXDrawableFactory"; } else if (nwt == NativeWindowFactory.TYPE_WINDOWS) { factoryClassName = "jogamp.opengl.windows.wgl.WindowsWGLDrawableFactory"; } else if (nwt == NativeWindowFactory.TYPE_MACOSX) { if (ReflectionUtil.isClassAvailable(macosxFactoryClassNameAWTCGL, cl)) { factoryClassName = macosxFactoryClassNameAWTCGL; } else { factoryClassName = macosxFactoryClassNameCGL; } } else { // may use egl*Factory .. if (DEBUG || GLProfile.DEBUG) { System.err.println( "GLDrawableFactory.static - No native Windowing Factory for: " + nwt + "; May use EGLDrawableFactory, if available."); } } } if (null != factoryClassName) { if (DEBUG || GLProfile.DEBUG) { System.err.println( "GLDrawableFactory.static - Native OS Factory for: " + nwt + ": " + factoryClassName); } try { tmp = (GLDrawableFactory) ReflectionUtil.createInstance(factoryClassName, cl); } catch (JogampRuntimeException jre) { if (DEBUG || GLProfile.DEBUG) { System.err.println( "Info: GLDrawableFactory.static - Native Platform: " + nwt + " - not available: " + factoryClassName); jre.printStackTrace(); } } } if (null != tmp && tmp.isComplete()) { nativeOSFactory = tmp; } tmp = null; if (!disableOpenGLES) { try { tmp = (GLDrawableFactory) ReflectionUtil.createInstance("jogamp.opengl.egl.EGLDrawableFactory", cl); } catch (JogampRuntimeException jre) { if (DEBUG || GLProfile.DEBUG) { System.err.println("Info: GLDrawableFactory.static - EGLDrawableFactory - not available"); jre.printStackTrace(); } } if (null != tmp && tmp.isComplete()) { eglFactory = tmp; } } else if (DEBUG || GLProfile.DEBUG) { System.err.println("Info: GLDrawableFactory.static - EGLDrawableFactory - disabled!"); } }
/** * NEWT Utility class MainThread * * <p>This class provides a startup singleton <i>main thread</i>, from which a new thread with the * users main class is launched.<br> * Such behavior is necessary for native windowing toolkits, where the windowing management must * happen on the so called <i>main thread</i> e.g. for Mac OS X !<br> * Utilizing this class as a launchpad, now you are able to use a NEWT multithreaded application * with window handling within the different threads, even on these restricted platforms.<br> * To support your NEWT Window platform, you have to pass your <i>main thread</i> actions to {@link * #invoke invoke(..)}, have a look at the {@link com.jogamp.newt.macosx.MacWindow MacWindow} * implementation.<br> * <i>TODO</i>: Some hardcoded dependencies exist in this implementation, where you have to patch * this code or factor it out. * * <p>If your platform is not Mac OS X, but you want to test your code without modifying this class, * you have to set the system property <code>newt.MainThread.force</code> to <code>true</code>. * * <p>The code is compatible with all other platform, which support multithreaded windowing * handling. Since those platforms won't trigger the <i>main thread</i> serialization, the main * method will be simply executed, in case you haven't set <code>newt.MainThread.force</code> to * <code>true</code>. * * <p>Test case on Mac OS X (or any other platform): * * <PRE> * java -XstartOnFirstThread com.jogamp.newt.util.MainThread demos.es1.RedSquare -GL2 -GL2 -GL2 -GL2 * </PRE> * * Which starts 4 threads, each with a window and OpenGL rendering.<br> */ public class MainThread implements EDTUtil { private static AccessControlContext localACC = AccessController.getContext(); public static final boolean MAIN_THREAD_CRITERIA = (!NativeWindowFactory.isAWTAvailable() && NativeWindowFactory.TYPE_MACOSX.equals( NativeWindowFactory.getNativeWindowType(false))) || Debug.getBooleanProperty("newt.MainThread.force", true, localACC); protected static final boolean DEBUG = Debug.debug("MainThread"); private static MainThread singletonMainThread = new MainThread(); // one singleton MainThread private static boolean isExit = false; private static volatile boolean isRunning = false; private static Object taskWorkerLock = new Object(); private static boolean shouldStop; private static ArrayList tasks; private static Thread mainThread; private static Timer pumpMessagesTimer = null; private static TimerTask pumpMessagesTimerTask = null; private static Map /*<Display, Runnable>*/ pumpMessageDisplayMap = new HashMap(); private static boolean useMainThread = false; private static Class cAWTEventQueue = null; private static Method mAWTInvokeAndWait = null; private static Method mAWTInvokeLater = null; private static Method mAWTIsDispatchThread = null; static class MainAction extends Thread { private String mainClassName; private String[] mainClassArgs; private Class mainClass; private Method mainClassMain; public MainAction(String mainClassName, String[] mainClassArgs) { this.mainClassName = mainClassName; this.mainClassArgs = mainClassArgs; } public void run() { if (useMainThread) { // we have to start first to provide the service .. singletonMainThread.waitUntilRunning(); } // start user app .. try { Class mainClass = ReflectionUtil.getClass(mainClassName, true, getClass().getClassLoader()); if (null == mainClass) { throw new RuntimeException( new ClassNotFoundException("MainThread couldn't find main class " + mainClassName)); } try { mainClassMain = mainClass.getDeclaredMethod("main", new Class[] {String[].class}); mainClassMain.setAccessible(true); } catch (Throwable t) { throw new RuntimeException(t); } if (DEBUG) System.err.println( "MainAction.run(): " + Thread.currentThread().getName() + " invoke " + mainClassName); mainClassMain.invoke(null, new Object[] {mainClassArgs}); } catch (InvocationTargetException ite) { ite.getTargetException().printStackTrace(); } catch (Throwable t) { t.printStackTrace(); } if (DEBUG) System.err.println( "MainAction.run(): " + Thread.currentThread().getName() + " user app fin"); if (useMainThread) { singletonMainThread.stop(); if (DEBUG) System.err.println( "MainAction.run(): " + Thread.currentThread().getName() + " MainThread fin - stop"); System.exit(0); } } } private static MainAction mainAction; /** Your new java application main entry, which pipelines your application */ public static void main(String[] args) { useMainThread = MAIN_THREAD_CRITERIA; if (DEBUG) System.err.println( "MainThread.main(): " + Thread.currentThread().getName() + " useMainThread " + useMainThread); if (args.length == 0) { return; } String mainClassName = args[0]; String[] mainClassArgs = new String[args.length - 1]; if (args.length > 1) { System.arraycopy(args, 1, mainClassArgs, 0, args.length - 1); } NEWTJNILibLoader.loadNEWT(); mainAction = new MainAction(mainClassName, mainClassArgs); if (NativeWindowFactory.TYPE_MACOSX.equals(NativeWindowFactory.getNativeWindowType(false))) { ReflectionUtil.callStaticMethod( "com.jogamp.newt.impl.macosx.MacDisplay", "initSingleton", null, null, MainThread.class.getClassLoader()); } if (useMainThread) { shouldStop = false; tasks = new ArrayList(); mainThread = Thread.currentThread(); // dispatch user's main thread .. mainAction.start(); // do our main thread task scheduling singletonMainThread.run(); } else { // run user's main in this thread mainAction.run(); } } public static final MainThread getSingleton() { return singletonMainThread; } public static Runnable removePumpMessage(Display dpy) { synchronized (pumpMessageDisplayMap) { return (Runnable) pumpMessageDisplayMap.remove(dpy); } } public static void addPumpMessage(Display dpy, Runnable pumpMessage) { if (useMainThread) { return; // error ? } if (null == pumpMessagesTimer) { synchronized (MainThread.class) { if (null == pumpMessagesTimer) { pumpMessagesTimer = new Timer(); pumpMessagesTimerTask = new TimerTask() { public void run() { synchronized (pumpMessageDisplayMap) { for (Iterator i = pumpMessageDisplayMap.values().iterator(); i.hasNext(); ) { ((Runnable) i.next()).run(); } } } }; pumpMessagesTimer.scheduleAtFixedRate( pumpMessagesTimerTask, 0, defaultEDTPollGranularity); } } } synchronized (pumpMessageDisplayMap) { pumpMessageDisplayMap.put(dpy, pumpMessage); } } private void initAWTReflection() { if (null == cAWTEventQueue) { ClassLoader cl = MainThread.class.getClassLoader(); cAWTEventQueue = ReflectionUtil.getClass("java.awt.EventQueue", true, cl); mAWTInvokeAndWait = ReflectionUtil.getMethod( cAWTEventQueue, "invokeAndWait", new Class[] {java.lang.Runnable.class}, cl); mAWTInvokeLater = ReflectionUtil.getMethod( cAWTEventQueue, "invokeLater", new Class[] {java.lang.Runnable.class}, cl); mAWTIsDispatchThread = ReflectionUtil.getMethod(cAWTEventQueue, "isDispatchThread", new Class[] {}, cl); } } public void start() { // nop } public void stop() { if (DEBUG) System.err.println("MainThread.stop(): " + Thread.currentThread().getName() + " start"); synchronized (taskWorkerLock) { if (isRunning) { shouldStop = true; } taskWorkerLock.notifyAll(); } if (DEBUG) System.err.println("MainThread.stop(): " + Thread.currentThread().getName() + " end"); } public boolean isCurrentThreadEDT() { if (NativeWindowFactory.isAWTAvailable()) { initAWTReflection(); return ((Boolean) ReflectionUtil.callMethod(null, mAWTIsDispatchThread, null)).booleanValue(); } return isRunning() && mainThread == Thread.currentThread(); } public boolean isRunning() { if (useMainThread) { synchronized (taskWorkerLock) { return isRunning; } } return true; // AWT is always running } private void invokeLater(Runnable task) { synchronized (taskWorkerLock) { if (isRunning() && mainThread != Thread.currentThread()) { tasks.add(task); taskWorkerLock.notifyAll(); } else { // if !running or isEDTThread, do it right away task.run(); } } } /** invokes the given Runnable */ public void invoke(boolean wait, Runnable r) { if (r == null) { return; } if (NativeWindowFactory.isAWTAvailable()) { initAWTReflection(); // handover to AWT MainThread .. try { if (((Boolean) ReflectionUtil.callMethod(null, mAWTIsDispatchThread, null)) .booleanValue()) { r.run(); return; } if (wait) { ReflectionUtil.callMethod(null, mAWTInvokeAndWait, new Object[] {r}); } else { ReflectionUtil.callMethod(null, mAWTInvokeLater, new Object[] {r}); } } catch (Exception e) { throw new NativeWindowException(e); } return; } // if this main thread is not being used or // if this is already the main thread .. just execute. if (!isRunning() || mainThread == Thread.currentThread()) { r.run(); return; } boolean doWait = wait && isRunning() && mainThread != Thread.currentThread(); Object lock = new Object(); RunnableTask rTask = new RunnableTask(r, doWait ? lock : null, true); Throwable throwable = null; synchronized (lock) { invokeLater(rTask); if (doWait) { try { lock.wait(); } catch (InterruptedException ie) { throwable = ie; } } } if (null == throwable) { throwable = rTask.getThrowable(); } if (null != throwable) { throw new RuntimeException(throwable); } } public void waitUntilIdle() {} public void waitUntilStopped() {} private void waitUntilRunning() { synchronized (taskWorkerLock) { if (isExit) return; while (!isRunning) { try { taskWorkerLock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } public void run() { if (DEBUG) System.err.println("MainThread.run(): " + Thread.currentThread().getName()); synchronized (taskWorkerLock) { isRunning = true; taskWorkerLock.notifyAll(); } while (!shouldStop) { try { // wait for something todo .. synchronized (taskWorkerLock) { while (!shouldStop && tasks.size() == 0) { try { taskWorkerLock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } // take over the tasks .. if (!shouldStop && tasks.size() > 0) { Runnable task = (Runnable) tasks.remove(0); task.run(); // FIXME: could be run outside of lock } taskWorkerLock.notifyAll(); } } catch (Throwable t) { // handle errors .. t.printStackTrace(); } finally { // epilog - unlock locked stuff } } if (DEBUG) System.err.println("MainThread.run(): " + Thread.currentThread().getName() + " fin"); synchronized (taskWorkerLock) { isRunning = false; isExit = true; taskWorkerLock.notifyAll(); } } }
protected static X11GLXGraphicsConfiguration chooseGraphicsConfigurationXVisual( GLCapabilities capabilities, GLCapabilitiesChooser chooser, X11GraphicsScreen x11Screen) { if (chooser == null) { chooser = new DefaultGLCapabilitiesChooser(); } // Until we have a rock-solid visual selection algorithm written // in pure Java, we're going to provide the underlying window // system's selection to the chooser as a hint GLProfile glProfile = capabilities.getGLProfile(); boolean onscreen = capabilities.isOnscreen(); GLCapabilities[] caps = null; int recommendedIndex = -1; XVisualInfo retXVisualInfo = null; int chosen = -1; AbstractGraphicsDevice absDevice = x11Screen.getDevice(); long display = absDevice.getHandle(); try { NativeWindowFactory.getDefaultFactory().getToolkitLock().lock(); X11Lib.XLockDisplay(display); int screen = x11Screen.getIndex(); boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display); int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList( capabilities, false, isMultisampleAvailable, display, screen); XVisualInfo[] infos = null; XVisualInfo recommendedVis = GLX.glXChooseVisualCopied(display, screen, attribs, 0); if (DEBUG) { System.err.print("!!! glXChooseVisual recommended "); if (recommendedVis == null) { System.err.println("null visual"); } else { System.err.println("visual id 0x" + Long.toHexString(recommendedVis.getVisualid())); } } int[] count = new int[1]; XVisualInfo template = XVisualInfo.create(); template.setScreen(screen); infos = X11Lib.XGetVisualInfoCopied(display, X11Lib.VisualScreenMask, template, count, 0); if (infos == null || infos.length < 1) { throw new GLException("Error while enumerating available XVisualInfos"); } caps = new GLCapabilities[infos.length]; for (int i = 0; i < infos.length; i++) { caps[i] = X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities( glProfile, display, infos[i], onscreen, false, isMultisampleAvailable); // Attempt to find the visual chosen by glXChooseVisual if (recommendedVis != null && recommendedVis.getVisualid() == infos[i].getVisualid()) { recommendedIndex = i; } } try { chosen = chooser.chooseCapabilities(capabilities, caps, recommendedIndex); } catch (NativeWindowException e) { if (DEBUG) { e.printStackTrace(); } chosen = -1; } if (chosen < 0) { // keep on going .. if (DEBUG) { System.err.println( "X11GLXGraphicsConfiguration.chooseGraphicsConfigurationXVisual Failed .. unable to choose config, using first"); } chosen = 0; // default .. } else if (chosen >= caps.length) { throw new GLException( "GLCapabilitiesChooser specified invalid index (expected 0.." + (caps.length - 1) + ")"); } if (infos[chosen] == null) { throw new GLException("GLCapabilitiesChooser chose an invalid visual"); } retXVisualInfo = XVisualInfo.create(infos[chosen]); } finally { X11Lib.XUnlockDisplay(display); NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock(); } return new X11GLXGraphicsConfiguration( x11Screen, caps[chosen], capabilities, chooser, retXVisualInfo, 0, -1); }
protected static X11GLXGraphicsConfiguration chooseGraphicsConfigurationFBConfig( GLCapabilities capabilities, GLCapabilitiesChooser chooser, X11GraphicsScreen x11Screen) { int recommendedIndex = -1; GLCapabilities[] caps = null; PointerBuffer fbcfgsL = null; int chosen = -1; int retFBID = -1; XVisualInfo retXVisualInfo = null; GLProfile glProfile = capabilities.getGLProfile(); boolean onscreen = capabilities.isOnscreen(); boolean usePBuffer = capabilities.isPBuffer(); // Utilizing FBConfig // AbstractGraphicsDevice absDevice = x11Screen.getDevice(); long display = absDevice.getHandle(); try { NativeWindowFactory.getDefaultFactory().getToolkitLock().lock(); X11Lib.XLockDisplay(display); int screen = x11Screen.getIndex(); boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display); int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList( capabilities, true, isMultisampleAvailable, display, screen); int[] count = {-1}; fbcfgsL = GLX.glXChooseFBConfigCopied(display, screen, attribs, 0, count, 0); if (fbcfgsL == null || fbcfgsL.limit() < 1) { if (DEBUG) { System.err.println( "X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed glXChooseFBConfig (" + x11Screen + "," + capabilities + "): " + fbcfgsL + ", " + count[0]); } return null; } if (!X11GLXGraphicsConfiguration.GLXFBConfigValid(display, fbcfgsL.get(0))) { if (DEBUG) { System.err.println( "X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed - GLX FBConfig invalid: (" + x11Screen + "," + capabilities + "): " + fbcfgsL + ", fbcfg: 0x" + Long.toHexString(fbcfgsL.get(0))); } return null; } recommendedIndex = 0; // 1st match is always recommended .. caps = new GLCapabilities[fbcfgsL.limit()]; for (int i = 0; i < fbcfgsL.limit(); i++) { caps[i] = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities( glProfile, display, fbcfgsL.get(i), false, onscreen, usePBuffer, isMultisampleAvailable); } if (null == chooser) { chosen = recommendedIndex; } else { try { chosen = chooser.chooseCapabilities(capabilities, caps, recommendedIndex); } catch (NativeWindowException e) { if (DEBUG) { e.printStackTrace(); } chosen = -1; } } if (chosen < 0) { // keep on going .. if (DEBUG) { System.err.println( "X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig Failed .. unable to choose config, using first"); } chosen = 0; // default .. } else if (chosen >= caps.length) { throw new GLException( "GLCapabilitiesChooser specified invalid index (expected 0.." + (caps.length - 1) + ")"); } retFBID = X11GLXGraphicsConfiguration.glXFBConfig2FBConfigID(display, fbcfgsL.get(chosen)); retXVisualInfo = GLX.glXGetVisualFromFBConfigCopied(display, fbcfgsL.get(chosen)); if (retXVisualInfo == null) { if (DEBUG) { System.err.println( "X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed glXGetVisualFromFBConfig (" + x11Screen + ", " + fbcfgsL.get(chosen) + " (Continue: " + (false == caps[chosen].isOnscreen()) + "):\n\t" + caps[chosen]); } if (caps[chosen].isOnscreen()) { // Onscreen drawables shall have a XVisual .. return null; } } } finally { X11Lib.XUnlockDisplay(display); NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock(); } return new X11GLXGraphicsConfiguration( x11Screen, caps[chosen], capabilities, chooser, retXVisualInfo, fbcfgsL.get(chosen), retFBID); }
private static AbstractGraphicsScreen cloneScreen(AbstractGraphicsScreen aScreen) { final AbstractGraphicsDevice aDevice2 = (AbstractGraphicsDevice) aScreen.getDevice().clone(); return NativeWindowFactory.createScreen(aDevice2, aScreen.getIndex()); }
public EGLDrawableFactory() { super(); // Register our GraphicsConfigurationFactory implementations // The act of constructing them causes them to be registered EGLGraphicsConfigurationFactory.registerFactory(); // Check for other underlying stuff .. if (NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(true)) { hasX11 = true; try { ReflectionUtil.createInstance( "jogamp.opengl.x11.glx.X11GLXGraphicsConfigurationFactory", EGLDrawableFactory.class.getClassLoader()); } catch (Exception jre) { /* n/a .. */ } } // FIXME: Probably need to move EGL from a static model // to a dynamic one, where there can be 2 instances // for each ES profile with their own ProcAddressTable. synchronized (EGLDrawableFactory.class) { final boolean hasDesktopES2 = null != eglES2DynamicLookupHelper; if (!hasDesktopES2 && null == eglES1DynamicLookupHelper) { GLDynamicLookupHelper tmp = null; try { tmp = new GLDynamicLookupHelper(new EGLES1DynamicLibraryBundleInfo()); } catch (GLException gle) { if (DEBUG) { gle.printStackTrace(); } } if (null != tmp && tmp.isLibComplete()) { eglES1DynamicLookupHelper = tmp; EGL.resetProcAddressTable(eglES1DynamicLookupHelper); final boolean isANGLEES1 = isANGLE(eglES1DynamicLookupHelper); isANGLE |= isANGLEES1; if (DEBUG || GLProfile.DEBUG) { System.err.println("Info: EGLDrawableFactory: EGL ES1 - OK, isANGLE: " + isANGLEES1); } } else if (DEBUG || GLProfile.DEBUG) { System.err.println("Info: EGLDrawableFactory: EGL ES1 - NOPE (ES1 lib)"); } } if (!hasDesktopES2 && null == eglES2DynamicLookupHelper) { GLDynamicLookupHelper tmp = null; try { tmp = new GLDynamicLookupHelper(new EGLES2DynamicLibraryBundleInfo()); } catch (GLException gle) { if (DEBUG) { gle.printStackTrace(); } } if (null != tmp && tmp.isLibComplete()) { eglES2DynamicLookupHelper = tmp; EGL.resetProcAddressTable(eglES2DynamicLookupHelper); final boolean includesES1 = null == eglES1DynamicLookupHelper && includesES1(eglES2DynamicLookupHelper); if (includesES1) { eglES1DynamicLookupHelper = tmp; } final boolean isANGLEES2 = isANGLE(eglES2DynamicLookupHelper); isANGLE |= isANGLEES2; if (DEBUG || GLProfile.DEBUG) { System.err.println( "Info: EGLDrawableFactory: EGL ES2 - OK (includesES1 " + includesES1 + ", isANGLE: " + isANGLEES2 + ")"); if (includesES1) { System.err.println("Info: EGLDrawableFactory: EGL ES1 - OK (ES2 lib)"); } } } else if (DEBUG || GLProfile.DEBUG) { System.err.println("Info: EGLDrawableFactory: EGL ES2 - NOPE"); } } if (null != eglES2DynamicLookupHelper || null != eglES1DynamicLookupHelper) { if (isANGLE && !enableANGLE) { if (DEBUG || GLProfile.DEBUG) { System.err.println("Info: EGLDrawableFactory.init - EGL/ES2 ANGLE disabled"); } } else { if (isANGLE && (DEBUG || GLProfile.DEBUG)) { System.err.println("Info: EGLDrawableFactory.init - EGL/ES2 ANGLE enabled"); } sharedMap = new HashMap<String /*uniqueKey*/, SharedResource>(); sharedMapCreateAttempt = new HashSet<String>(); // FIXME: Following triggers eglInitialize(..) which crashed on Windows w/ Chrome/Angle, // FF/Angle! defaultDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice( EGL.EGL_DEFAULT_DISPLAY, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT); } } } }
/** * Your new java application main entry, which pipelines your application * * @throws ClassNotFoundException * @throws NoSuchMethodException * @throws SecurityException */ public static void main(String[] args) throws SecurityException, NoSuchMethodException, ClassNotFoundException { final Thread cur = Thread.currentThread(); useMainThread = HINT_USE_MAIN_THREAD; if (DEBUG) { System.err.println( "MainThread.main(): " + cur.getName() + ", useMainThread " + useMainThread + ", HINT_USE_MAIN_THREAD " + HINT_USE_MAIN_THREAD + ", isAWTAvailable " + NativeWindowFactory.isAWTAvailable() + ", ostype " + osType + ", isMacOSX " + isMacOSX); } if (!useMainThread && !NativeWindowFactory.isAWTAvailable()) { throw new RuntimeException("!USE_MAIN_THREAD and no AWT available"); } if (args.length == 0) { return; } String mainClassName = args[0]; String[] mainClassArgs = new String[args.length - 1]; if (args.length > 1) { System.arraycopy(args, 1, mainClassArgs, 0, args.length - 1); } mainAction = new UserApp(mainClassName, mainClassArgs); if (isMacOSX) { ReflectionUtil.callStaticMethod( MACOSXDisplayClassName, "initSingleton", null, null, MainThread.class.getClassLoader()); } if (useMainThread) { try { cur.setName(cur.getName() + "-MainThread"); } catch (Exception e) { } // dispatch user's main thread .. mainAction.start(); if (isMacOSX) { try { if (DEBUG) { System.err.println("MainThread.main(): " + cur.getName() + "- runNSApp"); } ReflectionUtil.callStaticMethod( MACOSXDisplayClassName, "runNSApplication", null, null, MainThread.class.getClassLoader()); } catch (Exception e) { e.printStackTrace(); } } if (DEBUG) { System.err.println("MainThread - wait until last non daemon thread ends ..."); } } else { // run user's main in this thread mainAction.run(); } }