void gs_swapchain_destroy(gs_swapchain_t swapchain) { if (!swapchain) return; if (swapchain->device->cur_swap == swapchain) device_load_swapchain(swapchain->device, NULL); gl_platform_cleanup_swapchain(swapchain); gl_windowinfo_destroy(swapchain->wi); bfree(swapchain); }
void gl_platform_destroy(struct gl_platform *platform) { if (!platform) return; Display *dpy = platform->swap.wi->display; glXMakeCurrent(dpy, None, NULL); glXDestroyContext(dpy, platform->context); gl_windowinfo_destroy(platform->swap.wi); gl_platform_cleanup_swapchain(&platform->swap); bfree(platform); }
bool gl_platform_init_swapchain(struct gs_swap_chain *swap) { Display *display = swap->wi->display; struct gl_windowinfo *info = swap->wi; struct gl_platform *plat = swap->device->plat; XVisualInfo *vi = 0; Colormap cmap = 0; XSetWindowAttributes swa; XWindowAttributes attrs; XErrorHandler phandler = XSetErrorHandler(err_handler); gl_platform_cleanup_swapchain(swap); if (!XGetWindowAttributes(display, info->id, &attrs)) { blog(LOG_ERROR, "Failed getting window attributes"); goto fail; } vi = glXGetVisualFromFBConfig(display, plat->fbcfg); if (handle_x_error(display, "Failed to get visual from fb config.")) goto fail; cmap = XCreateColormap(display, info->id, vi->visual, AllocNone); if (handle_x_error(display, "Failed creating colormap")) goto fail; swa.colormap = cmap; swa.border_pixel = 0; info->int_id = XCreateWindow(display, info->id, 0, 0, attrs.width, attrs.height, 0, 24, InputOutput, vi->visual, CWBorderPixel|CWColormap, &swa); XMapWindow(display, info->int_id); if (handle_x_error(display, "Failed creating intermediate X window")) goto fail; info->glxid = glXCreateWindow(display, plat->fbcfg, info->int_id, 0); if (handle_x_error(display, "Failed creating intermediate GLX window")) goto fail; XFreeColormap(display, cmap); XFree(vi); return true; fail: gl_platform_cleanup_swapchain(swap); if (cmap) XFreeColormap(display, cmap); if (vi) XFree(vi); XSetErrorHandler(phandler); return false; }
struct gl_platform *gl_platform_create(device_t device, struct gs_init_data *info) { int num_configs = 0; int error_base = 0, event_base = 0; Display *display = info->window.display; struct gl_platform *plat = bzalloc(sizeof(struct gl_platform)); GLXFBConfig* configs; XWindowAttributes attrs; int screen; int major = 0, minor = 0; print_info_stuff(info); if (!display) { blog(LOG_ERROR, "Unable to find display. DISPLAY variable " "may not be set correctly."); goto fail0; } if (!XGetWindowAttributes(display, info->window.id, &attrs)) { blog(LOG_ERROR, "Failed getting window attributes"); goto fail0; } screen = XScreenNumberOfScreen(attrs.screen); if (!gladLoadGLX(display, screen)) { blog(LOG_ERROR, "Unable to load GLX entry functions."); goto fail0; } if (!glXQueryExtension(display, &error_base, &event_base)) { blog(LOG_ERROR, "GLX not supported."); goto fail0; } /* We require glX version 1.3 */ glXQueryVersion(display, &major, &minor); if (major < 1 || (major == 1 && minor < 3)) { blog(LOG_ERROR, "GLX version found: %i.%i\nRequired: " "1.3", major, minor); goto fail0; } if (!GLAD_GLX_ARB_create_context) { blog(LOG_ERROR, "ARB_GLX_create_context not supported!"); goto fail0; } configs = glXChooseFBConfig(display, screen, fb_attribs, &num_configs); if (!configs) { blog(LOG_ERROR, "Attribute list or screen is invalid."); goto fail0; } if (num_configs == 0) { XFree(configs); blog(LOG_ERROR, "No framebuffer configurations found."); goto fail0; } plat->fbcfg = configs[0]; XFree(configs); handle_x_error(display, NULL); /* We just use the first configuration found... as it does everything * we want at the very least. */ plat->context = glXCreateContextAttribsARB(display, plat->fbcfg, NULL, true, ctx_attribs); if (!plat->context) { blog(LOG_ERROR, "Failed to create OpenGL context."); goto fail0; } if (handle_x_error(display, "Failed to create OpenGL context.")) goto fail2; device->plat = plat; plat->swap.device = device; plat->swap.info.window.id = info->window.id; plat->swap.info.window.display = display; plat->swap.info.format = GS_RGBA; plat->swap.info.zsformat = GS_Z24_S8; plat->swap.info.num_backbuffers = 1; plat->swap.info.adapter = info->adapter; plat->swap.info.cx = attrs.width; plat->swap.info.cy = attrs.height; plat->swap.wi = gl_windowinfo_create(info); if (!gl_platform_init_swapchain(&plat->swap)) goto fail2; if (!glXMakeCurrent(display, plat->swap.wi->glxid, plat->context)) { blog(LOG_ERROR, "Failed to make context current."); goto fail2; } if (!gladLoadGL()) { blog(LOG_ERROR, "Failed to load OpenGL entry functions."); goto fail2; } blog(LOG_INFO, "OpenGL version: %s\n", glGetString(GL_VERSION)); /* We assume later that cur_swap is already set. */ device->cur_swap = &plat->swap; XSync(display, false); blog(LOG_INFO, "Created new platform data"); return plat; fail2: glXMakeCurrent(display, None, NULL); glXDestroyContext(display, plat->context); gl_platform_cleanup_swapchain(&plat->swap); fail0: bfree(plat); device->plat = 0; return NULL; }