Exemple #1
1
  /**
   * 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);
  }
Exemple #3
0
 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();
 }
Exemple #4
0
 public boolean isCurrentThreadEDT() {
   if (NativeWindowFactory.isAWTAvailable()) {
     initAWTReflection();
     return ((Boolean) ReflectionUtil.callMethod(null, mAWTIsDispatchThread, null)).booleanValue();
   }
   return isRunning() && mainThread == Thread.currentThread();
 }
Exemple #5
0
    @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");
      }
    }
Exemple #6
0
  /** 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);
    }
  }
Exemple #7
0
  /** 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();
    }
  }
Exemple #8
0
  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);
  }
Exemple #9
0
  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!");
    }
  }
Exemple #10
0
/**
 * 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);
        }
      }
    }
  }
Exemple #15
0
  /**
   * 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();
    }
  }