in tools/gpu-dump.c [285:445]
void report_gles_attributes(void) {
void* libEGL = NULL;
EGLConfig* configs = NULL;
EGLDisplay display = EGL_NO_DISPLAY;
EGLSurface surface = EGL_NO_SURFACE;
EGLContext context = EGL_NO_CONTEXT;
EGLBoolean egl_init_status = EGL_FALSE;
EGLBoolean egl_make_current_status = EGL_FALSE;
EGLBoolean egl_status;
libEGL = dlopen("libEGL.so", RTLD_LAZY | RTLD_LOCAL);
display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if (display == EGL_NO_DISPLAY) {
fprintf(stderr, "failed to get default EGL display\n");
goto cleanup;
}
EGLint egl_major = 0, egl_minor = 0;
egl_init_status = eglInitialize(display, &egl_major, &egl_minor);
if (egl_init_status != EGL_TRUE) {
fprintf(stderr, "failed to initialize EGL display connection\n");
goto cleanup;
}
printf("initialized display connection with EGL %d.%d\n", (int) egl_major, (int) egl_minor);
EGLint configs_count = 0;
egl_status = eglGetConfigs(display, NULL, 0, &configs_count);
if (egl_status != EGL_TRUE) {
fprintf(stderr, "failed to get the number of EGL frame buffer configurations\n");
goto cleanup;
}
configs = (EGLConfig*) malloc(configs_count * sizeof(EGLConfig));
if (configs == NULL) {
fprintf(stderr, "failed to allocate %zu bytes for %d frame buffer configurations\n",
configs_count * sizeof(EGLConfig), configs_count);
goto cleanup;
}
egl_status = eglGetConfigs(display, configs, configs_count, &configs_count);
if (egl_status != EGL_TRUE || configs_count == 0) {
fprintf(stderr, "failed to get EGL frame buffer configurations\n");
goto cleanup;
}
printf("EGL framebuffer configurations:\n");
for (EGLint i = 0; i < configs_count; i++) {
printf("\tConfiguration #%d:\n", (int) i);
for (size_t n = 0; n < COUNT_OF(egl_config_attributes); n++) {
EGLint value = 0;
egl_status = eglGetConfigAttrib(display, configs[i], egl_config_attributes[n].id, &value);
if (egl_config_attributes[n].cardinality == 0) {
printf("\t\t%s: %d\n", egl_config_attributes[n].name, (int) value);
} else if (egl_config_attributes[n].cardinality > 0) {
/* Enumeration */
bool known_value = false;
for (size_t k = 0; k < (size_t) egl_config_attributes[n].cardinality; k++) {
if (egl_config_attributes[n].values[k].id == value) {
printf("\t\t%s: %s\n", egl_config_attributes[n].name, egl_config_attributes[n].values[k].name);
known_value = true;
break;
}
}
if (!known_value) {
printf("\t\t%s: unknown (%d)\n", egl_config_attributes[n].name, value);
}
} else {
/* Bitfield */
printf("\t\t%s: ", egl_config_attributes[n].name);
if (value == 0) {
printf("none\n");
} else {
for (size_t k = 0; k < (size_t) -egl_config_attributes[n].cardinality; k++) {
if (egl_config_attributes[n].values[k].id & value) {
value &= ~egl_config_attributes[n].values[k].id;
if (value != 0) {
printf("%s | ", egl_config_attributes[n].values[k].name);
} else {
printf("%s\n", egl_config_attributes[n].values[k].name);
}
}
}
if (value != 0) {
printf("0x%08X\n", (int) value);
}
}
}
}
}
EGLint const config_attributes[] = {
EGL_BIND_TO_TEXTURE_RGBA, EGL_TRUE,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_CONFORMANT, EGL_OPENGL_ES2_BIT,
EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
EGL_NONE,
};
EGLConfig config = NULL;
EGLint config_count = 0;
egl_status = eglChooseConfig(display, config_attributes, &config, 1, &config_count);
if (egl_status != EGL_TRUE || config_count == 0 || config == NULL) {
fprintf(stderr, "failed to find EGL frame buffer configuration that match required attributes\n");
goto cleanup;
}
EGLint const surface_attributes[] = {
EGL_HEIGHT, 1,
EGL_WIDTH, 1,
EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,
EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,
EGL_NONE,
};
surface = eglCreatePbufferSurface(display, config, surface_attributes);
if (surface == EGL_NO_SURFACE) {
fprintf(stderr, "failed to create PBuffer surface\n");
goto cleanup;
}
EGLint const context_attributes[] = {
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE,
};
context = eglCreateContext(display, config, EGL_NO_CONTEXT, context_attributes);
if (context == EGL_NO_CONTEXT) {
fprintf(stderr, "failed to create OpenGL ES context\n");
goto cleanup;
}
egl_make_current_status = eglMakeCurrent(display, surface, surface, context);
if (egl_make_current_status != EGL_TRUE) {
fprintf(stderr, "failed to attach OpenGL ES rendering context\n");
goto cleanup;
}
printf("OpenGL ES Attributes:\n");
printf("\t%s: \"%s\"\n", "GL_VENDOR", glGetString(GL_VENDOR));
printf("\t%s: \"%s\"\n", "GL_RENDERER", glGetString(GL_RENDERER));
printf("\t%s: \"%s\"\n", "GL_VERSION", glGetString(GL_VERSION));
printf("\t%s: \"%s\"\n", "GL_SHADING_LANGUAGE_VERSION", glGetString(GL_SHADING_LANGUAGE_VERSION));
printf("\t%s: \"%s\"\n", "GL_EXTENSIONS", glGetString(GL_EXTENSIONS));
cleanup:
if (egl_make_current_status == EGL_TRUE) {
eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
}
if (context != EGL_NO_CONTEXT) {
eglDestroyContext(display, context);
}
if (surface != EGL_NO_SURFACE) {
eglDestroySurface(display, surface);
}
if (egl_init_status == EGL_TRUE) {
eglTerminate(display);
}
free(configs);
if (libEGL != NULL) {
dlclose(libEGL);
}
}