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; }
/** * Return true if a config matches the criteria. This and * _eglParseConfigAttribList together implement the algorithm * described in "Selection of EGLConfigs". * * Note that attributes that are special (currently, only * EGL_MATCH_NATIVE_PIXMAP) are ignored. */ EGLBoolean _eglMatchConfig(const _EGLConfig *conf, const _EGLConfig *criteria) { EGLint attr, val, i; EGLBoolean matched = EGL_TRUE; for (i = 0; i < ARRAY_SIZE(_eglValidationTable); i++) { EGLint cmp; if (_eglValidationTable[i].criterion == ATTRIB_CRITERION_IGNORE) continue; attr = _eglValidationTable[i].attr; cmp = _eglGetConfigKey(criteria, attr); if (cmp == EGL_DONT_CARE) continue; val = _eglGetConfigKey(conf, attr); switch (_eglValidationTable[i].criterion) { case ATTRIB_CRITERION_EXACT: if (val != cmp) matched = EGL_FALSE; break; case ATTRIB_CRITERION_ATLEAST: if (val < cmp) matched = EGL_FALSE; break; case ATTRIB_CRITERION_MASK: if ((val & cmp) != cmp) matched = EGL_FALSE; break; case ATTRIB_CRITERION_SPECIAL: /* ignored here */ break; case ATTRIB_CRITERION_IGNORE: unreachable("already handled above"); break; } if (!matched) { #ifndef DEBUG /* only print the common errors when DEBUG is not defined */ if (attr != EGL_RENDERABLE_TYPE) break; #endif _eglLog(_EGL_DEBUG, "the value (0x%x) of attribute 0x%04x did not meet the criteria (0x%x)", val, attr, cmp); break; } } return matched; }
/** * Fallback for eglGetConfigAttrib. */ EGLBoolean _eglGetConfigAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, EGLint attribute, EGLint *value) { if (!_eglIsConfigAttribValid(conf, attribute)) return _eglError(EGL_BAD_ATTRIBUTE, "eglGetConfigAttrib"); /* nonqueryable attributes */ switch (attribute) { case EGL_MATCH_NATIVE_PIXMAP: return _eglError(EGL_BAD_ATTRIBUTE, "eglGetConfigAttrib"); break; default: break; } if (!value) return _eglError(EGL_BAD_PARAMETER, "eglGetConfigAttrib"); *value = _eglGetConfigKey(conf, attribute); return EGL_TRUE; }
/** * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface(). */ static _EGLSurface * dri2_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type, _EGLConfig *conf, EGLNativeWindowType native_window, const EGLint *attrib_list) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_config *dri2_conf = dri2_egl_config(conf); struct dri2_egl_surface *dri2_surf; xcb_get_geometry_cookie_t cookie; xcb_get_geometry_reply_t *reply; xcb_screen_iterator_t s; xcb_generic_error_t *error; xcb_drawable_t window = (uintptr_t )native_window; (void) drv; dri2_surf = malloc(sizeof *dri2_surf); if (!dri2_surf) { _eglError(EGL_BAD_ALLOC, "dri2_create_surface"); return NULL; } if (!_eglInitSurface(&dri2_surf->base, disp, type, conf, attrib_list)) goto cleanup_surf; dri2_surf->region = XCB_NONE; if (type == EGL_PBUFFER_BIT) { dri2_surf->drawable = xcb_generate_id(dri2_dpy->conn); s = xcb_setup_roots_iterator(xcb_get_setup(dri2_dpy->conn)); xcb_create_pixmap(dri2_dpy->conn, conf->BufferSize, dri2_surf->drawable, s.data->root, dri2_surf->base.Width, dri2_surf->base.Height); } else { dri2_surf->drawable = window; } if (dri2_dpy->dri2) { dri2_surf->dri_drawable = (*dri2_dpy->dri2->createNewDrawable) (dri2_dpy->dri_screen, type == EGL_WINDOW_BIT ? dri2_conf->dri_double_config : dri2_conf->dri_single_config, dri2_surf); } else { assert(dri2_dpy->swrast); dri2_surf->dri_drawable = (*dri2_dpy->swrast->createNewDrawable) (dri2_dpy->dri_screen, dri2_conf->dri_double_config, dri2_surf); } if (dri2_surf->dri_drawable == NULL) { _eglError(EGL_BAD_ALLOC, "dri2->createNewDrawable"); goto cleanup_pixmap; } if (dri2_dpy->dri2) { xcb_dri2_create_drawable (dri2_dpy->conn, dri2_surf->drawable); } else { swrastCreateDrawable(dri2_dpy, dri2_surf, _eglGetConfigKey(conf, EGL_BUFFER_SIZE)); } if (type != EGL_PBUFFER_BIT) { cookie = xcb_get_geometry (dri2_dpy->conn, dri2_surf->drawable); reply = xcb_get_geometry_reply (dri2_dpy->conn, cookie, &error); if (reply == NULL || error != NULL) { _eglError(EGL_BAD_ALLOC, "xcb_get_geometry"); free(error); goto cleanup_dri_drawable; } dri2_surf->base.Width = reply->width; dri2_surf->base.Height = reply->height; free(reply); } /* we always copy the back buffer to front */ dri2_surf->base.PostSubBufferSupportedNV = EGL_TRUE; return &dri2_surf->base; cleanup_dri_drawable: dri2_dpy->core->destroyDrawable(dri2_surf->dri_drawable); cleanup_pixmap: if (type == EGL_PBUFFER_BIT) xcb_free_pixmap(dri2_dpy->conn, dri2_surf->drawable); cleanup_surf: free(dri2_surf); return NULL; }
/** * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface(). */ static _EGLSurface * dri2_x11_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type, _EGLConfig *conf, void *native_surface, const EGLint *attrib_list) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_config *dri2_conf = dri2_egl_config(conf); struct dri2_egl_surface *dri2_surf; xcb_get_geometry_cookie_t cookie; xcb_get_geometry_reply_t *reply; xcb_screen_iterator_t s; xcb_generic_error_t *error; xcb_drawable_t drawable; xcb_screen_t *screen; const __DRIconfig *config; STATIC_ASSERT(sizeof(uintptr_t) == sizeof(native_surface)); drawable = (uintptr_t) native_surface; (void) drv; dri2_surf = malloc(sizeof *dri2_surf); if (!dri2_surf) { _eglError(EGL_BAD_ALLOC, "dri2_create_surface"); return NULL; } if (!_eglInitSurface(&dri2_surf->base, disp, type, conf, attrib_list)) goto cleanup_surf; dri2_surf->region = XCB_NONE; if (type == EGL_PBUFFER_BIT) { s = xcb_setup_roots_iterator(xcb_get_setup(dri2_dpy->conn)); screen = get_xcb_screen(s, dri2_dpy->screen); if (!screen) { _eglError(EGL_BAD_ALLOC, "failed to get xcb screen"); goto cleanup_surf; } dri2_surf->drawable = xcb_generate_id(dri2_dpy->conn); xcb_create_pixmap(dri2_dpy->conn, conf->BufferSize, dri2_surf->drawable, screen->root, dri2_surf->base.Width, dri2_surf->base.Height); } else { if (!drawable) { if (type == EGL_WINDOW_BIT) _eglError(EGL_BAD_NATIVE_WINDOW, "dri2_create_surface"); else _eglError(EGL_BAD_NATIVE_PIXMAP, "dri2_create_surface"); goto cleanup_surf; } dri2_surf->drawable = drawable; } config = dri2_get_dri_config(dri2_conf, type, dri2_surf->base.GLColorspace); if (dri2_dpy->dri2) { dri2_surf->dri_drawable = (*dri2_dpy->dri2->createNewDrawable)(dri2_dpy->dri_screen, config, dri2_surf); } else { assert(dri2_dpy->swrast); dri2_surf->dri_drawable = (*dri2_dpy->swrast->createNewDrawable)(dri2_dpy->dri_screen, config, dri2_surf); } if (dri2_surf->dri_drawable == NULL) { _eglError(EGL_BAD_ALLOC, "dri2->createNewDrawable"); goto cleanup_pixmap; } if (type != EGL_PBUFFER_BIT) { cookie = xcb_get_geometry (dri2_dpy->conn, dri2_surf->drawable); reply = xcb_get_geometry_reply (dri2_dpy->conn, cookie, &error); if (error != NULL) { if (error->error_code == BadAlloc) _eglError(EGL_BAD_ALLOC, "xcb_get_geometry"); else if (type == EGL_WINDOW_BIT) _eglError(EGL_BAD_NATIVE_WINDOW, "xcb_get_geometry"); else _eglError(EGL_BAD_NATIVE_PIXMAP, "xcb_get_geometry"); free(error); goto cleanup_dri_drawable; } else if (reply == NULL) { _eglError(EGL_BAD_ALLOC, "xcb_get_geometry"); goto cleanup_dri_drawable; } dri2_surf->base.Width = reply->width; dri2_surf->base.Height = reply->height; dri2_surf->depth = reply->depth; free(reply); } if (dri2_dpy->dri2) { xcb_void_cookie_t cookie; int conn_error; cookie = xcb_dri2_create_drawable_checked(dri2_dpy->conn, dri2_surf->drawable); error = xcb_request_check(dri2_dpy->conn, cookie); conn_error = xcb_connection_has_error(dri2_dpy->conn); if (conn_error || error != NULL) { if (type == EGL_PBUFFER_BIT || conn_error || error->error_code == BadAlloc) _eglError(EGL_BAD_ALLOC, "xcb_dri2_create_drawable_checked"); else if (type == EGL_WINDOW_BIT) _eglError(EGL_BAD_NATIVE_WINDOW, "xcb_dri2_create_drawable_checked"); else _eglError(EGL_BAD_NATIVE_PIXMAP, "xcb_dri2_create_drawable_checked"); free(error); goto cleanup_dri_drawable; } } else { if (type == EGL_PBUFFER_BIT) { dri2_surf->depth = _eglGetConfigKey(conf, EGL_BUFFER_SIZE); } swrastCreateDrawable(dri2_dpy, dri2_surf); } /* we always copy the back buffer to front */ dri2_surf->base.PostSubBufferSupportedNV = EGL_TRUE; return &dri2_surf->base; cleanup_dri_drawable: dri2_dpy->core->destroyDrawable(dri2_surf->dri_drawable); cleanup_pixmap: if (type == EGL_PBUFFER_BIT) xcb_free_pixmap(dri2_dpy->conn, dri2_surf->drawable); cleanup_surf: free(dri2_surf); return NULL; }
/** * Decide the ordering of conf1 and conf2, under the given criteria. * When compare_id is true, this implements the algorithm described * in "Sorting of EGLConfigs". When compare_id is false, * EGL_CONFIG_ID is not compared. * * It returns a negative integer if conf1 is considered to come * before conf2; a positive integer if conf2 is considered to come * before conf1; zero if the ordering cannot be decided. * * Note that EGL_NATIVE_VISUAL_TYPE is platform-dependent and is * ignored here. */ EGLint _eglCompareConfigs(const _EGLConfig *conf1, const _EGLConfig *conf2, const _EGLConfig *criteria, EGLBoolean compare_id) { const EGLint compare_attribs[] = { EGL_BUFFER_SIZE, EGL_SAMPLE_BUFFERS, EGL_SAMPLES, EGL_DEPTH_SIZE, EGL_STENCIL_SIZE, EGL_ALPHA_MASK_SIZE, }; EGLint val1, val2; EGLint i; if (conf1 == conf2) return 0; /* the enum values have the desired ordering */ STATIC_ASSERT(EGL_NONE < EGL_SLOW_CONFIG); STATIC_ASSERT(EGL_SLOW_CONFIG < EGL_NON_CONFORMANT_CONFIG); val1 = conf1->ConfigCaveat - conf2->ConfigCaveat; if (val1) return val1; /* the enum values have the desired ordering */ STATIC_ASSERT(EGL_RGB_BUFFER < EGL_LUMINANCE_BUFFER); val1 = conf1->ColorBufferType - conf2->ColorBufferType; if (val1) return val1; if (criteria) { val1 = val2 = 0; if (conf1->ColorBufferType == EGL_RGB_BUFFER) { if (criteria->RedSize > 0) { val1 += conf1->RedSize; val2 += conf2->RedSize; } if (criteria->GreenSize > 0) { val1 += conf1->GreenSize; val2 += conf2->GreenSize; } if (criteria->BlueSize > 0) { val1 += conf1->BlueSize; val2 += conf2->BlueSize; } } else { if (criteria->LuminanceSize > 0) { val1 += conf1->LuminanceSize; val2 += conf2->LuminanceSize; } } if (criteria->AlphaSize > 0) { val1 += conf1->AlphaSize; val2 += conf2->AlphaSize; } } else { /* assume the default criteria, which gives no specific ordering */ val1 = val2 = 0; } /* for color bits, larger one is preferred */ if (val1 != val2) return (val2 - val1); for (i = 0; i < ARRAY_SIZE(compare_attribs); i++) { val1 = _eglGetConfigKey(conf1, compare_attribs[i]); val2 = _eglGetConfigKey(conf2, compare_attribs[i]); if (val1 != val2) return (val1 - val2); } /* EGL_NATIVE_VISUAL_TYPE cannot be compared here */ return (compare_id) ? (conf1->ConfigID - conf2->ConfigID) : 0; }
/** * Return true if a config is valid. When for_matching is true, * EGL_DONT_CARE is accepted as a valid attribute value, and checks * for conflicting attribute values are skipped. * * Note that some attributes are platform-dependent and are not * checked. */ EGLBoolean _eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching) { _EGLDisplay *disp = conf->Display; EGLint i, attr, val; EGLBoolean valid = EGL_TRUE; /* check attributes by their types */ for (i = 0; i < ARRAY_SIZE(_eglValidationTable); i++) { EGLint mask; attr = _eglValidationTable[i].attr; val = _eglGetConfigKey(conf, attr); switch (_eglValidationTable[i].type) { case ATTRIB_TYPE_INTEGER: switch (attr) { case EGL_CONFIG_ID: /* config id must be positive */ if (val <= 0) valid = EGL_FALSE; break; case EGL_SAMPLE_BUFFERS: /* there can be at most 1 sample buffer */ if (val > 1 || val < 0) valid = EGL_FALSE; break; default: if (val < 0) valid = EGL_FALSE; break; } break; case ATTRIB_TYPE_BOOLEAN: if (val != EGL_TRUE && val != EGL_FALSE) valid = EGL_FALSE; break; case ATTRIB_TYPE_ENUM: switch (attr) { case EGL_CONFIG_CAVEAT: if (val != EGL_NONE && val != EGL_SLOW_CONFIG && val != EGL_NON_CONFORMANT_CONFIG) valid = EGL_FALSE; break; case EGL_TRANSPARENT_TYPE: if (val != EGL_NONE && val != EGL_TRANSPARENT_RGB) valid = EGL_FALSE; break; case EGL_COLOR_BUFFER_TYPE: if (val != EGL_RGB_BUFFER && val != EGL_LUMINANCE_BUFFER) valid = EGL_FALSE; break; case EGL_COLOR_COMPONENT_TYPE_EXT: if (val != EGL_COLOR_COMPONENT_TYPE_FIXED_EXT && val != EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT) valid = EGL_FALSE; break; default: unreachable("check _eglValidationTable[]"); break; } break; case ATTRIB_TYPE_BITMASK: switch (attr) { case EGL_SURFACE_TYPE: mask = EGL_PBUFFER_BIT | EGL_PIXMAP_BIT | EGL_WINDOW_BIT | EGL_VG_COLORSPACE_LINEAR_BIT | EGL_VG_ALPHA_FORMAT_PRE_BIT | EGL_MULTISAMPLE_RESOLVE_BOX_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT; if (disp->Extensions.KHR_mutable_render_buffer) mask |= EGL_MUTABLE_RENDER_BUFFER_BIT_KHR; break; case EGL_RENDERABLE_TYPE: case EGL_CONFORMANT: mask = EGL_OPENGL_ES_BIT | EGL_OPENVG_BIT | EGL_OPENGL_ES2_BIT | EGL_OPENGL_ES3_BIT_KHR | EGL_OPENGL_BIT; break; default: unreachable("check _eglValidationTable[]"); mask = 0; break; } if (val & ~mask) valid = EGL_FALSE; break; case ATTRIB_TYPE_PLATFORM: /* unable to check platform-dependent attributes here */ break; case ATTRIB_TYPE_PSEUDO: /* pseudo attributes should not be set */ if (val != 0) valid = EGL_FALSE; break; } if (!valid && for_matching) { /* accept EGL_DONT_CARE as a valid value */ if (val == EGL_DONT_CARE) valid = EGL_TRUE; if (_eglValidationTable[i].criterion == ATTRIB_CRITERION_SPECIAL) valid = EGL_TRUE; } if (!valid) { _eglLog(_EGL_DEBUG, "attribute 0x%04x has an invalid value 0x%x", attr, val); break; } } /* any invalid attribute value should have been catched */ if (!valid || for_matching) return valid; /* now check for conflicting attribute values */ switch (conf->ColorBufferType) { case EGL_RGB_BUFFER: if (conf->LuminanceSize) valid = EGL_FALSE; if (conf->RedSize + conf->GreenSize + conf->BlueSize + conf->AlphaSize != conf->BufferSize) valid = EGL_FALSE; break; case EGL_LUMINANCE_BUFFER: if (conf->RedSize || conf->GreenSize || conf->BlueSize) valid = EGL_FALSE; if (conf->LuminanceSize + conf->AlphaSize != conf->BufferSize) valid = EGL_FALSE; break; } if (!valid) { _eglLog(_EGL_DEBUG, "conflicting color buffer type and channel sizes"); return EGL_FALSE; } if (!conf->SampleBuffers && conf->Samples) valid = EGL_FALSE; if (!valid) { _eglLog(_EGL_DEBUG, "conflicting samples and sample buffers"); return EGL_FALSE; } if (!(conf->SurfaceType & EGL_WINDOW_BIT)) { if (conf->NativeVisualID != 0 || conf->NativeVisualType != EGL_NONE) valid = EGL_FALSE; } if (!(conf->SurfaceType & EGL_PBUFFER_BIT)) { if (conf->BindToTextureRGB || conf->BindToTextureRGBA) valid = EGL_FALSE; } if (!valid) { _eglLog(_EGL_DEBUG, "conflicting surface type and native visual/texture binding"); return EGL_FALSE; } return valid; }
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); } }