private static List<GLCapabilitiesImmutable> getAvailableEGLConfigs( EGLGraphicsDevice eglDisplay, GLCapabilitiesImmutable caps) { final IntBuffer numConfigs = Buffers.newDirectIntBuffer(1); if (!EGL.eglGetConfigs(eglDisplay.getHandle(), null, 0, numConfigs)) { throw new GLException( "EGLDrawableFactory.getAvailableEGLConfigs: Get maxConfigs (eglGetConfigs) call failed, error " + EGLContext.toHexString(EGL.eglGetError())); } if (0 < numConfigs.get(0)) { final PointerBuffer configs = PointerBuffer.allocateDirect(numConfigs.get(0)); final IntBuffer attrs = EGLGraphicsConfiguration.GLCapabilities2AttribList(caps); final int winattrmask = GLGraphicsConfigurationUtil.getExclusiveWinAttributeBits(caps); if (EGL.eglChooseConfig( eglDisplay.getHandle(), attrs, configs, configs.capacity(), numConfigs) && numConfigs.get(0) > 0) { return EGLGraphicsConfigurationFactory.eglConfigs2GLCaps( eglDisplay, caps.getGLProfile(), configs, numConfigs.get(0), winattrmask, false /* forceTransparentFlag */); } } return new ArrayList<GLCapabilitiesImmutable>(0); }
void updateGraphicsConfiguration() { CapabilitiesImmutable capsChosen = getChosenCapabilities(); EGLGraphicsConfiguration newConfig = (EGLGraphicsConfiguration) GraphicsConfigurationFactory.getFactory(getScreen().getDevice(), capsChosen) .chooseGraphicsConfiguration( capsChosen, getRequestedCapabilities(), chooser, getScreen(), VisualIDHolder.VID_UNDEFINED); if (null != newConfig) { // FIXME: setScreen( ... ); setChosenCapabilities(newConfig.getChosenCapabilities()); if (DEBUG) { System.err.println("updateGraphicsConfiguration(1): " + this); } } }
protected static long createPBufferSurfaceImpl( EGLGraphicsConfiguration config, int width, int height, boolean useTexture) { final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) config.getScreen().getDevice(); final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) config.getChosenCapabilities(); final int texFormat; if (useTexture) { texFormat = caps.getAlphaBits() > 0 ? EGL.EGL_TEXTURE_RGBA : EGL.EGL_TEXTURE_RGB; } else { texFormat = EGL.EGL_NO_TEXTURE; } if (DEBUG) { System.out.println("Pbuffer config: " + config); } final IntBuffer attrs = EGLGraphicsConfiguration.CreatePBufferSurfaceAttribList(width, height, texFormat); final long surf = EGL.eglCreatePbufferSurface(eglDevice.getHandle(), config.getNativeConfig(), attrs); if (EGL.EGL_NO_SURFACE == surf) { throw new GLException( "Creation of window surface (eglCreatePbufferSurface) failed, dim " + width + "x" + height + ", " + eglDevice + ", " + config + ", error 0x" + Integer.toHexString(EGL.eglGetError())); } else if (DEBUG) { System.err.println("PBuffer setSurface result: eglSurface 0x" + Long.toHexString(surf)); } return surf; }
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); } } }
@Override protected void createNativeImpl() { Log.d( MD.TAG, "createNativeImpl 0 - surfaceHandle 0x" + Long.toHexString(surfaceHandle) + ", format [a " + androidFormat + ", n " + nativeFormat + "], " + getX() + "/" + getY() + " " + getWidth() + "x" + getHeight() + " - " + Thread.currentThread().getName()); if (0 != getParentWindowHandle()) { throw new NativeWindowException("Window parenting not supported (yet)"); } if (0 == surfaceHandle) { throw new InternalError("XXX"); } final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) getScreen().getDisplay().getGraphicsDevice(); final EGLGraphicsConfiguration eglConfig = EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic( capsByFormat, (GLCapabilitiesImmutable) getRequestedCapabilities(), (GLCapabilitiesChooser) capabilitiesChooser, getScreen().getGraphicsScreen(), nativeFormat, isAndroidFormatTransparent(androidFormat)); if (eglConfig == null) { throw new NativeWindowException( "Error choosing GraphicsConfiguration creating window: " + this); } final int nativeVisualID = eglConfig.getVisualID(VisualIDHolder.VIDType.NATIVE); Log.d(MD.TAG, "nativeVisualID 0x" + Integer.toHexString(nativeVisualID)); if (VisualIDHolder.VID_UNDEFINED != nativeVisualID) { setSurfaceVisualID0(surfaceHandle, nativeVisualID); } eglSurface = EGL.eglCreateWindowSurface( eglDevice.getHandle(), eglConfig.getNativeConfig(), surfaceHandle, null); if (EGL.EGL_NO_SURFACE == eglSurface) { throw new NativeWindowException( "Creation of window surface failed: " + eglConfig + ", surfaceHandle 0x" + Long.toHexString(surfaceHandle) + ", error " + toHexString(EGL.eglGetError())); } // propagate data .. setGraphicsConfiguration(eglConfig); setWindowHandle(surfaceHandle); focusChanged(false, true); Log.d(MD.TAG, "createNativeImpl X: eglSurfaceHandle 0x" + Long.toHexString(eglSurface)); }
@Override protected boolean createImpl(GLContextImpl shareWith) throws GLException { final EGLGraphicsConfiguration config = (EGLGraphicsConfiguration) drawable.getNativeSurface().getGraphicsConfiguration(); final long eglDisplay = config.getScreen().getDevice().getHandle(); final GLProfile glProfile = drawable.getGLProfile(); final long eglConfig = config.getNativeConfig(); long shareWithHandle = EGL.EGL_NO_CONTEXT; if (0 == eglDisplay) { throw new GLException( "Error: attempted to create an OpenGL context without a display connection"); } if (0 == eglConfig) { throw new GLException( "Error: attempted to create an OpenGL context without a graphics configuration"); } try { // might be unavailable on EGL < 1.2 if (!EGL.eglBindAPI(EGL.EGL_OPENGL_ES_API)) { throw new GLException( "Catched: eglBindAPI to ES failed , error 0x" + Integer.toHexString(EGL.eglGetError())); } } catch (GLException glex) { if (DEBUG) { glex.printStackTrace(); } } if (shareWith != null) { shareWithHandle = shareWith.getHandle(); if (shareWithHandle == 0) { throw new GLException("GLContextShareSet returned an invalid OpenGL context"); } } final IntBuffer contextAttrsNIO; { final int[] contextAttrs = new int[] {EGL.EGL_CONTEXT_CLIENT_VERSION, -1, EGL.EGL_NONE}; if (glProfile.usesNativeGLES2()) { contextAttrs[1] = 2; } else if (glProfile.usesNativeGLES1()) { contextAttrs[1] = 1; } else { throw new GLException("Error creating OpenGL context - invalid GLProfile: " + glProfile); } contextAttrsNIO = Buffers.newDirectIntBuffer(contextAttrs); } contextHandle = EGL.eglCreateContext(eglDisplay, eglConfig, shareWithHandle, contextAttrsNIO); if (contextHandle == 0) { throw new GLException( "Error creating OpenGL context: eglDisplay " + toHexString(eglDisplay) + ", eglConfig " + config + ", " + glProfile + ", shareWith " + toHexString(shareWithHandle) + ", error " + toHexString(EGL.eglGetError())); } if (DEBUG) { System.err.println( getThreadName() + ": Created OpenGL context 0x" + Long.toHexString(contextHandle) + ",\n\twrite surface 0x" + Long.toHexString(drawable.getHandle()) + ",\n\tread surface 0x" + Long.toHexString(drawableRead.getHandle()) + ",\n\t" + this + ",\n\tsharing with 0x" + Long.toHexString(shareWithHandle)); } if (!EGL.eglMakeCurrent( eglDisplay, drawable.getHandle(), drawableRead.getHandle(), contextHandle)) { throw new GLException( "Error making context " + toHexString(contextHandle) + " current: error code " + toHexString(EGL.eglGetError())); } setGLFunctionAvailability(true, glProfile.usesNativeGLES2() ? 2 : 1, 0, CTX_PROFILE_ES); return true; }