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); }
/** * @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 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; }
@Override public final ProxySurface createDummySurfaceImpl( AbstractGraphicsDevice deviceReq, boolean createNewDevice, GLCapabilitiesImmutable chosenCaps, GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height) { chosenCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(chosenCaps); return createMutableSurfaceImpl( deviceReq, createNewDevice, chosenCaps, requestedCaps, chooser, new X11DummyUpstreamSurfaceHook(width, height)); }
@Override public final ProxySurface createDummySurfaceImpl( AbstractGraphicsDevice deviceReq, boolean createNewDevice, GLCapabilitiesImmutable chosenCaps, GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height) { chosenCaps = GLGraphicsConfigurationUtil.fixGLPBufferGLCapabilities( chosenCaps); // complete validation in // EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(..) // above return createMutableSurfaceImpl( deviceReq, createNewDevice, chosenCaps, requestedCaps, chooser, new EGLDummyUpstreamSurfaceHook(width, height)); }
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); }
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); }
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; }
/** * @param defaultQuirks GLRendererQuirks of the EGLDrawableFactory's defaultDevice * @param device * @param glp desired GLProfile, may be null * @param config * @param winattrmask * @param forceTransparentFlag * @return */ public static EGLGLCapabilities EGLConfig2Capabilities( GLRendererQuirks defaultQuirks, EGLGraphicsDevice device, GLProfile glp, long config, int winattrmask, boolean forceTransparentFlag) { final long display = device.getHandle(); final int cfgID; final int rType; final int visualID; final int _attributes[] = { EGL.EGL_CONFIG_ID, // 0 EGL.EGL_RENDERABLE_TYPE, EGL.EGL_NATIVE_VISUAL_ID, EGL.EGL_CONFIG_CAVEAT, EGL.EGL_RED_SIZE, // 4 EGL.EGL_GREEN_SIZE, EGL.EGL_BLUE_SIZE, EGL.EGL_ALPHA_SIZE, // 7 EGL.EGL_STENCIL_SIZE, // 8 EGL.EGL_DEPTH_SIZE, EGL.EGL_TRANSPARENT_TYPE, // 10 EGL.EGL_TRANSPARENT_RED_VALUE, EGL.EGL_TRANSPARENT_GREEN_VALUE, EGL.EGL_TRANSPARENT_BLUE_VALUE, EGL.EGL_SAMPLES, // 14 EGLExt.EGL_COVERAGE_BUFFERS_NV, // 15 EGLExt.EGL_COVERAGE_SAMPLES_NV }; final IntBuffer attributes = Buffers.newDirectIntBuffer(_attributes); final IntBuffer values = Buffers.newDirectIntBuffer(attributes.remaining()); EGL.eglGetConfigAttributes(display, config, attributes, values); // get the configID if (EGL.EGL_CONFIG_ID != attributes.get(0)) { if (DEBUG) { // FIXME: this happens on a ATI PC Emulation .. System.err.println( dbgCfgFailIntro + "ConfigID" + dbgCfgFailForConfig + toHexString(config) + dbgCfgFailError + toHexString(EGL.eglGetError())); } return null; } cfgID = values.get(0); if (EGL.EGL_RENDERABLE_TYPE != attributes.get(1)) { if (DEBUG) { System.err.println( dbgCfgFailIntro + "EGL_RENDERABLE_TYPE" + dbgCfgFailForConfig + toHexString(config) + dbgCfgFailError + toHexString(EGL.eglGetError())); } return null; } { final int rTypeOrig = values.get(1); if (defaultQuirks.exist(GLRendererQuirks.GLES3ViaEGLES2Config) && 0 != (EGL.EGL_OPENGL_ES2_BIT & rTypeOrig)) { rType = rTypeOrig | EGLExt.EGL_OPENGL_ES3_BIT_KHR; } else { rType = rTypeOrig; } } if (EGL.EGL_NATIVE_VISUAL_ID == attributes.get(2)) { visualID = values.get(2); } else { if (DEBUG) { System.err.println( dbgCfgFailIntro + "EGL_NATIVE_VISUAL_ID" + dbgCfgFailForConfig + toHexString(config) + dbgCfgFailError + toHexString(EGL.eglGetError())); } visualID = VisualIDHolder.VID_UNDEFINED; } EGLGLCapabilities caps = null; try { if (null == glp) { glp = EGLGLCapabilities.getCompatible(device, rType); } if (!EGLGLCapabilities.isCompatible(glp, rType)) { if (DEBUG) { System.err.println( "config " + toHexString(config) + ": Requested GLProfile " + glp + " with quirks " + defaultQuirks + " not compatible with EGL-RenderableType[" + EGLGLCapabilities.renderableTypeToString(null, rType) + "]"); } return null; } caps = new EGLGLCapabilities(config, cfgID, visualID, glp, rType); } catch (GLException gle) { if (DEBUG) { System.err.println("config " + toHexString(config) + ": " + gle); } return null; } if (EGL.EGL_CONFIG_CAVEAT == attributes.get(3)) { if (EGL.EGL_SLOW_CONFIG == values.get(3)) { caps.setHardwareAccelerated(false); } } else if (DEBUG) { System.err.println( dbgCfgFailIntro + "EGL_CONFIG_CAVEAT" + dbgCfgFailForConfig + toHexString(config) + dbgCfgFailError + toHexString(EGL.eglGetError())); } // ALPHA shall be set at last - due to it's auto setting by the above (!opaque / samples) if (EGL.EGL_RED_SIZE == attributes.get(4)) { caps.setRedBits(values.get(4)); } else if (DEBUG) { System.err.println( dbgCfgFailIntro + "EGL_RED_SIZE" + dbgCfgFailForConfig + toHexString(config) + dbgCfgFailError + toHexString(EGL.eglGetError())); } if (EGL.EGL_GREEN_SIZE == attributes.get(5)) { caps.setGreenBits(values.get(5)); } else if (DEBUG) { System.err.println( dbgCfgFailIntro + "EGL_GREEN_SIZE" + dbgCfgFailForConfig + toHexString(config) + dbgCfgFailError + toHexString(EGL.eglGetError())); } if (EGL.EGL_BLUE_SIZE == attributes.get(6)) { caps.setBlueBits(values.get(6)); } else if (DEBUG) { System.err.println( dbgCfgFailIntro + "EGL_BLUE_SIZE" + dbgCfgFailForConfig + toHexString(config) + dbgCfgFailError + toHexString(EGL.eglGetError())); } if (EGL.EGL_ALPHA_SIZE == attributes.get(7)) { caps.setAlphaBits(values.get(7)); } else if (DEBUG) { System.err.println( dbgCfgFailIntro + "EGL_ALPHA_SIZE" + dbgCfgFailForConfig + toHexString(config) + dbgCfgFailError + toHexString(EGL.eglGetError())); } if (EGL.EGL_STENCIL_SIZE == attributes.get(8)) { caps.setStencilBits(values.get(8)); } else if (DEBUG) { System.err.println( dbgCfgFailIntro + "EGL_STENCIL_SIZE" + dbgCfgFailForConfig + toHexString(config) + dbgCfgFailError + toHexString(EGL.eglGetError())); } if (EGL.EGL_DEPTH_SIZE == attributes.get(9)) { caps.setDepthBits(values.get(9)); } else if (DEBUG) { System.err.println( dbgCfgFailIntro + "EGL_DEPTH_SIZE" + dbgCfgFailForConfig + toHexString(config) + dbgCfgFailError + toHexString(EGL.eglGetError())); } if (forceTransparentFlag) { caps.setBackgroundOpaque(false); } else if (EGL.EGL_TRANSPARENT_TYPE == attributes.get(10)) { caps.setBackgroundOpaque(values.get(10) != EGL.EGL_TRANSPARENT_RGB); } else if (DEBUG) { System.err.println( dbgCfgFailIntro + "EGL_TRANSPARENT_TYPE" + dbgCfgFailForConfig + toHexString(config) + dbgCfgFailError + toHexString(EGL.eglGetError())); } if (!caps.isBackgroundOpaque()) { if (EGL.EGL_TRANSPARENT_RED_VALUE == attributes.get(11)) { final int v = values.get(11); caps.setTransparentRedValue(EGL.EGL_DONT_CARE == v ? -1 : v); } else if (DEBUG) { System.err.println( dbgCfgFailIntro + "EGL_TRANSPARENT_RED_VALUE" + dbgCfgFailForConfig + toHexString(config) + dbgCfgFailError + toHexString(EGL.eglGetError())); } if (EGL.EGL_TRANSPARENT_GREEN_VALUE == attributes.get(12)) { final int v = values.get(12); caps.setTransparentGreenValue(EGL.EGL_DONT_CARE == v ? -1 : v); } else if (DEBUG) { System.err.println( dbgCfgFailIntro + "EGL_TRANSPARENT_GREEN_VALUE" + dbgCfgFailForConfig + toHexString(config) + dbgCfgFailError + toHexString(EGL.eglGetError())); } if (EGL.EGL_TRANSPARENT_BLUE_VALUE == attributes.get(13)) { final int v = values.get(13); caps.setTransparentBlueValue(EGL.EGL_DONT_CARE == v ? -1 : v); } else if (DEBUG) { System.err.println( dbgCfgFailIntro + "EGL_TRANSPARENT_BLUE_VALUE" + dbgCfgFailForConfig + toHexString(config) + dbgCfgFailError + toHexString(EGL.eglGetError())); } /** * Not defined in EGL if( EGL.EGL_TRANSPARENT_ALPHA_VALUE == attributes.get(??) ) { final int * v = values.get(??); caps.setTransparentAlphaValue(EGL.EGL_DONT_CARE==v?-1:v); } else * if(DEBUG) { * System.err.println(dbgStr01+"EGL_TRANSPARENT_ALPHA_VALUE"+dbgStr02+toHexString(config)+dbgEGLCfgFailError+toHexString(EGL.eglGetError())); * } */ } if (EGL.EGL_SAMPLES == attributes.get(14)) { final int numSamples = values.get(14); caps.setSampleBuffers(numSamples > 0 ? true : false); caps.setNumSamples(numSamples); } else if (DEBUG) { System.err.println( dbgCfgFailIntro + "EGL_SAMPLES" + dbgCfgFailForConfig + toHexString(config) + dbgCfgFailError + toHexString(EGL.eglGetError())); } if (!caps.getSampleBuffers()) { // try NV_coverage_sample extension if (EGLExt.EGL_COVERAGE_BUFFERS_NV == attributes.get(15)) { final boolean enabled = values.get(15) > 0; if (enabled && EGLExt.EGL_COVERAGE_SAMPLES_NV == attributes.get(16)) { caps.setSampleExtension(GLGraphicsConfigurationUtil.NV_coverage_sample); caps.setSampleBuffers(true); caps.setNumSamples(values.get(16)); } else if (DEBUG) { System.err.println( dbgCfgFailIntro + "EGL_COVERAGE_SAMPLES_NV" + dbgCfgFailForConfig + toHexString(config) + dbgCfgFailError + toHexString(EGL.eglGetError())); } } /** * else if(DEBUG) { // Not required - vendor extension - don't be verbose! * System.err.println(dbgCfgFailIntro+"EGL_COVERAGE_BUFFERS_NV"+dbgCfgFailForConfig+toHexString(config)+dbgCfgFailError+toHexString(EGL.eglGetError())); * } */ } // Since the passed GLProfile may be null, // we use EGL_RENDERABLE_TYPE derived profile as created in the EGLGLCapabilities constructor. final int availableTypeBits = EGLConfigDrawableTypeBits(device, config); final int drawableTypeBits = winattrmask & availableTypeBits; if (0 == drawableTypeBits) { return null; } return (EGLGLCapabilities) GLGraphicsConfigurationUtil.fixWinAttribBitsAndHwAccel(device, drawableTypeBits, caps); }