예제 #1
0
  @Override
  public final void create(ProxySurface surface) {
    final String dbgPrefix;
    if (DEBUG) {
      dbgPrefix =
          getThreadName()
              + ": EGLUpstreamSurfaceHook.create( up "
              + upstreamSurface.getClass().getSimpleName()
              + " -> this "
              + surface.getClass().getSimpleName()
              + " ): ";
      System.err.println(dbgPrefix + this);
    } else {
      dbgPrefix = null;
    }

    if (upstreamSurface instanceof ProxySurface) {
      // propagate createNotify(..) so upstreamSurface will be created
      ((ProxySurface) upstreamSurface).createNotify();
    }

    // lock upstreamSurface, so it can be used in case EGLDisplay is derived from it!
    if (NativeSurface.LOCK_SURFACE_NOT_READY >= upstreamSurface.lockSurface()) {
      throw new GLException("Could not lock: " + upstreamSurface);
    }
    try {
      evalUpstreamSurface(dbgPrefix, surface);
    } finally {
      upstreamSurface.unlockSurface();
    }
  }
예제 #2
0
 @Override
 public final synchronized void setRealized(boolean realizedArg) {
   if (realized != realizedArg) {
     if (DEBUG) {
       System.err.println(
           getThreadName()
               + ": setRealized: "
               + getClass().getSimpleName()
               + " "
               + realized
               + " -> "
               + realizedArg);
     }
     realized = realizedArg;
     AbstractGraphicsDevice aDevice = surface.getGraphicsConfiguration().getScreen().getDevice();
     if (realizedArg) {
       if (surface instanceof ProxySurface) {
         ((ProxySurface) surface).createNotify();
       }
       if (NativeSurface.LOCK_SURFACE_NOT_READY >= lockSurface()) {
         throw new GLException(
             "GLDrawableImpl.setRealized(true): Surface not ready (lockSurface)");
       }
     } else {
       aDevice.lock();
     }
     try {
       if (realizedArg) {
         setRealizedImpl();
         updateHandle();
       } else {
         destroyHandle();
         setRealizedImpl();
       }
     } finally {
       if (realizedArg) {
         unlockSurface();
       } else {
         aDevice.unlock();
         if (surface instanceof ProxySurface) {
           ((ProxySurface) surface).destroyNotify();
         }
       }
     }
   } else if (DEBUG) {
     System.err.println(
         getThreadName()
             + ": setRealized: "
             + getClass().getName()
             + " "
             + this.realized
             + " == "
             + realizedArg);
   }
 }
예제 #3
0
 @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();
   }
 }
예제 #4
0
  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);
      }
    }
  }
예제 #5
0
  /**
   * Moves all GLEventListenerState components to the given {@link GLAutoDrawable} from this
   * instance, while loosing {@link #isOwner() ownership}.
   *
   * <p>If the previous {@link GLAutoDrawable} was removed from a {@link GLAnimatorControl} by
   * previous {@link #moveFrom(GLAutoDrawable)}, the given {@link GLAutoDrawable} is added to the
   * cached {@link GLAnimatorControl}. This operation is skipped, if the given {@link
   * GLAutoDrawable} is already added to a {@link GLAnimatorControl} instance.
   *
   * <p>Note: After this operation, the GLEventListenerState reference should be released.
   *
   * @param a {@link GLAutoDrawable} destination to move GLEventListenerState components to
   * @throws GLException if the {@link GLAutoDrawable}'s configuration is incompatible, i.e.
   *     different {@link GLCapabilitiesImmutable}.
   * @see #moveFrom(GLAutoDrawable)
   * @see #isOwner()
   */
  public final void moveTo(GLAutoDrawable a) {
    final List<GLRunnable> aGLCmds = new ArrayList<GLRunnable>();
    final int aSz = listenerCount();

    final NativeSurface aSurface = a.getNativeSurface();
    final MutableGraphicsConfiguration aCfg =
        (MutableGraphicsConfiguration) aSurface.getGraphicsConfiguration();
    final GLCapabilitiesImmutable aCaps = (GLCapabilitiesImmutable) aCfg.getChosenCapabilities();
    if (caps.getVisualID(VisualIDHolder.VIDType.INTRINSIC)
            != aCaps.getVisualID(VisualIDHolder.VIDType.INTRINSIC)
        || caps.getVisualID(VisualIDHolder.VIDType.NATIVE)
            != aCaps.getVisualID(VisualIDHolder.VIDType.NATIVE)) {
      throw new GLException(
          "Incompatible Capabilities - Prev-Holder: " + caps + ", New-Holder " + caps);
    }
    // Destroy and remove currently associated GLContext, if any (will be replaced)
    {
      final GLContext ctx = a.getContext();
      if (null != ctx) {
        ctx.destroy();
      }
      a.setContext(null);
    }
    final boolean aRealized = a.isRealized();
    if (aRealized) {
      a.setRealized(false);
    }
    // Set new Screen and close previous one
    {
      if (DEBUG) {
        System.err.println(
            "XX0 NativeSurface:              " + aSurface.getClass().getName() + ", " + aSurface);
      }
      final AbstractGraphicsScreen aScreen1 = aCfg.getScreen();
      aCfg.setScreen(screen);
      aScreen1.getDevice().close();
      System.err.println(
          "XXX NativeSurface:              " + aSurface.getClass().getName() + ", " + aSurface);
    }
    // If using a ProxySurface w/ an upstream surface, set new Screen and close previous one on it
    {
      boolean upstreamSet = false;
      if (aSurface instanceof ProxySurface) {
        final ProxySurface aProxy = (ProxySurface) aSurface;
        final NativeSurface aUpSurface = aProxy.getUpstreamSurface();
        if (null != aUpSurface) {
          final MutableGraphicsConfiguration aUpCfg =
              (MutableGraphicsConfiguration) aUpSurface.getGraphicsConfiguration();
          final AbstractGraphicsScreen aUpScreen1 = aUpCfg.getScreen();
          if (null != upstreamScreen) {
            System.err.println(
                "XX0 UpstreamSurface:            "
                    + aUpSurface.getClass().getName()
                    + ", "
                    + aUpSurface);
            aUpCfg.setScreen(upstreamScreen);
            aUpScreen1.getDevice().close();
            upstreamSet = true;
            System.err.println(
                "XXX UpstreamSurface:            "
                    + aUpSurface.getClass().getName()
                    + ", "
                    + aUpSurface);
          } else {
            throw new GLException(
                "Incompatible Surface config - Has Upstream-Surface: Prev-Holder = false, New-Holder = true");
          }
        }
      }
      if (!upstreamSet && null != upstreamScreen) {
        throw new GLException(
            "Incompatible Surface config - Has Upstream-Surface: Prev-Holder = true, New-Holder = false");
      }
    }

    if (aRealized) {
      a.setRealized(true);
    }
    final boolean surfaceLocked =
        false; // NativeSurface.LOCK_SURFACE_NOT_READY < aSurface.lockSurface();
    try {
      a.setContext(context);
    } finally {
      if (surfaceLocked) {
        aSurface.unlockSurface();
      }
    }
    owner = false;

    //
    // Trigger GL-Viewport reset and reshape of all initialized GLEventListeners
    //
    aGLCmds.add(setViewport);
    for (int i = 0; i < aSz; i++) {
      if (listenersInit[i]) {
        aGLCmds.add(new ReshapeGLEventListener(listeners[i]));
      }
    }
    aGLCmds.add(glFinish);
    a.invoke(aRealized, aGLCmds); // only wait if already realized

    // add all cached GLEventListener to their destination and fix their init-state
    for (int i = 0; i < aSz; i++) {
      final GLEventListener l = listeners[i];
      a.addGLEventListener(l);
      a.setGLEventListenerInitState(l, listenersInit[i]);
      listeners[i] = null;
    }

    if (null != anim && null == a.getAnimator()) {
      anim.add(a); // also handles ECT
    }
  }
예제 #6
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;
  }
예제 #7
0
  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;
  }