// Return a list of available and usable framebuffer configs // static GLboolean chooseFBConfigs(const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* desired, EGLConfig* result) { EGLConfig* nativeConfigs; _GLFWfbconfig* usableConfigs; const _GLFWfbconfig* closest; int i, nativeCount, usableCount; eglGetConfigs(_glfw.egl.display, NULL, 0, &nativeCount); if (!nativeCount) { _glfwInputError(GLFW_API_UNAVAILABLE, "EGL: No EGLConfigs returned"); return GL_FALSE; } nativeConfigs = calloc(nativeCount, sizeof(EGLConfig)); eglGetConfigs(_glfw.egl.display, nativeConfigs, nativeCount, &nativeCount); usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig)); usableCount = 0; for (i = 0; i < nativeCount; i++) { const EGLConfig n = nativeConfigs[i]; _GLFWfbconfig* u = usableConfigs + usableCount; #if defined(_GLFW_X11) if (!getConfigAttrib(n, EGL_NATIVE_VISUAL_ID)) { // Only consider EGLConfigs with associated visuals continue; } #endif // _GLFW_X11 if (!(getConfigAttrib(n, EGL_COLOR_BUFFER_TYPE) & EGL_RGB_BUFFER)) { // Only consider RGB(A) EGLConfigs continue; } if (!(getConfigAttrib(n, EGL_SURFACE_TYPE) & EGL_WINDOW_BIT)) { // Only consider window EGLConfigs continue; } if (ctxconfig->api == GLFW_OPENGL_ES_API) { if (ctxconfig->major == 1) { if (!(getConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES_BIT)) continue; } else { if (!(getConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES2_BIT)) continue; } } else if (ctxconfig->api == GLFW_OPENGL_API) { if (!(getConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_BIT)) continue; } u->redBits = getConfigAttrib(n, EGL_RED_SIZE); u->greenBits = getConfigAttrib(n, EGL_GREEN_SIZE); u->blueBits = getConfigAttrib(n, EGL_BLUE_SIZE); u->alphaBits = getConfigAttrib(n, EGL_ALPHA_SIZE); u->depthBits = getConfigAttrib(n, EGL_DEPTH_SIZE); u->stencilBits = getConfigAttrib(n, EGL_STENCIL_SIZE); u->samples = getConfigAttrib(n, EGL_SAMPLES); u->doublebuffer = GL_TRUE; u->egl = n; usableCount++; } closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount); if (closest) *result = closest->egl; free(nativeConfigs); free(usableConfigs); return closest ? GL_TRUE : GL_FALSE; }
static _GLFWfbconfig* getFBConfigs(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, unsigned int* found) { EGLConfig* configs; _GLFWfbconfig* result; int i, count = 0; *found = 0; eglGetConfigs(_glfw.egl.display, NULL, 0, &count); configs = (EGLConfig*) malloc(sizeof(EGLConfig) * count); if (!configs) { _glfwInputError(GLFW_OUT_OF_MEMORY, NULL); return NULL; } eglGetConfigs(_glfw.egl.display, configs, count, &count); if (!count) { free(configs); _glfwInputError(GLFW_API_UNAVAILABLE, "EGL: No EGLConfigs returned"); return NULL; } result = (_GLFWfbconfig*) malloc(sizeof(_GLFWfbconfig) * count); if (!result) { free(configs); _glfwInputError(GLFW_OUT_OF_MEMORY, NULL); return NULL; } for (i = 0; i < count; i++) { _GLFWfbconfig* f = result + *found; #if defined(_GLFW_X11) if (!getConfigAttrib(configs[i], EGL_NATIVE_VISUAL_ID)) { // Only consider EGLConfigs with associated visuals continue; } #endif // _GLFW_X11 if (!(getConfigAttrib(configs[i], EGL_COLOR_BUFFER_TYPE) & EGL_RGB_BUFFER)) { // Only consider RGB(A) EGLConfigs continue; } if (!(getConfigAttrib(configs[i], EGL_SURFACE_TYPE) & EGL_WINDOW_BIT)) { // Only consider window EGLConfigs continue; } if (wndconfig->clientAPI == GLFW_OPENGL_ES_API) { if (wndconfig->glMajor == 1) { if (!(getConfigAttrib(configs[i], EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES_BIT)) continue; } else { if (!(getConfigAttrib(configs[i], EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES2_BIT)) continue; } } else if (wndconfig->clientAPI == GLFW_OPENGL_API) { if (!(getConfigAttrib(configs[i], EGL_RENDERABLE_TYPE) & EGL_OPENGL_BIT)) continue; } f->redBits = getConfigAttrib(configs[i], EGL_RED_SIZE); f->greenBits = getConfigAttrib(configs[i], EGL_GREEN_SIZE); f->blueBits = getConfigAttrib(configs[i], EGL_BLUE_SIZE); f->alphaBits = getConfigAttrib(configs[i], EGL_ALPHA_SIZE); f->depthBits = getConfigAttrib(configs[i], EGL_DEPTH_SIZE); f->stencilBits = getConfigAttrib(configs[i], EGL_STENCIL_SIZE); f->samples = getConfigAttrib(configs[i], EGL_SAMPLES); // NOTE: There does not appear to be any way to request sRGB // framebuffers for OpenGL or GLES contexts; only for OpenVG ones f->sRGB = GL_FALSE; f->platformID = (GLFWintptr) getConfigAttrib(configs[i], EGL_CONFIG_ID); (*found)++; } free(configs); return result; }
egl::ConfigSet DisplayAndroid::generateConfigs() { egl::ConfigSet configSet; mConfigIds.clear(); EGLint numConfigs; EGLBoolean success = mEGL->chooseConfig(mConfigAttribList.data(), nullptr, 0, &numConfigs); ASSERT(success == EGL_TRUE && numConfigs > 0); std::vector<EGLConfig> configs(numConfigs); EGLint numConfigs2; success = mEGL->chooseConfig(mConfigAttribList.data(), configs.data(), numConfigs, &numConfigs2); ASSERT(success == EGL_TRUE && numConfigs2 == numConfigs); for (int i = 0; i < numConfigs; i++) { egl::Config config; getConfigAttrib(configs[i], EGL_BUFFER_SIZE, &config.bufferSize); getConfigAttrib(configs[i], EGL_RED_SIZE, &config.redSize); getConfigAttrib(configs[i], EGL_GREEN_SIZE, &config.greenSize); getConfigAttrib(configs[i], EGL_BLUE_SIZE, &config.blueSize); getConfigAttrib(configs[i], EGL_LUMINANCE_SIZE, &config.luminanceSize); getConfigAttrib(configs[i], EGL_ALPHA_SIZE, &config.alphaSize); getConfigAttrib(configs[i], EGL_ALPHA_MASK_SIZE, &config.alphaMaskSize); getConfigAttrib(configs[i], EGL_BIND_TO_TEXTURE_RGB, &config.bindToTextureRGB); getConfigAttrib(configs[i], EGL_BIND_TO_TEXTURE_RGBA, &config.bindToTextureRGBA); getConfigAttrib(configs[i], EGL_COLOR_BUFFER_TYPE, &config.colorBufferType); getConfigAttrib(configs[i], EGL_CONFIG_CAVEAT, &config.configCaveat); getConfigAttrib(configs[i], EGL_CONFIG_ID, &config.configID); getConfigAttrib(configs[i], EGL_CONFORMANT, &config.conformant); getConfigAttrib(configs[i], EGL_DEPTH_SIZE, &config.depthSize); getConfigAttrib(configs[i], EGL_LEVEL, &config.level); getConfigAttrib(configs[i], EGL_MAX_PBUFFER_WIDTH, &config.maxPBufferWidth); getConfigAttrib(configs[i], EGL_MAX_PBUFFER_HEIGHT, &config.maxPBufferHeight); getConfigAttrib(configs[i], EGL_MAX_PBUFFER_PIXELS, &config.maxPBufferPixels); getConfigAttrib(configs[i], EGL_MAX_SWAP_INTERVAL, &config.maxSwapInterval); getConfigAttrib(configs[i], EGL_MIN_SWAP_INTERVAL, &config.minSwapInterval); getConfigAttrib(configs[i], EGL_NATIVE_RENDERABLE, &config.nativeRenderable); getConfigAttrib(configs[i], EGL_NATIVE_VISUAL_ID, &config.nativeVisualID); getConfigAttrib(configs[i], EGL_NATIVE_VISUAL_TYPE, &config.nativeVisualType); getConfigAttrib(configs[i], EGL_RENDERABLE_TYPE, &config.renderableType); getConfigAttrib(configs[i], EGL_SAMPLE_BUFFERS, &config.sampleBuffers); getConfigAttrib(configs[i], EGL_SAMPLES, &config.samples); getConfigAttrib(configs[i], EGL_STENCIL_SIZE, &config.stencilSize); getConfigAttrib(configs[i], EGL_SURFACE_TYPE, &config.surfaceType); getConfigAttrib(configs[i], EGL_TRANSPARENT_TYPE, &config.transparentType); getConfigAttrib(configs[i], EGL_TRANSPARENT_RED_VALUE, &config.transparentRedValue); getConfigAttrib(configs[i], EGL_TRANSPARENT_GREEN_VALUE, &config.transparentGreenValue); getConfigAttrib(configs[i], EGL_TRANSPARENT_BLUE_VALUE, &config.transparentBlueValue); if (config.colorBufferType == EGL_RGB_BUFFER) { if (config.redSize == 8 && config.greenSize == 8 && config.blueSize == 8 && config.alphaSize == 8) { config.renderTargetFormat = GL_RGBA8; } else if (config.redSize == 8 && config.greenSize == 8 && config.blueSize == 8 && config.alphaSize == 0) { config.renderTargetFormat = GL_RGB8; } else if (config.redSize == 5 && config.greenSize == 6 && config.blueSize == 5 && config.alphaSize == 0) { config.renderTargetFormat = GL_RGB565; } else { UNREACHABLE(); } } else { UNREACHABLE(); } if (config.depthSize == 0 && config.stencilSize == 0) { config.depthStencilFormat = GL_ZERO; } else if (config.depthSize == 16 && config.stencilSize == 0) { config.depthStencilFormat = GL_DEPTH_COMPONENT16; } else if (config.depthSize == 24 && config.stencilSize == 0) { config.depthStencilFormat = GL_DEPTH_COMPONENT24; } else if (config.depthSize == 24 && config.stencilSize == 8) { config.depthStencilFormat = GL_DEPTH24_STENCIL8; } else if (config.depthSize == 0 && config.stencilSize == 8) { config.depthStencilFormat = GL_STENCIL_INDEX8; } else { UNREACHABLE(); } config.matchNativePixmap = EGL_NONE; config.optimalOrientation = 0; int internalId = configSet.add(config); mConfigIds[internalId] = config.configID; } return configSet; }