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); } } }
/** * @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); }