static EGLBoolean haiku_add_configs_for_visuals(_EGLDisplay *dpy) { printf("Adding configs\n"); struct haiku_egl_config* conf; conf = CALLOC_STRUCT(haiku_egl_config); _eglInitConfig(&conf->base, dpy, 1); _eglLog(_EGL_DEBUG,"Config inited\n"); _eglSetConfigKey(&conf->base, EGL_RED_SIZE, 8); _eglSetConfigKey(&conf->base, EGL_BLUE_SIZE, 8); _eglSetConfigKey(&conf->base, EGL_GREEN_SIZE, 8); _eglSetConfigKey(&conf->base, EGL_LUMINANCE_SIZE, 0); _eglSetConfigKey(&conf->base, EGL_ALPHA_SIZE, 8); _eglSetConfigKey(&conf->base, EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER); EGLint r = (_eglGetConfigKey(&conf->base, EGL_RED_SIZE) + _eglGetConfigKey(&conf->base, EGL_GREEN_SIZE) + _eglGetConfigKey(&conf->base, EGL_BLUE_SIZE) + _eglGetConfigKey(&conf->base, EGL_ALPHA_SIZE)); _eglSetConfigKey(&conf->base, EGL_BUFFER_SIZE, r); _eglSetConfigKey(&conf->base, EGL_CONFIG_CAVEAT, EGL_NONE); _eglSetConfigKey(&conf->base, EGL_CONFIG_ID, 1); _eglSetConfigKey(&conf->base, EGL_BIND_TO_TEXTURE_RGB, EGL_FALSE); _eglSetConfigKey(&conf->base, EGL_BIND_TO_TEXTURE_RGBA, EGL_FALSE); _eglSetConfigKey(&conf->base, EGL_STENCIL_SIZE, 0); _eglSetConfigKey(&conf->base, EGL_TRANSPARENT_TYPE, EGL_NONE); _eglSetConfigKey(&conf->base, EGL_NATIVE_RENDERABLE, EGL_TRUE); // Let's say yes _eglSetConfigKey(&conf->base, EGL_NATIVE_VISUAL_ID, 0); // No visual _eglSetConfigKey(&conf->base, EGL_NATIVE_VISUAL_TYPE, EGL_NONE); // No visual _eglSetConfigKey(&conf->base, EGL_RENDERABLE_TYPE, 0x8); _eglSetConfigKey(&conf->base, EGL_SAMPLE_BUFFERS, 0); // TODO: How to get the right value ? _eglSetConfigKey(&conf->base, EGL_SAMPLES, _eglGetConfigKey(&conf->base, EGL_SAMPLE_BUFFERS) == 0 ? 0 : 0); _eglSetConfigKey(&conf->base, EGL_DEPTH_SIZE, 24); // TODO: How to get the right value ? _eglSetConfigKey(&conf->base, EGL_LEVEL, 0); _eglSetConfigKey(&conf->base, EGL_MAX_PBUFFER_WIDTH, 0); // TODO: How to get the right value ? _eglSetConfigKey(&conf->base, EGL_MAX_PBUFFER_HEIGHT, 0); // TODO: How to get the right value ? _eglSetConfigKey(&conf->base, EGL_MAX_PBUFFER_PIXELS, 0); // TODO: How to get the right value ? _eglSetConfigKey(&conf->base, EGL_SURFACE_TYPE, EGL_WINDOW_BIT /*| EGL_PIXMAP_BIT | EGL_PBUFFER_BIT*/); printf("Config configuated\n"); if (!_eglValidateConfig(&conf->base, EGL_FALSE)) { _eglLog(_EGL_DEBUG, "Haiku failed to validate config"); return EGL_FALSE; } printf("Validated config\n"); _eglLinkConfig(&conf->base); if (!_eglGetArraySize(dpy->Configs)) { _eglLog(_EGL_WARNING, "Haiku: failed to create any config"); return EGL_FALSE; } printf("Config successful!\n"); return EGL_TRUE; }
/** * Initialize a criteria config from the given attribute list. * Return EGL_FALSE if any of the attribute is invalid. */ EGLBoolean _eglParseConfigAttribList(_EGLConfig *conf, _EGLDisplay *dpy, const EGLint *attrib_list) { EGLint attr, val, i; _eglInitConfig(conf, dpy, EGL_DONT_CARE); /* reset to default values */ for (i = 0; i < ARRAY_SIZE(_eglValidationTable); i++) { attr = _eglValidationTable[i].attr; val = _eglValidationTable[i].default_value; _eglSetConfigKey(conf, attr, val); } /* parse the list */ for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i += 2) { attr = attrib_list[i]; val = attrib_list[i + 1]; if (!_eglIsConfigAttribValid(conf, attr)) return EGL_FALSE; _eglSetConfigKey(conf, attr, val); } if (!_eglValidateConfig(conf, EGL_TRUE)) return EGL_FALSE; /* EGL_LEVEL and EGL_MATCH_NATIVE_PIXMAP cannot be EGL_DONT_CARE */ if (conf->Level == EGL_DONT_CARE || conf->MatchNativePixmap == EGL_DONT_CARE) return EGL_FALSE; /* ignore other attributes when EGL_CONFIG_ID is given */ if (conf->ConfigID != EGL_DONT_CARE) { for (i = 0; i < ARRAY_SIZE(_eglValidationTable); i++) { attr = _eglValidationTable[i].attr; if (attr != EGL_CONFIG_ID) _eglSetConfigKey(conf, attr, EGL_DONT_CARE); } } else { if (!(conf->SurfaceType & EGL_WINDOW_BIT)) conf->NativeVisualType = EGL_DONT_CARE; if (conf->TransparentType == EGL_NONE) { conf->TransparentRedValue = EGL_DONT_CARE; conf->TransparentGreenValue = EGL_DONT_CARE; conf->TransparentBlueValue = EGL_DONT_CARE; } } return EGL_TRUE; }
/** * Create the EGLConfigs. (one per X visual) */ static void create_configs(_EGLDriver *drv, EGLDisplay dpy) { static const EGLint all_apis = (EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT | EGL_OPENVG_BIT | EGL_OPENGL_BIT); _EGLDisplay *disp = _eglLookupDisplay(dpy); XVisualInfo *visInfo, visTemplate; int num_visuals, i; /* get list of all X visuals, create an EGL config for each */ visTemplate.screen = DefaultScreen(disp->Xdpy); visInfo = XGetVisualInfo(disp->Xdpy, VisualScreenMask, &visTemplate, &num_visuals); if (!visInfo) { printf("egl_xlib.c: couldn't get any X visuals\n"); abort(); } for (i = 0; i < num_visuals; i++) { _EGLConfig *config = calloc(1, sizeof(_EGLConfig)); int id = i + 1; int rbits = bitcount(visInfo[i].red_mask); int gbits = bitcount(visInfo[i].green_mask); int bbits = bitcount(visInfo[i].blue_mask); int abits = bbits == 8 ? 8 : 0; int zbits = 24; int sbits = 8; int visid = visInfo[i].visualid; #if defined(__cplusplus) || defined(c_plusplus) int vistype = visInfo[i].c_class; #else int vistype = visInfo[i].class; #endif _eglInitConfig(config, id); SET_CONFIG_ATTRIB(config, EGL_BUFFER_SIZE, rbits + gbits + bbits + abits); SET_CONFIG_ATTRIB(config, EGL_RED_SIZE, rbits); SET_CONFIG_ATTRIB(config, EGL_GREEN_SIZE, gbits); SET_CONFIG_ATTRIB(config, EGL_BLUE_SIZE, bbits); SET_CONFIG_ATTRIB(config, EGL_ALPHA_SIZE, abits); SET_CONFIG_ATTRIB(config, EGL_DEPTH_SIZE, zbits); SET_CONFIG_ATTRIB(config, EGL_STENCIL_SIZE, sbits); SET_CONFIG_ATTRIB(config, EGL_NATIVE_VISUAL_ID, visid); SET_CONFIG_ATTRIB(config, EGL_NATIVE_VISUAL_TYPE, vistype); SET_CONFIG_ATTRIB(config, EGL_NATIVE_RENDERABLE, EGL_FALSE); SET_CONFIG_ATTRIB(config, EGL_CONFORMANT, all_apis); SET_CONFIG_ATTRIB(config, EGL_RENDERABLE_TYPE, all_apis); SET_CONFIG_ATTRIB(config, EGL_SURFACE_TYPE, EGL_WINDOW_BIT); _eglAddConfig(disp, config); } }
/** * Add configs to display and return the next config ID. */ static EGLint egl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id) { struct egl_g3d_display *gdpy = egl_g3d_display(dpy); const struct native_config **native_configs; enum pipe_format depth_stencil_formats[8]; int num_formats, num_configs, i, j; int preserve_buffer, max_swap_interval, premultiplied_alpha; native_configs = gdpy->native->get_configs(gdpy->native, &num_configs); if (!num_configs) { if (native_configs) FREE(native_configs); return id; } preserve_buffer = gdpy->native->get_param(gdpy->native, NATIVE_PARAM_PRESERVE_BUFFER); max_swap_interval = gdpy->native->get_param(gdpy->native, NATIVE_PARAM_MAX_SWAP_INTERVAL); premultiplied_alpha = gdpy->native->get_param(gdpy->native, NATIVE_PARAM_PREMULTIPLIED_ALPHA); num_formats = egl_g3d_fill_depth_stencil_formats(dpy, depth_stencil_formats); for (i = 0; i < num_configs; i++) { for (j = 0; j < num_formats; j++) { struct egl_g3d_config *gconf; gconf = CALLOC_STRUCT(egl_g3d_config); if (gconf) { _eglInitConfig(&gconf->base, dpy, id); if (!egl_g3d_init_config(drv, dpy, &gconf->base, native_configs[i], depth_stencil_formats[j], preserve_buffer, max_swap_interval, premultiplied_alpha)) { FREE(gconf); break; } _eglLinkConfig(&gconf->base); id++; } } } FREE(native_configs); return id; }
static EGLBoolean convert_config(_EGLConfig *conf, EGLint id, const __GLcontextModes *m) { static const EGLint all_apis = (EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT | EGL_OPENVG_BIT | EGL_OPENGL_BIT); EGLint val; _eglInitConfig(conf, id); if (!_eglConfigFromContextModesRec(conf, m, all_apis, all_apis)) return EGL_FALSE; if (m->doubleBufferMode) { /* pixmap and pbuffer surfaces are always single-buffered */ val = GET_CONFIG_ATTRIB(conf, EGL_SURFACE_TYPE); val &= ~(EGL_PIXMAP_BIT | EGL_PBUFFER_BIT); SET_CONFIG_ATTRIB(conf, EGL_SURFACE_TYPE, val); } else { /* EGL requires OpenGL ES context to be double-buffered */ val = GET_CONFIG_ATTRIB(conf, EGL_RENDERABLE_TYPE); val &= ~(EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT); SET_CONFIG_ATTRIB(conf, EGL_RENDERABLE_TYPE, val); } /* skip "empty" config */ if (!val) return EGL_FALSE; val = GET_CONFIG_ATTRIB(conf, EGL_SURFACE_TYPE); if (!(val & EGL_PBUFFER_BIT)) { /* bind-to-texture cannot be EGL_TRUE without pbuffer bit */ SET_CONFIG_ATTRIB(conf, EGL_BIND_TO_TEXTURE_RGB, EGL_FALSE); SET_CONFIG_ATTRIB(conf, EGL_BIND_TO_TEXTURE_RGBA, EGL_FALSE); } /* EGL_NATIVE_RENDERABLE is a boolean */ val = GET_CONFIG_ATTRIB(conf, EGL_NATIVE_RENDERABLE); if (val != EGL_TRUE) SET_CONFIG_ATTRIB(conf, EGL_NATIVE_RENDERABLE, EGL_FALSE); return _eglValidateConfig(conf, EGL_FALSE); }
/** * Typical fallback routine for eglChooseConfig */ EGLBoolean _eglChooseConfig(_EGLDriver *drv, _EGLDisplay *disp, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_configs) { _EGLConfig **configList, criteria; EGLint i, count; if (!num_configs) return _eglError(EGL_BAD_PARAMETER, "eglChooseConfigs"); _eglInitConfig(&criteria, disp, 0); if (!_eglParseConfigAttribList(&criteria, attrib_list)) return _eglError(EGL_BAD_ATTRIBUTE, "eglChooseConfig"); /* allocate array of config pointers */ configList = (_EGLConfig **) malloc(disp->NumConfigs * sizeof(_EGLConfig *)); if (!configList) return _eglError(EGL_BAD_ALLOC, "eglChooseConfig(out of memory)"); /* perform selection of configs */ count = 0; for (i = 0; i < disp->NumConfigs; i++) { if (_eglMatchConfig(disp->Configs[i], &criteria)) configList[count++] = disp->Configs[i]; } /* perform sorting of configs */ if (configs && count) { _eglSortConfigs((const _EGLConfig **) configList, count, _eglFallbackCompare, (void *) &criteria); count = MIN2(count, config_size); for (i = 0; i < count; i++) configs[i] = _eglGetConfigHandle(configList[i]); } free(configList); *num_configs = count; return EGL_TRUE; }
EGLBoolean drm_initialize(_EGLDriver *drv, _EGLDisplay *disp, EGLint *major, EGLint *minor) { struct drm_device *dev; struct drm_screen *screen = NULL; drmModeConnectorPtr connector = NULL; drmModeResPtr res = NULL; unsigned count_connectors = 0; int num_screens = 0; EGLint i; int fd; _EGLConfig *config; dev = (struct drm_device *) calloc(1, sizeof(struct drm_device)); if (!dev) return EGL_FALSE; dev->api = drm_api_create(); /* try the first node */ fd = drm_open_minor(0); if (fd < 0) goto err_fd; dev->drmFD = fd; drm_get_device_id(dev); dev->screen = dev->api->create_screen(dev->api, dev->drmFD, NULL); if (!dev->screen) goto err_screen; dev->winsys = dev->screen->winsys; driInitExtensions(NULL, NULL, GL_FALSE); drm_update_res(dev); res = dev->res; if (res) count_connectors = res->count_connectors; else _eglLog(_EGL_WARNING, "Could not retrive kms information\n"); for(i = 0; i < count_connectors && i < MAX_SCREENS; i++) { connector = drmModeGetConnector(fd, res->connectors[i]); if (!connector) continue; if (connector->connection != DRM_MODE_CONNECTED) { drmModeFreeConnector(connector); continue; } screen = malloc(sizeof(struct drm_screen)); memset(screen, 0, sizeof(*screen)); screen->connector = connector; screen->connectorID = connector->connector_id; _eglInitScreen(&screen->base); _eglAddScreen(disp, &screen->base); drm_add_modes_from_connector(&screen->base, connector); drm_find_dpms(dev, screen); dev->screens[num_screens++] = screen; } dev->count_screens = num_screens; disp->DriverData = dev; /* for now we only have one config */ config = calloc(1, sizeof(*config)); memset(config, 1, sizeof(*config)); _eglInitConfig(config, 1); _eglSetConfigAttrib(config, EGL_RED_SIZE, 8); _eglSetConfigAttrib(config, EGL_GREEN_SIZE, 8); _eglSetConfigAttrib(config, EGL_BLUE_SIZE, 8); _eglSetConfigAttrib(config, EGL_ALPHA_SIZE, 8); _eglSetConfigAttrib(config, EGL_BUFFER_SIZE, 32); _eglSetConfigAttrib(config, EGL_DEPTH_SIZE, 24); _eglSetConfigAttrib(config, EGL_STENCIL_SIZE, 8); _eglSetConfigAttrib(config, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT); _eglAddConfig(disp, config); disp->ClientAPIsMask = EGL_OPENGL_BIT /*| EGL_OPENGL_ES_BIT*/; /* enable supported extensions */ disp->Extensions.MESA_screen_surface = EGL_TRUE; disp->Extensions.MESA_copy_context = EGL_TRUE; *major = 1; *minor = 4; return EGL_TRUE; err_screen: drmClose(fd); err_fd: free(dev); return EGL_FALSE; }
struct dri2_egl_config * dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id, int depth, EGLint surface_type, const EGLint *attr_list, const unsigned int *rgba_masks) { struct dri2_egl_config *conf; struct dri2_egl_display *dri2_dpy; _EGLConfig base; unsigned int attrib, value, double_buffer; EGLint key, bind_to_texture_rgb, bind_to_texture_rgba; unsigned int dri_masks[4] = { 0, 0, 0, 0 }; _EGLConfig *matching_config; EGLint num_configs = 0; EGLint config_id; int i; dri2_dpy = disp->DriverData; _eglInitConfig(&base, disp, id); i = 0; double_buffer = 0; bind_to_texture_rgb = 0; bind_to_texture_rgba = 0; while (dri2_dpy->core->indexConfigAttrib(dri_config, i++, &attrib, &value)) { switch (attrib) { case __DRI_ATTRIB_RENDER_TYPE: if (value & __DRI_ATTRIB_RGBA_BIT) value = EGL_RGB_BUFFER; else if (value & __DRI_ATTRIB_LUMINANCE_BIT) value = EGL_LUMINANCE_BUFFER; else /* not valid */; _eglSetConfigKey(&base, EGL_COLOR_BUFFER_TYPE, value); break; case __DRI_ATTRIB_CONFIG_CAVEAT: if (value & __DRI_ATTRIB_NON_CONFORMANT_CONFIG) value = EGL_NON_CONFORMANT_CONFIG; else if (value & __DRI_ATTRIB_SLOW_BIT) value = EGL_SLOW_CONFIG; else value = EGL_NONE; _eglSetConfigKey(&base, EGL_CONFIG_CAVEAT, value); break; case __DRI_ATTRIB_BIND_TO_TEXTURE_RGB: bind_to_texture_rgb = value; break; case __DRI_ATTRIB_BIND_TO_TEXTURE_RGBA: bind_to_texture_rgba = value; break; case __DRI_ATTRIB_DOUBLE_BUFFER: double_buffer = value; break; case __DRI_ATTRIB_RED_MASK: dri_masks[0] = value; break; case __DRI_ATTRIB_GREEN_MASK: dri_masks[1] = value; break; case __DRI_ATTRIB_BLUE_MASK: dri_masks[2] = value; break; case __DRI_ATTRIB_ALPHA_MASK: dri_masks[3] = value; break; default: key = dri2_to_egl_attribute_map[attrib]; if (key != 0) _eglSetConfigKey(&base, key, value); break; } } if (attr_list) for (i = 0; attr_list[i] != EGL_NONE; i += 2) _eglSetConfigKey(&base, attr_list[i], attr_list[i+1]); if (depth > 0 && depth != base.BufferSize) return NULL; if (rgba_masks && memcmp(rgba_masks, dri_masks, sizeof(dri_masks))) return NULL; base.NativeRenderable = EGL_TRUE; base.SurfaceType = surface_type; if (surface_type & (EGL_PBUFFER_BIT | (disp->Extensions.NOK_texture_from_pixmap ? EGL_PIXMAP_BIT : 0))) { base.BindToTextureRGB = bind_to_texture_rgb; if (base.AlphaSize > 0) base.BindToTextureRGBA = bind_to_texture_rgba; } base.RenderableType = disp->ClientAPIs; base.Conformant = disp->ClientAPIs; if (!_eglValidateConfig(&base, EGL_FALSE)) { _eglLog(_EGL_DEBUG, "DRI2: failed to validate config %d", id); return NULL; } config_id = base.ConfigID; base.ConfigID = EGL_DONT_CARE; base.SurfaceType = EGL_DONT_CARE; num_configs = _eglFilterArray(disp->Configs, (void **) &matching_config, 1, (_EGLArrayForEach) dri2_match_config, &base); if (num_configs == 1) { conf = (struct dri2_egl_config *) matching_config; if (double_buffer && !conf->dri_double_config) conf->dri_double_config = dri_config; else if (!double_buffer && !conf->dri_single_config) conf->dri_single_config = dri_config; else /* a similar config type is already added (unlikely) => discard */ return NULL; } else if (num_configs == 0) { conf = malloc(sizeof *conf); if (conf == NULL) return NULL; memcpy(&conf->base, &base, sizeof base); if (double_buffer) { conf->dri_double_config = dri_config; conf->dri_single_config = NULL; } else { conf->dri_single_config = dri_config; conf->dri_double_config = NULL; } conf->base.SurfaceType = 0; conf->base.ConfigID = config_id; _eglLinkConfig(&conf->base); } else { assert(0); return NULL; } if (double_buffer) { surface_type &= ~EGL_PIXMAP_BIT; if (dri2_dpy->swap_available) { conf->base.MinSwapInterval = 0; conf->base.MaxSwapInterval = 1000; /* XXX arbitrary value */ } } conf->base.SurfaceType |= surface_type; return conf; }
static void dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id, int depth, xcb_visualtype_t *visual) { struct dri2_egl_config *conf; struct dri2_egl_display *dri2_dpy; _EGLConfig base; unsigned int attrib, value, double_buffer; EGLint key, bind_to_texture_rgb, bind_to_texture_rgba; int i; dri2_dpy = disp->DriverData; _eglInitConfig(&base, disp, id); i = 0; while (dri2_dpy->core->indexConfigAttrib(dri_config, i++, &attrib, &value)) { switch (attrib) { case __DRI_ATTRIB_RENDER_TYPE: if (value & __DRI_ATTRIB_RGBA_BIT) value = EGL_RGB_BUFFER; else if (value & __DRI_ATTRIB_LUMINANCE_BIT) value = EGL_LUMINANCE_BUFFER; else /* not valid */; _eglSetConfigKey(&base, EGL_COLOR_BUFFER_TYPE, value); break; case __DRI_ATTRIB_CONFIG_CAVEAT: if (value & __DRI_ATTRIB_NON_CONFORMANT_CONFIG) value = EGL_NON_CONFORMANT_CONFIG; else if (value & __DRI_ATTRIB_SLOW_BIT) value = EGL_SLOW_CONFIG; else value = EGL_NONE; _eglSetConfigKey(&base, EGL_CONFIG_CAVEAT, value); break; case __DRI_ATTRIB_BIND_TO_TEXTURE_RGB: bind_to_texture_rgb = value; break; case __DRI_ATTRIB_BIND_TO_TEXTURE_RGBA: bind_to_texture_rgba = value; break; case __DRI_ATTRIB_DOUBLE_BUFFER: double_buffer = value; break; default: key = dri2_to_egl_attribute_map[attrib]; if (key != 0) _eglSetConfigKey(&base, key, value); break; } } /* In EGL, double buffer or not isn't a config attribute. Pixmaps * surfaces are always single buffered, pbuffer surfaces are always * back buffers and windows can be either, selected by passing an * attribute at window surface construction time. To support this * we ignore all double buffer configs and manipulate the buffer we * return in the getBuffer callback to get the behaviour we want. */ if (double_buffer) return; if (visual != NULL) { if (depth != _eglGetConfigKey(&base, EGL_BUFFER_SIZE)) return; _eglSetConfigKey(&base, EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PIXMAP_BIT | EGL_PBUFFER_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT); _eglSetConfigKey(&base, EGL_NATIVE_VISUAL_ID, visual->visual_id); _eglSetConfigKey(&base, EGL_NATIVE_VISUAL_TYPE, visual->_class); } else { _eglSetConfigKey(&base, EGL_SURFACE_TYPE, EGL_PIXMAP_BIT | EGL_PBUFFER_BIT); } _eglSetConfigKey(&base, EGL_NATIVE_RENDERABLE, EGL_TRUE); _eglSetConfigKey(&base, EGL_BIND_TO_TEXTURE_RGB, bind_to_texture_rgb); if (_eglGetConfigKey(&base, EGL_ALPHA_SIZE) > 0) _eglSetConfigKey(&base, EGL_BIND_TO_TEXTURE_RGBA, bind_to_texture_rgba); /* EGL_OPENGL_ES_BIT, EGL_OPENVG_BIT, EGL_OPENGL_ES2_BIT */ _eglSetConfigKey(&base, EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT); _eglSetConfigKey(&base, EGL_CONFORMANT, EGL_OPENGL_BIT); if (!_eglValidateConfig(&base, EGL_FALSE)) { _eglLog(_EGL_DEBUG, "DRI2: failed to validate config %d", id); return; } conf = malloc(sizeof *conf); if (conf != NULL) { memcpy(&conf->base, &base, sizeof base); conf->dri_config = dri_config; _eglAddConfig(disp, &conf->base); } }