Exemple #1
0
  public static GLOffscreenAutoDrawable newOffscreenDrawable(GLProfile profile) {
    GLDrawableFactory drawableFactory = GLDrawableFactory.getFactory(profile);
    GLCapabilities caps = new GLCapabilities(profile);
    GLOffscreenAutoDrawable offscreenDrawable =
        drawableFactory.createOffscreenAutoDrawable(null, caps, null, 1, 1);

    // Trigger context creation
    offscreenDrawable.display();

    return offscreenDrawable;
  }
Exemple #2
0
 protected static GLDrawableFactory getFactoryImpl(AbstractGraphicsDevice device)
     throws GLException {
   if (null != nativeOSFactory && nativeOSFactory.getIsDeviceCompatible(device)) {
     return nativeOSFactory;
   }
   if (null != eglFactory && eglFactory.getIsDeviceCompatible(device)) {
     return eglFactory;
   }
   throw new GLException(
       "No native platform GLDrawableFactory, nor EGLDrawableFactory available: " + device);
 }
 @Test
 public void testAvailableInfo() {
   GLDrawableFactory f = GLDrawableFactory.getDesktopFactory();
   if (null != f) {
     System.err.println(
         JoglVersion.getDefaultOpenGLInfo(f.getDefaultDevice(), null, true).toString());
   }
   f = GLDrawableFactory.getEGLFactory();
   if (null != f) {
     System.err.println(
         JoglVersion.getDefaultOpenGLInfo(f.getDefaultDevice(), null, true).toString());
   }
 }
 /**
  * @param capsRequested
  * @param absScreen
  * @param eglConfigID {@link EGL#EGL_CONFIG_ID} for which the config is being created for.
  * @return
  * @throws GLException if invalid EGL display.
  */
 public static EGLGraphicsConfiguration create(
     GLCapabilitiesImmutable capsRequested, AbstractGraphicsScreen absScreen, int eglConfigID) {
   final AbstractGraphicsDevice absDevice = absScreen.getDevice();
   if (null == absDevice || !(absDevice instanceof EGLGraphicsDevice)) {
     throw new GLException("GraphicsDevice must be a valid EGLGraphicsDevice");
   }
   final long dpy = absDevice.getHandle();
   if (dpy == EGL.EGL_NO_DISPLAY) {
     throw new GLException("Invalid EGL display: " + absDevice);
   }
   final long cfg = EGLConfigId2EGLConfig(dpy, eglConfigID);
   if (0 < cfg) {
     final GLRendererQuirks defaultQuirks =
         GLRendererQuirks.getStickyDeviceQuirks(
             GLDrawableFactory.getEGLFactory().getDefaultDevice());
     final int winattrmask =
         GLGraphicsConfigurationUtil.getExclusiveWinAttributeBits(capsRequested);
     final EGLGLCapabilities caps =
         EGLConfig2Capabilities(
             defaultQuirks,
             (EGLGraphicsDevice) absDevice,
             capsRequested.getGLProfile(),
             cfg,
             winattrmask,
             false);
     return new EGLGraphicsConfiguration(
         absScreen, caps, capsRequested, new DefaultGLCapabilitiesChooser());
   }
   return null;
 }
  static X11GLXGraphicsConfiguration fetchGraphicsConfigurationFBConfig(
      X11GraphicsScreen x11Screen, int fbID, GLProfile glp) {
    final AbstractGraphicsDevice absDevice = x11Screen.getDevice();
    final long display = absDevice.getHandle();
    final int screen = x11Screen.getIndex();

    final long fbcfg = X11GLXGraphicsConfiguration.glXFBConfigID2FBConfig(display, screen, fbID);
    if (0 == fbcfg || !X11GLXGraphicsConfiguration.GLXFBConfigValid(display, fbcfg)) {
      if (DEBUG) {
        System.err.println(
            "X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed - GLX FBConfig invalid: ("
                + x11Screen
                + ","
                + toHexString(fbID)
                + "): fbcfg: "
                + toHexString(fbcfg));
      }
      return null;
    }
    final X11GLXDrawableFactory factory =
        (X11GLXDrawableFactory) GLDrawableFactory.getDesktopFactory();

    final X11GLCapabilities caps =
        X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(
            glp, display, fbcfg, true, true, true, factory.isGLXMultisampleAvailable(absDevice));
    return new X11GLXGraphicsConfiguration(
        x11Screen, caps, caps, new DefaultGLCapabilitiesChooser());
  }
  protected void runTestAGL(GLProfile glprofile) throws InterruptedException {
    GLData gldata = new GLData();
    gldata.doubleBuffer = true;
    // need SWT.NO_BACKGROUND to prevent SWT from clearing the window
    // at the wrong times (we use glClear for this instead)
    final GLCanvas glcanvas = new GLCanvas(composite, SWT.NO_BACKGROUND, gldata);
    Assert.assertNotNull(glcanvas);
    glcanvas.setCurrent();
    final GLContext glcontext = GLDrawableFactory.getFactory(glprofile).createExternalGLContext();
    Assert.assertNotNull(glcontext);

    // fix the viewport when the user resizes the window
    glcanvas.addListener(
        SWT.Resize,
        new Listener() {
          public void handleEvent(Event event) {
            Rectangle rectangle = glcanvas.getClientArea();
            glcanvas.setCurrent();
            glcontext.makeCurrent();
            GL2ES1 gl = glcontext.getGL().getGL2ES1();
            OneTriangle.setup(gl, rectangle.width, rectangle.height);
            glcontext.release();
            System.err.println("resize");
          }
        });

    // draw the triangle when the OS tells us that any part of the window needs drawing
    glcanvas.addPaintListener(
        new PaintListener() {
          public void paintControl(PaintEvent paintevent) {
            Rectangle rectangle = glcanvas.getClientArea();
            glcanvas.setCurrent();
            glcontext.makeCurrent();
            GL2ES1 gl = glcontext.getGL().getGL2ES1();
            OneTriangle.render(gl, rectangle.width, rectangle.height);
            glcanvas.swapBuffers();
            glcontext.release();
            System.err.println("paint");
          }
        });

    shell.setText(getClass().getName());
    shell.setSize(640, 480);
    shell.open();

    long lStartTime = System.currentTimeMillis();
    long lEndTime = lStartTime + duration;
    try {
      while ((System.currentTimeMillis() < lEndTime) && !glcanvas.isDisposed()) {
        if (!display.readAndDispatch()) {
          // blocks on linux .. display.sleep();
          Thread.sleep(10);
        }
      }
    } catch (Throwable throwable) {
      throwable.printStackTrace();
      Assume.assumeNoException(throwable);
    }
    glcanvas.dispose();
  }
Exemple #7
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 (null == drawable
          && visible
          && 0 != window.getWindowHandle()
          && 0 < getWidth() * getHeight()) {
        if ((null != context)) {
          throw new InternalError(
              "GLWindow.LifecycleHook.setVisiblePost: "
                  + WindowImpl.getThreadName()
                  + " - Null drawable, but valid context - "
                  + GLWindow.this);
        }
        final NativeSurface ns;
        {
          final NativeSurface wrapped_ns = window.getWrappedSurface();
          ns = null != wrapped_ns ? wrapped_ns : window;
        }
        final GLCapabilitiesImmutable glCaps =
            (GLCapabilitiesImmutable) ns.getGraphicsConfiguration().getChosenCapabilities();
        if (null == factory) {
          factory = GLDrawableFactory.getFactory(glCaps.getGLProfile());
        }
        drawable = (GLDrawableImpl) factory.createGLDrawable(ns);
        drawable.setRealized(true);

        if (!GLWindow.this.pushGLEventListenerState()) {
          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 #8
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");
      }
    }
  @Override
  public GLAutoDrawable createGLAutoDrawable(
      final QuitAdapter quitAdapter,
      final GLCapabilitiesImmutable caps,
      final int width,
      final int height)
      throws InterruptedException, InvocationTargetException {
    final GLAutoDrawable glad;
    if (caps.isOnscreen()) {
      final Frame frame = new Frame("Gears AWT Test");
      Assert.assertNotNull(frame);

      final GLCanvas glCanvas = new GLCanvas(caps);
      Assert.assertNotNull(glCanvas);
      final Dimension glc_sz = new Dimension(width, height);
      glCanvas.setMinimumSize(glc_sz);
      glCanvas.setPreferredSize(glc_sz);
      glCanvas.setSize(glc_sz);
      glad = glCanvas;

      new AWTWindowAdapter(new TraceWindowAdapter(quitAdapter), glCanvas).addTo(frame);

      frame.setLayout(new BorderLayout());
      frame.add(glCanvas, BorderLayout.CENTER);
      javax.swing.SwingUtilities.invokeAndWait(
          new Runnable() {
            public void run() {
              frame.pack();
              frame.setVisible(true);
            }
          });
    } else {
      final GLDrawableFactory factory = GLDrawableFactory.getFactory(caps.getGLProfile());
      glad = factory.createOffscreenAutoDrawable(null, caps, null, width, height);
      Assert.assertNotNull(glad);
    }
    return glad;
  }
  static X11GLXGraphicsConfiguration chooseGraphicsConfigurationStatic(
      GLCapabilitiesImmutable capsChosen,
      GLCapabilitiesImmutable capsReq,
      GLCapabilitiesChooser chooser,
      X11GraphicsScreen x11Screen) {
    if (x11Screen == null) {
      throw new IllegalArgumentException("AbstractGraphicsScreen is null");
    }

    if (capsChosen == null) {
      capsChosen = new GLCapabilities(null);
    }
    X11GraphicsDevice x11Device = (X11GraphicsDevice) x11Screen.getDevice();
    X11GLXDrawableFactory factory = (X11GLXDrawableFactory) GLDrawableFactory.getDesktopFactory();

    capsChosen =
        GLGraphicsConfigurationUtil.fixGLCapabilities(
            capsChosen, factory.canCreateGLPbuffer(x11Device));
    boolean usePBuffer = capsChosen.isPBuffer();

    X11GLXGraphicsConfiguration res = null;
    if (factory.isGLXVersionGreaterEqualOneThree(x11Device)) {
      res = chooseGraphicsConfigurationFBConfig(capsChosen, capsReq, chooser, x11Screen);
    }
    if (null == res) {
      if (usePBuffer) {
        throw new GLException(
            "Error: Couldn't create X11GLXGraphicsConfiguration based on FBConfig for "
                + capsChosen);
      }
      res = chooseGraphicsConfigurationXVisual(capsChosen, capsReq, chooser, x11Screen);
    }
    if (null == res) {
      throw new GLException(
          "Error: Couldn't create X11GLXGraphicsConfiguration based on FBConfig and XVisual for "
              + capsChosen);
    }
    if (DEBUG) {
      System.err.println(
          "X11GLXGraphicsConfiguration.chooseGraphicsConfigurationStatic("
              + x11Screen
              + ","
              + capsChosen
              + "): "
              + res);
    }
    return res;
  }
  private static X11GLXGraphicsConfiguration chooseGraphicsConfigurationXVisual(
      GLCapabilitiesImmutable capsChosen,
      GLCapabilitiesImmutable capsReq,
      GLCapabilitiesChooser chooser,
      X11GraphicsScreen x11Screen) {
    if (chooser == null) {
      chooser = new DefaultGLCapabilitiesChooser();
    }

    GLProfile glProfile = capsChosen.getGLProfile();
    final int winattrmask =
        GLGraphicsConfigurationUtil.getWinAttributeBits(
            capsChosen.isOnscreen(), false /* pbuffer */);
    ArrayList availableCaps = new ArrayList();
    int recommendedIndex = -1;

    AbstractGraphicsDevice absDevice = x11Screen.getDevice();
    long display = absDevice.getHandle();
    int screen = x11Screen.getIndex();

    final X11GLXDrawableFactory factory =
        (X11GLXDrawableFactory) GLDrawableFactory.getDesktopFactory();
    final boolean isMultisampleAvailable = factory.isGLXMultisampleAvailable(absDevice);
    int[] attribs =
        X11GLXGraphicsConfiguration.GLCapabilities2AttribList(
            capsChosen, false, isMultisampleAvailable, display, screen);

    // 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as
    // preferred choice
    XVisualInfo recommendedVis = GLX.glXChooseVisual(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 " + toHexString(recommendedVis.getVisualid()));
      }
    }

    // 2nd choice: get all GLCapabilities available, preferred recommendedIndex might be available
    // if 1st choice was successful
    int[] count = new int[1];
    XVisualInfo template = XVisualInfo.create();
    template.setScreen(screen);
    XVisualInfo[] infos =
        X11Lib.XGetVisualInfo(display, X11Lib.VisualScreenMask, template, count, 0);
    if (infos == null || infos.length < 1) {
      throw new GLException("Error while enumerating available XVisualInfos");
    }

    for (int i = 0; i < infos.length; i++) {
      if (!X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(
          availableCaps, glProfile, display, infos[i], winattrmask, isMultisampleAvailable)) {
        if (DEBUG) {
          System.err.println(
              "X11GLXGraphicsConfiguration.chooseGraphicsConfigurationXVisual: XVisual invalid: ("
                  + x11Screen
                  + "): fbcfg: "
                  + toHexString(infos[i].getVisualid()));
        }
      } else {
        // Attempt to find the visual chosenIndex by glXChooseVisual, if not translucent
        if (capsChosen.isBackgroundOpaque()
            && recommendedVis != null
            && recommendedVis.getVisualid() == infos[i].getVisualid()) {
          recommendedIndex = availableCaps.size() - 1;
        }
      }
    }

    int chosenIndex = chooseCapabilities(chooser, capsChosen, availableCaps, recommendedIndex);
    if (0 > chosenIndex) {
      if (DEBUG) {
        System.err.println(
            "X11GLXGraphicsConfiguration.chooseGraphicsConfigurationXVisual: failed, return null");
        Thread.dumpStack();
      }
      return null;
    }
    X11GLCapabilities chosenCaps = (X11GLCapabilities) availableCaps.get(chosenIndex);

    return new X11GLXGraphicsConfiguration(x11Screen, chosenCaps, capsReq, chooser);
  }
  private static X11GLXGraphicsConfiguration chooseGraphicsConfigurationFBConfig(
      GLCapabilitiesImmutable capsChosen,
      GLCapabilitiesImmutable capsReq,
      GLCapabilitiesChooser chooser,
      X11GraphicsScreen x11Screen) {
    int recommendedIndex = -1;
    PointerBuffer fbcfgsL = null;
    GLProfile glProfile = capsChosen.getGLProfile();
    boolean onscreen = capsChosen.isOnscreen();
    boolean usePBuffer = capsChosen.isPBuffer();

    // Utilizing FBConfig
    //
    AbstractGraphicsDevice absDevice = x11Screen.getDevice();
    long display = absDevice.getHandle();
    int screen = x11Screen.getIndex();

    final X11GLXDrawableFactory factory =
        (X11GLXDrawableFactory) GLDrawableFactory.getDesktopFactory();
    final boolean isMultisampleAvailable = factory.isGLXMultisampleAvailable(absDevice);
    int[] attribs =
        X11GLXGraphicsConfiguration.GLCapabilities2AttribList(
            capsChosen, true, isMultisampleAvailable, display, screen);
    int[] count = {-1};
    ArrayList /*<X11GLCapabilities>*/ availableCaps = new ArrayList();
    final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer);

    // 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as
    // preferred choice
    fbcfgsL = GLX.glXChooseFBConfig(display, screen, attribs, 0, count, 0);
    if (fbcfgsL != null && fbcfgsL.limit() > 0) {
      for (int i = 0; i < fbcfgsL.limit(); i++) {
        if (!X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(
            availableCaps,
            glProfile,
            display,
            fbcfgsL.get(i),
            winattrmask,
            isMultisampleAvailable)) {
          if (DEBUG) {
            System.err.println(
                "X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: FBConfig invalid (1): ("
                    + x11Screen
                    + ","
                    + capsChosen
                    + "): fbcfg: "
                    + toHexString(fbcfgsL.get(i)));
          }
        }
      }
      if (availableCaps.size() > 0) {
        recommendedIndex =
            capsChosen.isBackgroundOpaque() ? 0 : -1; // only use recommended idx if not translucent
        if (DEBUG) {
          System.err.println(
              "glXChooseFBConfig recommended fbcfg "
                  + toHexString(fbcfgsL.get(0))
                  + ", idx "
                  + recommendedIndex);
          System.err.println("user  caps " + capsChosen);
          System.err.println("fbcfg caps " + availableCaps.get(0));
        }
      } else if (DEBUG) {
        System.err.println(
            "glXChooseFBConfig no caps for recommended fbcfg " + toHexString(fbcfgsL.get(0)));
        System.err.println("user  caps " + capsChosen);
      }
    }

    // 2nd choice: get all GLCapabilities available, no preferred recommendedIndex available
    if (0 == availableCaps.size()) {
      // reset ..
      recommendedIndex = -1;

      fbcfgsL = GLX.glXChooseFBConfig(display, screen, null, 0, count, 0);
      if (fbcfgsL == null || fbcfgsL.limit() <= 0) {
        if (DEBUG) {
          System.err.println(
              "X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed glXChooseFBConfig ("
                  + x11Screen
                  + ","
                  + capsChosen
                  + "): "
                  + fbcfgsL
                  + ", "
                  + count[0]);
        }
        return null;
      }

      for (int i = 0; i < fbcfgsL.limit(); i++) {
        if (!X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(
            availableCaps,
            glProfile,
            display,
            fbcfgsL.get(i),
            winattrmask,
            isMultisampleAvailable)) {
          if (DEBUG) {
            System.err.println(
                "X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: FBConfig invalid (2): ("
                    + x11Screen
                    + "): fbcfg: "
                    + toHexString(fbcfgsL.get(i)));
          }
        }
      }
    }
    int chosenIndex = chooseCapabilities(chooser, capsChosen, availableCaps, recommendedIndex);
    if (0 > chosenIndex) {
      if (DEBUG) {
        System.err.println(
            "X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: failed, return null");
        Thread.dumpStack();
      }
      return null;
    }
    X11GLCapabilities chosenCaps = (X11GLCapabilities) availableCaps.get(chosenIndex);

    return new X11GLXGraphicsConfiguration(x11Screen, chosenCaps, capsReq, chooser);
  }
  public static IntBuffer GLCapabilities2AttribList(GLCapabilitiesImmutable caps) {
    final IntBuffer attrs = Buffers.newDirectIntBuffer(32);
    int idx = 0;

    attrs.put(idx++, EGL.EGL_SURFACE_TYPE);
    final int surfaceType;
    if (caps.isOnscreen()) {
      surfaceType = EGL.EGL_WINDOW_BIT;
    } else if (caps.isFBO()) {
      surfaceType = EGL.EGL_PBUFFER_BIT; // native replacement!
    } else if (caps.isPBuffer()) {
      surfaceType = EGL.EGL_PBUFFER_BIT;
    } else if (caps.isBitmap()) {
      surfaceType = EGL.EGL_PIXMAP_BIT;
    } else {
      throw new GLException("no surface type set in caps: " + caps);
    }
    attrs.put(idx++, surfaceType);

    attrs.put(idx++, EGL.EGL_RED_SIZE);
    attrs.put(idx++, caps.getRedBits());

    attrs.put(idx++, EGL.EGL_GREEN_SIZE);
    attrs.put(idx++, caps.getGreenBits());

    attrs.put(idx++, EGL.EGL_BLUE_SIZE);
    attrs.put(idx++, caps.getBlueBits());

    if (caps.getAlphaBits() > 0) {
      attrs.put(idx++, EGL.EGL_ALPHA_SIZE);
      attrs.put(idx++, caps.getAlphaBits());
    }

    if (caps.getStencilBits() > 0) {
      attrs.put(idx++, EGL.EGL_STENCIL_SIZE);
      attrs.put(idx++, caps.getStencilBits());
    }

    attrs.put(idx++, EGL.EGL_DEPTH_SIZE);
    attrs.put(idx++, caps.getDepthBits());

    if (caps.getSampleBuffers()) {
      if (caps.getSampleExtension().equals(GLGraphicsConfigurationUtil.NV_coverage_sample)) {
        attrs.put(idx++, EGLExt.EGL_COVERAGE_BUFFERS_NV);
        attrs.put(idx++, 1);
        attrs.put(idx++, EGLExt.EGL_COVERAGE_SAMPLES_NV);
        attrs.put(idx++, caps.getNumSamples());
      } else {
        // try default ..
        attrs.put(idx++, EGL.EGL_SAMPLE_BUFFERS);
        attrs.put(idx++, 1);
        attrs.put(idx++, EGL.EGL_SAMPLES);
        attrs.put(idx++, caps.getNumSamples());
      }
    }

    attrs.put(idx++, EGL.EGL_TRANSPARENT_TYPE);
    attrs.put(idx++, caps.isBackgroundOpaque() ? EGL.EGL_NONE : EGL.EGL_TRANSPARENT_TYPE);

    // 22

    if (!caps.isBackgroundOpaque()) {
      attrs.put(idx++, EGL.EGL_TRANSPARENT_RED_VALUE);
      attrs.put(
          idx++,
          caps.getTransparentRedValue() >= 0 ? caps.getTransparentRedValue() : EGL.EGL_DONT_CARE);

      attrs.put(idx++, EGL.EGL_TRANSPARENT_GREEN_VALUE);
      attrs.put(
          idx++,
          caps.getTransparentGreenValue() >= 0
              ? caps.getTransparentGreenValue()
              : EGL.EGL_DONT_CARE);

      attrs.put(idx++, EGL.EGL_TRANSPARENT_BLUE_VALUE);
      attrs.put(
          idx++,
          caps.getTransparentBlueValue() >= 0 ? caps.getTransparentBlueValue() : EGL.EGL_DONT_CARE);

      /**
       * Not define in EGL attrs.put(idx++, EGL.EGL_TRANSPARENT_ALPHA_VALUE; attrs.put(idx++,
       * caps.getTransparentAlphaValue()>=0?caps.getTransparentAlphaValue():EGL.EGL_DONT_CARE;
       */
    }

    // 28
    attrs.put(idx++, EGL.EGL_RENDERABLE_TYPE);
    if (caps.getGLProfile().usesNativeGLES1()) {
      attrs.put(idx++, EGL.EGL_OPENGL_ES_BIT);
    } else if (caps.getGLProfile().usesNativeGLES2()) {
      attrs.put(idx++, EGL.EGL_OPENGL_ES2_BIT);
    } else if (caps.getGLProfile().usesNativeGLES3()) {
      if (GLRendererQuirks.existStickyDeviceQuirk(
          GLDrawableFactory.getEGLFactory().getDefaultDevice(),
          GLRendererQuirks.GLES3ViaEGLES2Config)) {
        attrs.put(idx++, EGL.EGL_OPENGL_ES2_BIT);
      } else {
        attrs.put(idx++, EGLExt.EGL_OPENGL_ES3_BIT_KHR);
      }
    } else {
      attrs.put(idx++, EGL.EGL_OPENGL_BIT);
    }

    // 30

    attrs.put(idx++, EGL.EGL_NONE);

    return attrs;
  }
  private boolean mapAvailableEGLESConfig(
      AbstractGraphicsDevice adevice,
      int esProfile,
      boolean[] hasPBuffer,
      GLRendererQuirks[] rendererQuirks,
      int[] ctp) {
    final String profileString;
    switch (esProfile) {
      case 3:
        profileString = GLProfile.GLES3;
        break;
      case 2:
        profileString = GLProfile.GLES2;
        break;
      case 1:
        profileString = GLProfile.GLES1;
        break;
      default:
        throw new GLException("Invalid ES profile number " + esProfile);
    }
    if (!GLProfile.isAvailable(adevice, profileString)) {
      if (DEBUG) {
        System.err.println(
            "EGLDrawableFactory.mapAvailableEGLESConfig: " + profileString + " n/a on " + adevice);
      }
      return false;
    }
    final GLProfile glp = GLProfile.get(adevice, profileString);
    final GLDrawableFactoryImpl desktopFactory =
        (GLDrawableFactoryImpl) GLDrawableFactory.getDesktopFactory();
    final boolean mapsADeviceToDefaultDevice =
        !QUERY_EGL_ES_NATIVE_TK || null == desktopFactory || adevice instanceof EGLGraphicsDevice;
    if (DEBUG) {
      System.err.println(
          "EGLDrawableFactory.mapAvailableEGLESConfig: "
              + profileString
              + " ( "
              + esProfile
              + " ), "
              + "defaultSharedResourceSet "
              + (null != defaultSharedResource)
              + ", mapsADeviceToDefaultDevice "
              + mapsADeviceToDefaultDevice
              + " (QUERY_EGL_ES_NATIVE_TK "
              + QUERY_EGL_ES_NATIVE_TK
              + ", hasDesktopFactory "
              + (null != desktopFactory)
              + ", isEGLGraphicsDevice "
              + (adevice instanceof EGLGraphicsDevice)
              + ")");
    }

    EGLGraphicsDevice eglDevice = null;
    NativeSurface surface = null;
    ProxySurface upstreamSurface = null; // X11, GLX, ..
    boolean success = false;
    boolean deviceFromUpstreamSurface = false;
    try {
      final GLCapabilities reqCapsAny = new GLCapabilities(glp);
      reqCapsAny.setRedBits(5);
      reqCapsAny.setGreenBits(5);
      reqCapsAny.setBlueBits(5);
      reqCapsAny.setAlphaBits(0);
      reqCapsAny.setDoubleBuffered(false);

      if (mapsADeviceToDefaultDevice) {
        // In this branch, any non EGL device is mapped to EGL default shared resources (default
        // behavior).
        // Only one default shared resource instance is ever be created.
        final GLCapabilitiesImmutable reqCapsPBuffer =
            GLGraphicsConfigurationUtil.fixGLPBufferGLCapabilities(reqCapsAny);
        final List<GLCapabilitiesImmutable> availablePBufferCapsL =
            getAvailableEGLConfigs(defaultDevice, reqCapsPBuffer);
        hasPBuffer[0] = availablePBufferCapsL.size() > 0;

        // 1st case: adevice is not the EGL default device, map default shared resources
        if (adevice != defaultDevice) {
          if (null == defaultSharedResource) {
            return false;
          }
          switch (esProfile) {
            case 3:
              if (!defaultSharedResource.wasES3ContextCreated) {
                return false;
              }
              rendererQuirks[0] = defaultSharedResource.rendererQuirksES3ES2;
              ctp[0] = defaultSharedResource.ctpES3ES2;
              break;
            case 2:
              if (!defaultSharedResource.wasES2ContextCreated) {
                return false;
              }
              rendererQuirks[0] = defaultSharedResource.rendererQuirksES3ES2;
              ctp[0] = defaultSharedResource.ctpES3ES2;
              break;
            case 1:
              if (!defaultSharedResource.wasES1ContextCreated) {
                return false;
              }
              rendererQuirks[0] = defaultSharedResource.rendererQuirksES1;
              ctp[0] = defaultSharedResource.ctpES1;
              break;
          }
          EGLContext.mapStaticGLVersion(adevice, esProfile, 0, ctp[0]);
          return true;
        }

        // attempt to created the default shared resources ..

        eglDevice = defaultDevice; // reuse

        if (hasPBuffer[0]) {
          // 2nd case create defaultDevice shared resource using pbuffer surface
          surface =
              createDummySurfaceImpl(
                  eglDevice,
                  false,
                  reqCapsPBuffer,
                  reqCapsPBuffer,
                  null,
                  64,
                  64); // egl pbuffer offscreen
          upstreamSurface = (ProxySurface) surface;
          upstreamSurface.createNotify();
          deviceFromUpstreamSurface = false;
        } else {
          // 3rd case fake creation of defaultDevice shared resource, no pbuffer available
          final List<GLCapabilitiesImmutable> capsAnyL =
              getAvailableEGLConfigs(eglDevice, reqCapsAny);
          if (capsAnyL.size() > 0) {
            final GLCapabilitiesImmutable chosenCaps = capsAnyL.get(0);
            EGLContext.mapStaticGLESVersion(eglDevice, chosenCaps);
            success = true;
          }
          if (DEBUG) {
            System.err.println(
                "EGLDrawableFactory.mapAvailableEGLESConfig() no pbuffer config available, detected !pbuffer config: "
                    + success);
            EGLGraphicsConfigurationFactory.printCaps("!PBufferCaps", capsAnyL, System.err);
          }
        }
      } else {
        // 4th case always creates a true mapping of given device to EGL
        surface =
            desktopFactory.createDummySurface(
                adevice, reqCapsAny, null, 64, 64); // X11, WGL, .. dummy window
        upstreamSurface = (surface instanceof ProxySurface) ? (ProxySurface) surface : null;
        if (null != upstreamSurface) {
          upstreamSurface.createNotify();
        }
        eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(surface);
        deviceFromUpstreamSurface = true;
        hasPBuffer[0] = true;
      }

      if (null != surface) {
        final EGLDrawable drawable =
            (EGLDrawable)
                createOnscreenDrawableImpl(
                    surface); // works w/ implicit pbuffer surface via proxy-hook
        drawable.setRealized(true);
        final EGLContext context = (EGLContext) drawable.createContext(null);
        if (null != context) {
          try {
            context.makeCurrent(); // could cause exception
            if (context.isCurrent()) {
              final String glVersion = context.getGL().glGetString(GL.GL_VERSION);
              if (null != glVersion) {
                context.mapCurrentAvailableGLVersion(eglDevice);
                if (eglDevice != adevice) {
                  context.mapCurrentAvailableGLVersion(adevice);
                }
                rendererQuirks[0] = context.getRendererQuirks();
                ctp[0] = context.getContextOptions();
                success = true;
              } else {
                // Oops .. something is wrong
                if (DEBUG) {
                  System.err.println(
                      "EGLDrawableFactory.mapAvailableEGLESConfig: "
                          + eglDevice
                          + ", "
                          + context.getGLVersion()
                          + " - VERSION is null, dropping availability!");
                }
              }
            }
          } catch (GLException gle) {
            if (DEBUG) {
              System.err.println(
                  "EGLDrawableFactory.mapAvailableEGLESConfig: INFO: context create/makeCurrent failed");
              gle.printStackTrace();
            }
          } finally {
            context.destroy();
          }
        }
        drawable.setRealized(false);
      }
    } catch (Throwable t) {
      if (DEBUG) {
        System.err.println("Catched Exception on thread " + getThreadName());
        t.printStackTrace();
      }
      success = false;
    } finally {
      if (eglDevice == defaultDevice) {
        if (null != upstreamSurface) {
          upstreamSurface.destroyNotify();
        }
      } else if (deviceFromUpstreamSurface) {
        if (null != eglDevice) {
          eglDevice.close();
        }
        if (null != upstreamSurface) {
          upstreamSurface.destroyNotify();
        }
      } else {
        if (null != upstreamSurface) {
          upstreamSurface.destroyNotify();
        }
        if (null != eglDevice) {
          eglDevice.close();
        }
      }
    }
    return success;
  }
Exemple #15
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!");
    }
  }
  void doTest(final GLCapabilitiesImmutable reqGLCaps, final GLEventListener demo)
      throws InterruptedException {
    System.out.println("Requested  GL Caps: " + reqGLCaps);
    final GLDrawableFactory factory = GLDrawableFactory.getFactory(reqGLCaps.getGLProfile());
    final GLCapabilitiesImmutable expGLCaps =
        GLGraphicsConfigurationUtil.fixGLCapabilities(reqGLCaps, factory, null);
    System.out.println("Expected   GL Caps: " + expGLCaps);

    //
    // Create native OpenGL resources .. XGL/WGL/CGL ..
    // equivalent to GLAutoDrawable methods: setVisible(true)
    //
    final GLOffscreenAutoDrawable glad =
        factory.createOffscreenAutoDrawable(
            null, reqGLCaps, null, widthStep * szStep, heightStep * szStep);

    Assert.assertNotNull(glad);
    System.out.println(
        "Drawable    Pre-GL(0): "
            + glad.getClass().getName()
            + ", "
            + glad.getNativeSurface().getClass().getName());
    Assert.assertTrue(glad.isRealized());

    // Check caps of NativeWindow config w/o GL
    final CapabilitiesImmutable chosenCaps = glad.getChosenGLCapabilities();
    System.out.println("Drawable Caps Pre_GL : " + chosenCaps);
    Assert.assertNotNull(chosenCaps);
    Assert.assertTrue(chosenCaps.getGreenBits() > 4);
    Assert.assertTrue(chosenCaps.getBlueBits() > 4);
    Assert.assertTrue(chosenCaps.getRedBits() > 4);

    glad.display(); // force native context creation

    // Check caps of GLDrawable after realization
    final GLCapabilitiesImmutable chosenGLCaps = glad.getChosenGLCapabilities();
    System.out.println("Chosen     GL CTX (1): " + glad.getContext().getGLVersion());
    System.out.println("Chosen     GL Caps(1): " + chosenGLCaps);
    System.out.println(
        "Chosen     GL Caps(2): "
            + glad.getNativeSurface().getGraphicsConfiguration().getChosenCapabilities());

    Assert.assertNotNull(chosenGLCaps);
    Assert.assertTrue(chosenGLCaps.getGreenBits() > 4);
    Assert.assertTrue(chosenGLCaps.getBlueBits() > 4);
    Assert.assertTrue(chosenGLCaps.getRedBits() > 4);
    Assert.assertTrue(chosenGLCaps.getDepthBits() > 4);
    Assert.assertEquals(expGLCaps.isOnscreen(), chosenGLCaps.isOnscreen());
    Assert.assertEquals(expGLCaps.isFBO(), chosenGLCaps.isFBO());
    Assert.assertEquals(expGLCaps.isPBuffer(), chosenGLCaps.isPBuffer());
    Assert.assertEquals(expGLCaps.isBitmap(), chosenGLCaps.isBitmap());
    /**
     * Single/Double buffer cannot be checked since result may vary .. if(chosenGLCaps.isOnscreen()
     * || chosenGLCaps.isFBO()) { // dbl buffer may be disabled w/ offscreen pbuffer and bitmap
     * Assert.assertEquals(expGLCaps.getDoubleBuffered(), chosenGLCaps.getDoubleBuffered()); }
     */
    glad.addGLEventListener(demo);

    final SnapshotGLEventListener snapshotGLEventListener = new SnapshotGLEventListener();
    glad.addGLEventListener(snapshotGLEventListener);

    glad.display(); // initial resize/display

    // 1 - szStep = 2
    Assert.assertTrue(
        "Size not reached: Expected "
            + (widthStep * szStep)
            + "x"
            + (heightStep * szStep)
            + ", Is "
            + glad.getSurfaceWidth()
            + "x"
            + glad.getSurfaceHeight(),
        AWTRobotUtil.waitForSize(glad, widthStep * szStep, heightStep * szStep));
    snapshotGLEventListener.setMakeSnapshot();
    glad.display();

    // 2, 3 (resize + display)
    szStep = 1;
    glad.setSurfaceSize(widthStep * szStep, heightStep * szStep);
    Assert.assertTrue(
        "Size not reached: Expected "
            + (widthStep * szStep)
            + "x"
            + (heightStep * szStep)
            + ", Is "
            + glad.getSurfaceWidth()
            + "x"
            + glad.getSurfaceHeight(),
        AWTRobotUtil.waitForSize(glad, widthStep * szStep, heightStep * szStep));
    snapshotGLEventListener.setMakeSnapshot();
    glad.display();

    // 4, 5 (resize + display)
    szStep = 4;
    glad.setSurfaceSize(widthStep * szStep, heightStep * szStep);
    Assert.assertTrue(
        "Size not reached: Expected "
            + (widthStep * szStep)
            + "x"
            + (heightStep * szStep)
            + ", Is "
            + glad.getSurfaceWidth()
            + "x"
            + glad.getSurfaceHeight(),
        AWTRobotUtil.waitForSize(glad, widthStep * szStep, heightStep * szStep));
    snapshotGLEventListener.setMakeSnapshot();
    glad.display();

    Thread.sleep(50);

    glad.destroy();
    System.out.println("Fin Drawable: " + glad);
  }
  public void createPartControl(final Composite parent) {
    Composite top = new Composite(parent, SWT.NONE);
    top.setLayout(new FillLayout());
    GLData data = new GLData();
    data.doubleBuffer = true;
    canvas = new GLCanvas(top, SWT.NONE, data);
    canvas.setCurrent();
    final GLContext context = GLDrawableFactory.getFactory().createExternalGLContext();
    context.makeCurrent();
    GL gl = context.getGL();
    geocontext.initialize(context);
    gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    context.release();

    canvas.addListener(
        SWT.Resize,
        new Listener() {
          public void handleEvent(Event event) {
            Rectangle bounds = canvas.getBounds();
            canvas.setCurrent();
            context.makeCurrent();
            GL gl = context.getGL();
            geocontext.setHeight(bounds.height);
            geocontext.setWidth(bounds.width);
            gl.glViewport(0, 0, bounds.width, bounds.height);
            gl.glMatrixMode(GL.GL_PROJECTION);
            gl.glLoadIdentity();
            new GLU().gluOrtho2D(0, 1, 0, 1);
            gl.glMatrixMode(GL.GL_MODELVIEW);
            gl.glLoadIdentity();
            context.release();
          }
        });

    canvas.addMouseMoveListener(
        new MouseMoveListener() {

          @Override
          public void mouseMove(MouseEvent e) {
            if (e.stateMask == SWT.SHIFT) {
              dxx = (int) (geocontext.getZoom() * (e.x - canvas.getBounds().width / 2) / 10);
              dyy = (int) (geocontext.getZoom() * (e.y - canvas.getBounds().height / 2) / 10);
              geocontext.setDirty(true);
            } else {
              Point p = new Point();
              try {
                p.x =
                    (int)
                        (geocontext.getX()
                            + e.x
                                * geocontext.getWidth()
                                / canvas.getBounds().width
                                * geocontext.getZoom());
                p.y =
                    (int)
                        (geocontext.getY()
                            + e.y
                                * geocontext.getHeight()
                                / canvas.getBounds().height
                                * geocontext.getZoom());
                root.mouseMoved(p, geocontext);
              } catch (Exception ex) {
              }
            }
          }
        });

    canvas.addMouseWheelListener(
        new MouseWheelListener() {

          @Override
          public void mouseScrolled(MouseEvent e) {

            float zoom = (float) (geocontext.getZoom() * Math.pow(2, -e.count / 20.0));

            // check mouse position
            int posX = e.x;
            int posY = e.y;
            // calculate the image position of the current position of the mouse
            int x =
                (int)
                    (geocontext.getX()
                        + posX
                            * geocontext.getWidth()
                            / canvas.getBounds().width
                            * geocontext.getZoom());
            int y =
                (int)
                    (geocontext.getY()
                        + posY
                            * geocontext.getHeight()
                            / canvas.getBounds().height
                            * geocontext.getZoom());
            geocontext.setZoom(zoom);
            // translate the image origin to have the same mouse position in the geocontext
            geocontext.setX(
                (int)
                    (x
                        - posX
                            * geocontext.getWidth()
                            / canvas.getBounds().width
                            * geocontext.getZoom()));
            geocontext.setY(
                (int)
                    (y
                        - posY
                            * geocontext.getHeight()
                            / canvas.getBounds().height
                            * geocontext.getZoom()));
            geocontext.setDirty(true);
          }
        });

    final Runnable core =
        new Runnable() {
          int count = 0;
          long[] times = new long[500];

          public void run() {
            if (!canvas.isDisposed()) {
              if (count == times.length) {
                count = 0;
                double fps = 0;
                for (int i = 0; i < times.length - 1; i++) {
                  fps += (times[i + 1] - times[i]) / 1000.;
                }
                fps /= times.length - 1;
                System.out.println(1 / fps);
              } else {
                times[count++] = System.currentTimeMillis();
              }
              canvas.setCurrent();
              context.makeCurrent();
              GL gl = context.getGL();
              gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
              if (dxx != 0 || dyy != 0) {
                dxx /= 1.2;
                dyy /= 1.2;
                geocontext.setX(geocontext.getX() + dxx);
                geocontext.setY(geocontext.getY() + dyy);
              }
              geocontext.initialize(context);
              geocontext.setDirty(true);
              root.render(geocontext);
              canvas.swapBuffers();
              context.release();
              try {
                Thread.sleep(15);
              } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
              }
              canvas.getDisplay().asyncExec(this);
            }
          }
        };
    canvas.getDisplay().asyncExec(core);

    registerView();
    renderLayers();
  }
  void doTest(
      final boolean onscreen, final GLEventListener demo, final GLProfile glp, final int msaaCount)
      throws IOException {
    final GLCapabilities caps = new GLCapabilities(glp);
    caps.setDoubleBuffered(onscreen);
    if (msaaCount > 0) {
      caps.setSampleBuffers(true);
      caps.setNumSamples(msaaCount);
    }

    final int maxTileSize = 256;
    final GLAutoDrawable glad;
    if (onscreen) {
      final GLWindow glWin = GLWindow.create(caps);
      glWin.setSize(maxTileSize, maxTileSize);
      glWin.setVisible(true);
      glad = glWin;
    } else {
      final GLDrawableFactory factory = GLDrawableFactory.getFactory(glp);
      glad = factory.createOffscreenAutoDrawable(null, caps, null, maxTileSize, maxTileSize);
    }

    glad.addGLEventListener(demo);

    // Fix the image size for now
    final int imageWidth = glad.getSurfaceWidth() * 6;
    final int imageHeight = glad.getSurfaceHeight() * 4;

    final String filename =
        this.getSnapshotFilename(
            0,
            "-tile",
            glad.getChosenGLCapabilities(),
            imageWidth,
            imageHeight,
            false,
            TextureIO.PNG,
            null);
    final File file = new File(filename);

    // Initialize the tile rendering library
    final TileRenderer renderer = new TileRenderer();
    renderer.setImageSize(imageWidth, imageHeight);
    renderer.setTileSize(glad.getSurfaceWidth(), glad.getSurfaceHeight(), 0);
    renderer.attachAutoDrawable(glad);

    final GLPixelBuffer.GLPixelBufferProvider pixelBufferProvider =
        GLPixelBuffer.defaultProviderWithRowStride;
    final boolean[] flipVertically = {false};

    final GLEventListener preTileGLEL =
        new GLEventListener() {
          @Override
          public void init(final GLAutoDrawable drawable) {
            final GL gl = drawable.getGL();
            final GLPixelAttributes pixelAttribs = pixelBufferProvider.getAttributes(gl, 3);
            final GLPixelBuffer pixelBuffer =
                pixelBufferProvider.allocate(gl, pixelAttribs, imageWidth, imageHeight, 1, true, 0);
            renderer.setImageBuffer(pixelBuffer);
            if (drawable.isGLOriented()) {
              flipVertically[0] = false;
            } else {
              flipVertically[0] = true;
            }
          }

          @Override
          public void dispose(final GLAutoDrawable drawable) {}

          @Override
          public void display(final GLAutoDrawable drawable) {}

          @Override
          public void reshape(
              final GLAutoDrawable drawable,
              final int x,
              final int y,
              final int width,
              final int height) {}
        };
    renderer.setGLEventListener(preTileGLEL, null);

    while (!renderer.eot()) {
      renderer.display();
    }

    renderer.detachAutoDrawable();

    // Restore viewport and Gear's PMV matrix
    // .. even though we close the demo, this is for documentation!
    glad.invoke(
        true,
        new GLRunnable() {
          @Override
          public boolean run(final GLAutoDrawable drawable) {
            drawable
                .getGL()
                .glViewport(0, 0, drawable.getSurfaceWidth(), drawable.getSurfaceHeight());
            demo.reshape(drawable, 0, 0, drawable.getSurfaceWidth(), drawable.getSurfaceHeight());
            return false;
          }
        });

    final GLPixelBuffer imageBuffer = renderer.getImageBuffer();
    final TextureData textureData =
        new TextureData(
            caps.getGLProfile(),
            0 /* internalFormat */,
            imageWidth,
            imageHeight,
            0,
            imageBuffer.pixelAttributes,
            false,
            false,
            flipVertically[0],
            imageBuffer.buffer,
            null /* Flusher */);

    TextureIO.write(textureData, file);

    glad.destroy();
  }