@Override
 public final void destroy(ProxySurface surface) {
   if (EGLDrawableFactory.DEBUG) {
     System.err.println(
         "EGLUpstreamSurfaceHook.destroy(" + surface.getClass().getSimpleName() + "): " + this);
   }
   surface.clearUpstreamOptionBits(ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE);
   if (upstreamSurface instanceof ProxySurface) {
     ((ProxySurface) upstreamSurface).destroyNotify();
   }
 }
  private final void evalUpstreamSurface(String dbgPrefix, ProxySurface surface) {
    //
    // evaluate nature of upstreamSurface, may create EGL instances if required
    //

    boolean isEGLSurfaceValid = true; // assume yes

    final EGLGraphicsDevice eglDevice;
    final AbstractGraphicsConfiguration aConfig;
    {
      final AbstractGraphicsConfiguration surfaceConfig = surface.getGraphicsConfiguration();
      final AbstractGraphicsDevice surfaceDevice =
          null != surfaceConfig ? surfaceConfig.getScreen().getDevice() : null;
      if (DEBUG) {
        System.err.println(
            dbgPrefix
                + "SurfaceDevice: "
                + surfaceDevice.getClass().getSimpleName()
                + ", hash 0x"
                + Integer.toHexString(surfaceDevice.hashCode())
                + ", "
                + surfaceDevice);
        System.err.println(
            dbgPrefix
                + "SurfaceConfig: "
                + surfaceConfig.getClass().getSimpleName()
                + ", hash 0x"
                + Integer.toHexString(surfaceConfig.hashCode())
                + ", "
                + surfaceConfig);
      }

      final AbstractGraphicsConfiguration upstreamConfig =
          upstreamSurface.getGraphicsConfiguration();
      final AbstractGraphicsDevice upstreamDevice = upstreamConfig.getScreen().getDevice();
      if (DEBUG) {
        System.err.println(
            dbgPrefix
                + "UpstreamDevice: "
                + upstreamDevice.getClass().getSimpleName()
                + ", hash 0x"
                + Integer.toHexString(upstreamDevice.hashCode())
                + ", "
                + upstreamDevice);
        System.err.println(
            dbgPrefix
                + "UpstreamConfig: "
                + upstreamConfig.getClass().getSimpleName()
                + ", hash 0x"
                + Integer.toHexString(upstreamConfig.hashCode())
                + ", "
                + upstreamConfig);
      }

      if (surfaceDevice instanceof EGLGraphicsDevice) {
        eglDevice = (EGLGraphicsDevice) surfaceDevice;
        aConfig = surfaceConfig;
        if (DEBUG) {
          System.err.println(
              dbgPrefix
                  + "Reusing this eglDevice: "
                  + eglDevice
                  + ", using this config "
                  + aConfig.getClass().getSimpleName()
                  + " "
                  + aConfig);
        }
        if (EGL.EGL_NO_DISPLAY == eglDevice.getHandle()) {
          eglDevice.open();
          isEGLSurfaceValid = false;
          surface.addUpstreamOptionBits(ProxySurface.OPT_PROXY_OWNS_UPSTREAM_DEVICE);
        }
      } else if (upstreamDevice instanceof EGLGraphicsDevice) {
        eglDevice = (EGLGraphicsDevice) upstreamDevice;
        aConfig = upstreamConfig;
        if (DEBUG) {
          System.err.println(
              dbgPrefix
                  + "Reusing upstream eglDevice: "
                  + eglDevice
                  + ", using upstream config "
                  + aConfig.getClass().getSimpleName()
                  + " "
                  + aConfig);
        }
        if (EGL.EGL_NO_DISPLAY == eglDevice.getHandle()) {
          eglDevice.open();
          isEGLSurfaceValid = false;
          surface.addUpstreamOptionBits(ProxySurface.OPT_PROXY_OWNS_UPSTREAM_DEVICE);
        }
      } else {
        eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(upstreamSurface);
        eglDevice.open();
        aConfig = upstreamConfig;
        isEGLSurfaceValid = false;
        surface.addUpstreamOptionBits(ProxySurface.OPT_PROXY_OWNS_UPSTREAM_DEVICE);
      }
    }

    final GLCapabilitiesImmutable capsRequested =
        (GLCapabilitiesImmutable) aConfig.getRequestedCapabilities();
    final EGLGraphicsConfiguration eglConfig;
    if (aConfig instanceof EGLGraphicsConfiguration) {
      // Config is already in EGL type - reuse ..
      final EGLGLCapabilities capsChosen = (EGLGLCapabilities) aConfig.getChosenCapabilities();
      if (!isEGLSurfaceValid
          || !EGLGraphicsConfiguration.isEGLConfigValid(
              eglDevice.getHandle(), capsChosen.getEGLConfig())) {
        // 'refresh' the native EGLConfig handle
        capsChosen.setEGLConfig(
            EGLGraphicsConfiguration.EGLConfigId2EGLConfig(
                eglDevice.getHandle(), capsChosen.getEGLConfigID()));
        if (0 == capsChosen.getEGLConfig()) {
          throw new GLException(
              "Refreshing native EGLConfig handle failed with error "
                  + EGLContext.toHexString(EGL.eglGetError())
                  + ": "
                  + eglDevice
                  + ", "
                  + capsChosen
                  + " of "
                  + aConfig);
        }
        final AbstractGraphicsScreen eglScreen =
            new DefaultGraphicsScreen(eglDevice, aConfig.getScreen().getIndex());
        eglConfig = new EGLGraphicsConfiguration(eglScreen, capsChosen, capsRequested, null);
        if (DEBUG) {
          System.err.println(dbgPrefix + "Refreshing eglConfig: " + eglConfig);
        }
        isEGLSurfaceValid = false;
      } else {
        eglConfig = (EGLGraphicsConfiguration) aConfig;
        if (DEBUG) {
          System.err.println(dbgPrefix + "Reusing eglConfig: " + eglConfig);
        }
      }
    } else {
      final AbstractGraphicsScreen eglScreen =
          new DefaultGraphicsScreen(eglDevice, aConfig.getScreen().getIndex());
      eglConfig =
          EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(
              capsRequested,
              capsRequested,
              null,
              eglScreen,
              aConfig.getVisualID(VIDType.NATIVE),
              false /* forceTransparencyFlag */);

      if (null == eglConfig) {
        throw new GLException("Couldn't create EGLGraphicsConfiguration from " + eglScreen);
      } else if (DEBUG) {
        System.err.println(dbgPrefix + "Chosen eglConfig: " + eglConfig);
      }
      isEGLSurfaceValid = false;
    }
    surface.setGraphicsConfiguration(eglConfig);

    if (isEGLSurfaceValid) {
      isEGLSurfaceValid =
          EGLDrawable.isValidEGLSurface(eglDevice.getHandle(), upstreamSurface.getSurfaceHandle());
    }
    if (isEGLSurfaceValid) {
      surface.setSurfaceHandle(upstreamSurface.getSurfaceHandle());
      surface.clearUpstreamOptionBits(ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE);
      if (DEBUG) {
        System.err.println(
            dbgPrefix + "Fin: Already valid EGL surface - use as-is: " + upstreamSurface);
      }
    } else {
      surface.setSurfaceHandle(EGL.EGL_NO_SURFACE);
      surface.addUpstreamOptionBits(
          ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE); // create/destroy in EGLDrawable
      if (DEBUG) {
        System.err.println(dbgPrefix + "Fin: EGL surface n/a - TBD: " + upstreamSurface);
      }
    }
  }
Example #3
0
  /**
   * Moves all GLEventListenerState components from the given {@link GLAutoDrawable} to a newly
   * created instance.
   *
   * <p>Note that all components are removed from the {@link GLAutoDrawable}, i.e. the {@link
   * GLContext}, all {@link GLEventListener}.
   *
   * <p>If the {@link GLAutoDrawable} was added to a {@link GLAnimatorControl}, it is removed and
   * the {@link GLAnimatorControl} added to the GLEventListenerState.
   *
   * <p>The returned GLEventListenerState instance is the {@link #isOwner() owner of the
   * components}.
   *
   * @param a {@link GLAutoDrawable} source to move components from
   * @return new GLEventListenerState instance {@link #isOwner() owning} moved components.
   * @see #moveTo(GLAutoDrawable)
   */
  public static GLEventListenerState moveFrom(GLAutoDrawable a) {
    final int aSz = a.getGLEventListenerCount();

    // Create new AbstractGraphicsScreen w/ cloned AbstractGraphicsDevice for future GLAutoDrawable
    // allowing this AbstractGraphicsDevice to loose ownership -> not closing display/device!
    final NativeSurface aSurface = a.getNativeSurface();
    final AbstractGraphicsConfiguration aCfg = aSurface.getGraphicsConfiguration();
    final AbstractGraphicsScreen aScreen1 = aCfg.getScreen();
    final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) aCfg.getChosenCapabilities();
    final AbstractGraphicsScreen aScreen2 = cloneScreen(aScreen1);
    if (DEBUG) {
      System.err.println(
          "X00 NativeSurface:              " + aSurface.getClass().getName() + ", " + aSurface);
    }
    aScreen1.getDevice().clearHandleOwner(); // don't close device handle

    final AbstractGraphicsScreen aUpScreen2;
    {
      AbstractGraphicsScreen _aUpScreen2 = null;
      if (aSurface instanceof ProxySurface) {
        final ProxySurface aProxy = (ProxySurface) aSurface;
        final NativeSurface aUpSurface = aProxy.getUpstreamSurface();
        if (null != aUpSurface) {
          System.err.println(
              "X00 UpstreamSurface:            "
                  + aUpSurface.getClass().getName()
                  + ", "
                  + aUpSurface);
        }
        aProxy.clearUpstreamOptionBits(
            ProxySurface.OPT_PROXY_OWNS_UPSTREAM_DEVICE); // don't close device handle
        if (null != aUpSurface) {
          final AbstractGraphicsScreen aUpScreen1 =
              aUpSurface.getGraphicsConfiguration().getScreen();
          _aUpScreen2 = cloneScreen(aUpScreen1);
          if (null != aUpScreen1) {
            aUpScreen1.getDevice().clearHandleOwner(); // don't close device handle
          }
          System.err.println(
              "X0X NativeSurface:              " + aSurface.getClass().getName() + ", " + aSurface);
          System.err.println(
              "X0X UpstreamSurface:            "
                  + aUpSurface.getClass().getName()
                  + ", "
                  + aUpSurface);
        }
      }
      aUpScreen2 = _aUpScreen2;
    }

    final GLAnimatorControl aAnim = a.getAnimator();
    if (null != aAnim) {
      aAnim.remove(a); // also handles ECT
    }

    final GLEventListenerState glls =
        new GLEventListenerState(aUpScreen2, aScreen2, caps, a.getContext(), aSz, aAnim);

    //
    // remove and cache all GLEventListener and their init-state
    //
    for (int i = 0; i < aSz; i++) {
      final GLEventListener l = a.getGLEventListener(0);
      glls.listenersInit[i] = a.getGLEventListenerInitState(l);
      glls.listeners[i] = a.removeGLEventListener(l);
    }

    //
    // trigger glFinish to sync GL ctx
    //
    a.invoke(true, glFinish);

    a.setContext(null);

    return glls;
  }