void TopCanvas::CreateGLX(_XDisplay *_x_display, X11Window x_window, GLXFBConfig *fb_cfg) { x_display = _x_display; glx_context = glXCreateNewContext(_x_display, *fb_cfg, GLX_RGBA_TYPE, nullptr, true); if (glx_context == nullptr) { fprintf(stderr, "Failed to create GLX context\n"); exit(EXIT_FAILURE); } glx_window = glXCreateWindow(_x_display, *fb_cfg, x_window, nullptr); XSync(x_display, false); if (!glXMakeContextCurrent(_x_display, glx_window, glx_window, glx_context)) { fprintf(stderr, "Failed to attach GLX context to GLX window\n"); exit(EXIT_FAILURE); } const PixelSize effective_size = GetNativeSize(); if (effective_size.cx <= 0 || effective_size.cy <= 0) { fprintf(stderr, "Failed to query GLX drawable size\n"); exit(EXIT_FAILURE); } OpenGL::SetupContext(); SetupViewport(effective_size); }
bool GlxBackend::initBuffer() { if (!initFbConfig()) return false; if (overlayWindow()->create()) { // Try to create double-buffered window in the overlay XVisualInfo* visual = glXGetVisualFromFBConfig(display(), fbconfig); if (!visual) { qCritical() << "Failed to get visual from fbconfig"; return false; } XSetWindowAttributes attrs; attrs.colormap = XCreateColormap(display(), rootWindow(), visual->visual, AllocNone); window = XCreateWindow(display(), overlayWindow()->window(), 0, 0, displayWidth(), displayHeight(), 0, visual->depth, InputOutput, visual->visual, CWColormap, &attrs); glxWindow = glXCreateWindow(display(), fbconfig, window, NULL); overlayWindow()->setup(window); XFree(visual); } else { qCritical() << "Failed to create overlay window"; return false; } int vis_buffer; glXGetFBConfigAttrib(display(), fbconfig, GLX_VISUAL_ID, &vis_buffer); XVisualInfo* visinfo_buffer = glXGetVisualFromFBConfig(display(), fbconfig); qDebug() << "Buffer visual (depth " << visinfo_buffer->depth << "): 0x" << QString::number(vis_buffer, 16); XFree(visinfo_buffer); return true; }
GLXWindow get_glx_window(Display *XJ_disp, GLXFBConfig glx_fbconfig, Window gl_window, GLXContext glx_context, GLXPbuffer glx_pbuffer, const QSize &window_size) { X11L; GLXWindow glx_window = glXCreateWindow( XJ_disp, glx_fbconfig, gl_window, NULL); glXMakeContextCurrent(XJ_disp, glx_window, glx_pbuffer, glx_context); glDrawBuffer(GL_BACK_LEFT); glReadBuffer(GL_FRONT_LEFT); glClearColor(0.0, 0.0, 0.0, 0.0); glShadeModel(GL_FLAT); glEnable(GL_TEXTURE_RECTANGLE_NV); glViewport(0, 0, window_size.width(), window_size.height()); glMatrixMode(GL_PROJECTION); glLoadIdentity(); // left, right, botton, top, near, far glOrtho(0, window_size.width(), 0, window_size.height(), -2, 2); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glFinish(); glXMakeContextCurrent(XJ_disp, None, None, NULL); X11U; return glx_window; }
uint32_t createSurface(const IntSize& size) { XVisualInfo* visualInfo = glXGetVisualFromFBConfig(m_display, m_fbConfig); if (!visualInfo) return 0; Colormap cmap = XCreateColormap(m_display, m_offScreenWindow.getXWindow(), visualInfo->visual, AllocNone); XSetWindowAttributes a; a.background_pixel = WhitePixel(m_display, 0); a.border_pixel = BlackPixel(m_display, 0); a.colormap = cmap; m_surface = XCreateWindow(m_display, m_offScreenWindow.getXWindow(), 0, 0, size.width(), size.height(), 0, visualInfo->depth, InputOutput, visualInfo->visual, CWBackPixel | CWBorderPixel | CWColormap, &a); XSetWindowBackgroundPixmap(m_display, m_surface, 0); XCompositeRedirectWindow(m_display, m_surface, CompositeRedirectManual); m_glxSurface = glXCreateWindow(m_display, m_fbConfig, m_surface, 0); XFree(visualInfo); // Make sure the XRender Extension is available. int eventBasep, errorBasep; if (!XRenderQueryExtension(m_display, &eventBasep, &errorBasep)) return 0; XMapWindow(m_display, m_surface); return m_surface; }
bool GraphicsContext::acquireGLSystem() { m_window = glXCreateWindow(m_display, m_config, m_xWindow, NULL); if (!m_window) { printf("%s: %s (%i): ERROR - Invalid glxWindow\n", __FILE__, __FUNCTION__, __LINE__); return false; } const int pbuffer_attribs[] = { GLX_PBUFFER_WIDTH, 1, GLX_PBUFFER_HEIGHT, 1, None }; m_pbuffer = glXCreatePbuffer(m_display, m_config, pbuffer_attribs); if (!m_window) { printf("%s: %s (%i): ERROR - Invalid glxPbuffer\n", __FILE__, __FUNCTION__, __LINE__); return false; } m_context = glXCreateNewContext(m_display, m_config, GLX_RGBA_TYPE, NULL, true); if (!m_context) { printf("%s: %s (%i): ERROR - Invalid glxContext\n", __FILE__, __FUNCTION__, __LINE__); return false; } return true; }
void TopCanvas::CreateGLX(_XDisplay *_x_display, X11Window x_window, GLXFBConfig *fb_cfg) { x_display = _x_display; glx_context = glXCreateNewContext(_x_display, *fb_cfg, GLX_RGBA_TYPE, nullptr, true); if (glx_context == nullptr) { fprintf(stderr, "Failed to create GLX context\n"); exit(EXIT_FAILURE); } glx_window = glXCreateWindow(_x_display, *fb_cfg, x_window, nullptr); XSync(x_display, false); if (!glXMakeContextCurrent(_x_display, glx_window, glx_window, glx_context)) { fprintf(stderr, "Failed to attach GLX context to GLX window\n"); exit(EXIT_FAILURE); } unsigned int glx_width = -1, glx_height = -1; glXQueryDrawable(_x_display, glx_window, GLX_WIDTH, &glx_width); glXQueryDrawable(_x_display, glx_window, GLX_HEIGHT, &glx_height); if ((glx_width <= 0) || (glx_height <= 0)) { fprintf(stderr, "Failed to query GLX drawable size\n"); exit(EXIT_FAILURE); } const PixelSize effective_size = { glx_width, glx_height }; OpenGL::SetupContext(); OpenGL::SetupViewport(UnsignedPoint2D(effective_size.cx, effective_size.cy)); Canvas::Create(effective_size); }
DECLEXPORT(EGLSurface) eglCreateWindowSurface(EGLDisplay hDisplay, EGLConfig config, EGLNativeWindowType hWindow, const EGLint *paAttributes) { Display *pDisplay = (Display *)hDisplay; GLXWindow hGLXWindow; if (!VALID_PTR(hDisplay)) { setEGLError(EGL_NOT_INITIALIZED); return EGL_NO_SURFACE; } if (paAttributes != NULL) /* Sanity test only. */ while (*paAttributes != EGL_NONE) { if (*paAttributes != EGL_RENDER_BUFFER) { setEGLError(EGL_BAD_MATCH); return EGL_NO_SURFACE; } paAttributes += 2; } hGLXWindow = glXCreateWindow(pDisplay, (GLXFBConfig)config, (Window)hWindow, NULL); if (hGLXWindow == None) { setEGLError(EGL_BAD_ALLOC); return EGL_NO_SURFACE; } EGL_ASSERT(hGLXWindow < VBEGL_WINDOW_SURFACE); /* Greater than the maximum XID. */ clearEGLError(); return (EGLSurface)(hGLXWindow | VBEGL_WINDOW_SURFACE); }
static gboolean clutter_stage_glx_realize (ClutterStageWindow *stage_window) { ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window); ClutterStageGLX *stage_glx = CLUTTER_STAGE_GLX (stage_window); ClutterBackendX11 *backend_x11; ClutterBackendGLX *backend_glx; CLUTTER_NOTE (ACTOR, "Realizing stage '%s' [%p]", G_OBJECT_TYPE_NAME (stage_window), stage_window); if (!_clutter_stage_x11_create_window (stage_x11)) return FALSE; backend_x11 = stage_x11->backend; backend_glx = CLUTTER_BACKEND_GLX (backend_x11); if (stage_glx->glxwin == None) { int major; int minor; GLXFBConfig config; /* Try and create a GLXWindow to use with extensions dependent on * GLX versions >= 1.3 that don't accept regular X Windows as GLX * drawables. */ if (glXQueryVersion (backend_x11->xdpy, &major, &minor) && major == 1 && minor >= 3 && _clutter_backend_glx_get_fbconfig (backend_glx, &config)) { stage_glx->glxwin = glXCreateWindow (backend_x11->xdpy, config, stage_x11->xwin, NULL); } } #ifdef GLX_INTEL_swap_event if (clutter_feature_available (CLUTTER_FEATURE_SWAP_EVENTS)) { GLXDrawable drawable = stage_glx->glxwin ? stage_glx->glxwin : stage_x11->xwin; /* we unconditionally select this event because we rely on it to * advance the master clock, and drive redraw/relayout, animations * and event handling. */ glXSelectEvent (backend_x11->xdpy, drawable, GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK); } #endif /* GLX_INTEL_swap_event */ /* chain up to the StageX11 implementation */ return clutter_stage_window_parent_iface->realize (stage_window); }
JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_GLX13_nglXCreateWindow(JNIEnv *__env, jclass clazz, jlong displayAddress, jlong configAddress, jlong win, jlong attrib_listAddress, jlong __functionAddress) { Display *display = (Display *)(intptr_t)displayAddress; GLXFBConfig config = (GLXFBConfig)(intptr_t)configAddress; const int *attrib_list = (const int *)(intptr_t)attrib_listAddress; glXCreateWindowPROC glXCreateWindow = (glXCreateWindowPROC)(intptr_t)__functionAddress; UNUSED_PARAMS(__env, clazz) return (jlong)(intptr_t)glXCreateWindow(display, config, (Window)win, attrib_list); }
void *platform_window_surface_create (PlatformDisplay *display, EGLProxyConfig *egl_config, SurfaceAttributes *attributes) { EGLNativeWindowType win = attributes->specific.window.id; GLXDrawable result = win; if (display->is_modern) { GLXFBConfig glx_config = (GLXFBConfig) egl_config->platform; result = glXCreateWindow (display->x11_display, glx_config, win, NULL); } return (void *) result; }
void createWindow() { eventmask = XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_KEY_RELEASE; uint32_t valuelist[] = { eventmask, colormap }; uint32_t valuemask = XCB_CW_EVENT_MASK | XCB_CW_COLORMAP; xcb_create_window( connection, XCB_COPY_FROM_PARENT, window, screen->root, 0, 0, width, height, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, visualID, valuemask, valuelist); // NOTE: window must be mapped before glXMakeContextCurrent xcb_map_window(connection, window); // Create GLX Window glxwindow = glXCreateWindow(display, fb_config, window, 0); if (!glxwindow) printf("glXCreateWindow failed"); drawable = glxwindow; // make OpenGL context current if (!glXMakeContextCurrent(display, drawable, drawable, context)) printf("glXMakeContextCurrent failed"); // Set swap interval #ifdef NVIDIA_GL PFNGLXSWAPINTERVALSGIPROC glXSwapInterval = reinterpret_cast<PFNGLXSWAPINTERVALSGIPROC> (glXGetProcAddress( reinterpret_cast<GLubyte const *>("glXSwapIntervalSGI"))); if (!glXSwapInterval) { printf("VSync is not supported"); } else { glXSwapInterval(1); } #endif setWindowTitle(programTile); }
int InitGLX13( vout_thread_t *p_vout ) { vout_sys_t *p_sys = p_vout->p_sys; int i_nbelem; GLXFBConfig *p_fbconfs, fbconf; XVisualInfo *p_vi; int p_attr[] = { GLX_RED_SIZE, 5, GLX_GREEN_SIZE, 5, GLX_BLUE_SIZE, 5, GLX_DOUBLEBUFFER, True, GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, 0 }; /* Get the FB configuration */ p_fbconfs = glXChooseFBConfig( p_sys->p_display, 0, p_attr, &i_nbelem ); if( (i_nbelem <= 0) || !p_fbconfs ) { msg_Err( p_vout, "Cannot get FB configurations"); if( p_fbconfs ) XFree( p_fbconfs ); return VLC_EGENERIC; } fbconf = p_fbconfs[0]; /* Get the X11 visual */ p_vi = glXGetVisualFromFBConfig( p_sys->p_display, fbconf ); if( !p_vi ) { msg_Err( p_vout, "Cannot get X11 visual" ); XFree( p_fbconfs ); return VLC_EGENERIC; } XFree( p_vi ); /* Create the GLX window */ p_sys->gwnd = glXCreateWindow( p_sys->p_display, fbconf, p_sys->p_win->video_window, NULL ); if( p_sys->gwnd == None ) { msg_Err( p_vout, "Cannot create GLX window" ); return VLC_EGENERIC; } /* Create an OpenGL context */ p_sys->gwctx = glXCreateNewContext( p_sys->p_display, fbconf, GLX_RGBA_TYPE, NULL, True ); XFree( p_fbconfs ); if( !p_sys->gwctx ) { msg_Err( p_vout, "Cannot create OpenGL context"); return VLC_EGENERIC; } return VLC_SUCCESS; }
int main(int argc, char* argv[]) { gtk_init(&argc, &argv); display = GDK_DISPLAY_XDISPLAY(gdk_display_get_default()); rand = g_rand_new(); g_width = 400; g_height = 300; if (setup_context() != 0) return -1; ref = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_default_size(GTK_WINDOW(ref), g_width, g_height); g_object_connect(ref, "signal::draw", on_ref_draw, NULL, "signal::configure-event", on_ref_configure, NULL, "signal::map-event", on_ref_mapped, NULL, "signal::delete-event", on_deleted, NULL, NULL); gtk_widget_show_all(ref); top = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_default_size(GTK_WINDOW(top), g_width, g_height); gtk_widget_set_app_paintable(top, TRUE); gtk_widget_set_double_buffered(top, FALSE); g_object_connect(top, "signal::draw", on_draw, NULL, "signal::delete-event", on_deleted, NULL, NULL); gtk_widget_show_all(top); GdkWindow* gdkwin = gtk_widget_get_window(top); glxwin = glXCreateWindow(display, bestFbc, GDK_WINDOW_XID(gdkwin), NULL); g_timeout_add(1000, on_timeout, NULL); gtk_main(); if (glx_pm) { glXDestroyPixmap(display, glx_pm); XFreePixmap(display, back_pixmap); } glXDestroyContext(ctx); g_rand_free(rand); }
void X11Win::init(void) { XSetWindowAttributes swa; XVisualInfo *vi; glXCreateContextAttribsARBProc glXCreateContextAttribsARB; static int context_attribs[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, 3, GLX_CONTEXT_MINOR_VERSION_ARB, 0, // GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, None }; assignBestFBC(); vi = glXGetVisualFromFBConfig(_d, _fbc); swa.colormap = _cmap = XCreateColormap(_d, RootWindow(_d, vi->screen), vi->visual, AllocNone); swa.background_pixmap = None; swa.border_pixel = 0; swa.event_mask = ExposureMask|KeyPressMask|ButtonPressMask|StructureNotifyMask; /*Window XCreateWindow( _d, parent, x, y, width, height, border_width, depth, class, visual, valuemask, attributes)*/ _w = XCreateWindow(_d, RootWindow(_d, vi->screen) , 0 , 0 , _width , _height , 0 , vi->depth , InputOutput , vi->visual , CWBackPixel|CWBackPixmap|CWBorderPixel|CWColormap|CWEventMask , &swa); _glxWin = glXCreateWindow(_d, _fbc, _w, NULL); XStoreName(_d, _w, "GL Window"); XMapWindow(_d, _w); glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)glXGetProcAddressARB( (const GLubyte *)"glXCreateContextAttribsARB"); _ctx = glXCreateContextAttribsARB(_d, _fbc, 0, True, context_attribs); XFree(vi); XSync(_d, True); glXMakeCurrent(_d, _glxWin, _ctx); glClearColor(0, 0.5, 1, 1); }
struct ephyr_glamor * ephyr_glamor_glx_screen_init(xcb_window_t win) { GLXContext ctx; struct ephyr_glamor *glamor; GLXWindow glx_win; glamor = calloc(1, sizeof(struct ephyr_glamor)); if (!glamor) { FatalError("malloc"); return NULL; } glx_win = glXCreateWindow(dpy, fb_config, win, NULL); if (ephyr_glamor_gles2) { static const int context_attribs[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, 2, GLX_CONTEXT_MINOR_VERSION_ARB, 0, GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_ES_PROFILE_BIT_EXT, 0, }; if (epoxy_has_glx_extension(dpy, DefaultScreen(dpy), "GLX_EXT_create_context_es2_profile")) { ctx = glXCreateContextAttribsARB(dpy, fb_config, NULL, True, context_attribs); } else { FatalError("Xephyr -glamor_gles2 rquires " "GLX_EXT_create_context_es2_profile\n"); } } else { ctx = glXCreateContext(dpy, visual_info, NULL, True); } if (ctx == NULL) FatalError("glXCreateContext failed\n"); if (!glXMakeCurrent(dpy, glx_win, ctx)) FatalError("glXMakeCurrent failed\n"); glamor->ctx = ctx; glamor->win = win; glamor->glx_win = glx_win; ephyr_glamor_setup_texturing_shader(glamor); return glamor; }
GlxDrawable(const Visual *vis, int w, int h, const glws::pbuffer_info *pbInfo) : Drawable(vis, w, h, pbInfo ? true : false) { const GlxVisual *glxvisual = static_cast<const GlxVisual *>(visual); XVisualInfo *visinfo = glxvisual->visinfo; const char *name = "glretrace"; if (pbInfo) { drawable = createPbuffer(display, glxvisual, pbInfo, w, h); } else { window = createWindow(visinfo, name, width, height); drawable = glXCreateWindow(display, glxvisual->fbconfig, window, NULL); } glXWaitX(); }
// create destination buffer bool SceneOpenGL::initBuffer() { if (!initBufferConfigs()) return false; if (fbcbuffer_db != NULL && m_overlayWindow->create()) { // we have overlay, try to create double-buffered window in it fbcbuffer = fbcbuffer_db; XVisualInfo* visual = glXGetVisualFromFBConfig(display(), fbcbuffer); XSetWindowAttributes attrs; attrs.colormap = XCreateColormap(display(), rootWindow(), visual->visual, AllocNone); buffer = XCreateWindow(display(), m_overlayWindow->window(), 0, 0, displayWidth(), displayHeight(), 0, visual->depth, InputOutput, visual->visual, CWColormap, &attrs); if (hasGLXVersion(1, 3)) glxbuffer = glXCreateWindow(display(), fbcbuffer, buffer, NULL); else glxbuffer = buffer; m_overlayWindow->setup(buffer); db = true; XFree(visual); } else if (fbcbuffer_nondb != NULL) { // cannot get any double-buffered drawable, will double-buffer using a pixmap fbcbuffer = fbcbuffer_nondb; XVisualInfo* visual = glXGetVisualFromFBConfig(display(), fbcbuffer); XGCValues gcattr; gcattr.subwindow_mode = IncludeInferiors; gcroot = XCreateGC(display(), rootWindow(), GCSubwindowMode, &gcattr); buffer = XCreatePixmap(display(), rootWindow(), displayWidth(), displayHeight(), visual->depth); glxbuffer = glXCreatePixmap(display(), fbcbuffer, buffer, NULL); db = false; XFree(visual); } else { kError(1212) << "Couldn't create output buffer (failed to create overlay window?) !"; return false; // error } int vis_buffer; glXGetFBConfigAttrib(display(), fbcbuffer, GLX_VISUAL_ID, &vis_buffer); XVisualInfo* visinfo_buffer = glXGetVisualFromFBConfig(display(), fbcbuffer); kDebug(1212) << "Buffer visual (depth " << visinfo_buffer->depth << "): 0x" << QString::number(vis_buffer, 16); XFree(visinfo_buffer); return true; }
GLXWindow create_canvas(void) { XSetWindowAttributes sattr; GLXWindow c = 0; Window w = 0; GLXFBConfig fbc = choose_fbconfig(); XVisualInfo* vi = glXGetVisualFromFBConfig(dpy, fbc); check_gl(__LINE__); fbconfig_attrs(fbc, &width, &height, &top, &bottom); sattr.colormap = XCreateColormap(dpy, root, vi->visual, AllocNone); ratio = ((GLfloat) width) / ((GLfloat) height); w = XCreateWindow(dpy, overlay, 0, 0, width, height, 0, vi->depth, InputOutput, vi->visual, CWColormap, &sattr); c = glXCreateWindow(dpy, fbc, w, NULL); check_gl(__LINE__); XFree(vi); XSelectInput(dpy, w, ExposureMask); context = glXCreateNewContext(dpy, fbc, GLX_RGBA_TYPE, NULL, direct); check_gl(__LINE__); glXMakeCurrent(dpy, c, context); check_gl(__LINE__); info("Canvas is %d x %d (ratio: %g)\n", width, height, ratio); return c; }
void GLX_ARB_create_context_setup(void) { dpy = piglit_get_glx_display(); piglit_require_glx_version(dpy, 1, 4); piglit_require_glx_extension(dpy, "GLX_ARB_create_context"); __piglit_glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC) glXGetProcAddress((const GLubyte *) "glXCreateContextAttribsARB"); assert(__piglit_glXCreateContextAttribsARB != NULL); visinfo = piglit_get_glx_visual(dpy); fbconfig = piglit_glx_get_fbconfig_for_visinfo(dpy, visinfo); win = piglit_get_glx_window_unmapped(dpy, visinfo); glxWin = glXCreateWindow(dpy, fbconfig, win, NULL); piglit_glx_get_error(dpy, NULL); old_handler = XSetErrorHandler(x_error_handler); }
bool GlxBackend::initBuffer() { if (!initFbConfig()) return false; if (overlayWindow()->create()) { xcb_connection_t * const c = connection(); // Try to create double-buffered window in the overlay xcb_visualid_t visual; glXGetFBConfigAttrib(display(), fbconfig, GLX_VISUAL_ID, (int *) &visual); if (!visual) { qCCritical(KWIN_CORE) << "The GLXFBConfig does not have an associated X visual"; return false; } xcb_colormap_t colormap = xcb_generate_id(c); xcb_create_colormap(c, false, colormap, rootWindow(), visual); const QSize size = screens()->size(); window = xcb_generate_id(c); xcb_create_window(c, visualDepth(visual), window, overlayWindow()->window(), 0, 0, size.width(), size.height(), 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, visual, XCB_CW_COLORMAP, &colormap); glxWindow = glXCreateWindow(display(), fbconfig, window, NULL); overlayWindow()->setup(window); } else { qCCritical(KWIN_CORE) << "Failed to create overlay window"; return false; } return true; }
Glf_TestGLContextPrivate::Glf_TestGLContextPrivate( Glf_TestGLContextPrivate const * other ) : _dpy(NULL), _context(NULL) { static int attribs[] = { GLX_DOUBLEBUFFER, GLX_RGBA_BIT, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, GLX_SAMPLE_BUFFERS, 1, GLX_SAMPLES, 4, None }; _dpy = XOpenDisplay(0); int n; GLXFBConfig * fbConfigs = glXChooseFBConfig( _dpy, DefaultScreen(_dpy), attribs, &n ); GLXContext share = other ? other->_context : 0; _context = glXCreateNewContext( _dpy, fbConfigs[0], GLX_RGBA_TYPE, share, true); _sharedContext=other ? other : this; if (!_win) { XVisualInfo * vi = glXGetVisualFromFBConfig( _dpy, fbConfigs[0] ); XSetWindowAttributes swa; swa.colormap = XCreateColormap(_dpy, RootWindow(_dpy, vi->screen), vi->visual, AllocNone); swa.border_pixel = 0; swa.event_mask = StructureNotifyMask; Window xwin = XCreateWindow( _dpy, RootWindow(_dpy, vi->screen), 0, 0, 256, 256, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel|CWColormap|CWEventMask, &swa ); _win = glXCreateWindow( _dpy, fbConfigs[0], xwin, NULL ); } }
static gboolean clutter_backend_glx_create_context (ClutterBackend *backend, GError **error) { ClutterBackendGLX *backend_glx = CLUTTER_BACKEND_GLX (backend); ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend); GLXFBConfig config; gboolean is_direct; Window root_xwin; XSetWindowAttributes attrs; XVisualInfo *xvisinfo; Display *xdisplay; int major; int minor; GLXDrawable dummy_drawable; if (backend_glx->gl_context != None) return TRUE; xdisplay = clutter_x11_get_default_display (); root_xwin = clutter_x11_get_root_window (); if (!_clutter_backend_glx_get_fbconfig (backend_glx, &config)) { g_set_error (error, CLUTTER_INIT_ERROR, CLUTTER_INIT_ERROR_BACKEND, "Unable to find suitable fbconfig for the GLX context"); return FALSE; } CLUTTER_NOTE (BACKEND, "Creating GLX Context (display: %p)", xdisplay); backend_glx->gl_context = glXCreateNewContext (xdisplay, config, GLX_RGBA_TYPE, NULL, True); if (backend_glx->gl_context == None) { g_set_error (error, CLUTTER_INIT_ERROR, CLUTTER_INIT_ERROR_BACKEND, "Unable to create suitable GL context"); return FALSE; } is_direct = glXIsDirect (xdisplay, backend_glx->gl_context); CLUTTER_NOTE (GL, "Setting %s context", is_direct ? "direct" : "indirect"); _cogl_set_indirect_context (!is_direct); /* COGL assumes that there is always a GL context selected; in order * to make sure that a GLX context exists and is made current, we use * a dummy, offscreen override-redirect window to which we can always * fall back if no stage is available * * XXX - we need to do this dance because GLX does not allow creating * a context and querying it for basic information (even the function * pointers) unless it's made current to a real Drawable. it should be * possible to avoid this in future releases of Mesa and X11, but right * now this is the best solution available. */ xvisinfo = glXGetVisualFromFBConfig (xdisplay, config); if (xvisinfo == None) { g_set_error (error, CLUTTER_INIT_ERROR, CLUTTER_INIT_ERROR_BACKEND, "Unable to retrieve the X11 visual"); return FALSE; } clutter_x11_trap_x_errors (); attrs.override_redirect = True; attrs.colormap = XCreateColormap (xdisplay, root_xwin, xvisinfo->visual, AllocNone); attrs.border_pixel = 0; backend_glx->dummy_xwin = XCreateWindow (xdisplay, root_xwin, -100, -100, 1, 1, 0, xvisinfo->depth, CopyFromParent, xvisinfo->visual, CWOverrideRedirect | CWColormap | CWBorderPixel, &attrs); /* Try and create a GLXWindow to use with extensions dependent on * GLX versions >= 1.3 that don't accept regular X Windows as GLX * drawables. */ if (glXQueryVersion (backend_x11->xdpy, &major, &minor) && major == 1 && minor >= 3) { backend_glx->dummy_glxwin = glXCreateWindow (backend_x11->xdpy, config, backend_glx->dummy_xwin, NULL); } if (backend_glx->dummy_glxwin) dummy_drawable = backend_glx->dummy_glxwin; else dummy_drawable = backend_glx->dummy_xwin; CLUTTER_NOTE (BACKEND, "Selecting dummy 0x%x for the GLX context", (unsigned int) dummy_drawable); glXMakeContextCurrent (xdisplay, dummy_drawable, dummy_drawable, backend_glx->gl_context); XFree (xvisinfo); if (clutter_x11_untrap_x_errors ()) { g_set_error (error, CLUTTER_INIT_ERROR, CLUTTER_INIT_ERROR_BACKEND, "Unable to select the newly created GLX context"); return FALSE; } return TRUE; }
void init(int w, int h) { display = XOpenDisplay( NULL ); if ( display == NULL ) { fprintf( stderr, "Bad DISPLAY (%s).\n", getenv( "DISPLAY" ) ); exit( 1 ); } int pbuffer_attributes[] = { GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT, 0 }; int attributes[] = { GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_RED_SIZE, 8, /* Request a single buffered color buffer */ GLX_GREEN_SIZE, 8, /* with the maximum number of color bits */ GLX_BLUE_SIZE, 8, /* for each component */ None }; int pb_nconfigs = 0; GLXFBConfig *pb_configs = glXChooseFBConfig( display, DefaultScreen( display ), pbuffer_attributes, &pb_nconfigs ); int nconfigs = 0; GLXFBConfig *configs = glXChooseFBConfig( display, DefaultScreen( display ), attributes, &nconfigs ); if ( !configs || !pb_configs) { fprintf( stderr, "Num configs: %d.\n", nconfigs ); fprintf( stderr, "Num pbconfigs: %d.\n", pb_nconfigs ); exit( 1 ); } Window root = DefaultRootWindow(display); XVisualInfo* vi = glXGetVisualFromFBConfig(display, configs[0] ); XSetWindowAttributes swa; swa.border_pixel = 0; swa.event_mask = StructureNotifyMask; swa.colormap = XCreateColormap( display, root, vi->visual, AllocNone ); win = XCreateWindow(display, root, 0, 0, w, h, 0, vi->depth, InputOutput, vi->visual, CWEventMask | CWColormap, &swa); int pbuffer_create_attributes[] = { GLX_PBUFFER_WIDTH, w, GLX_PBUFFER_HEIGHT, h, 0 }; XMapWindow(display, win); XStoreName(display, win, "Trajectory Visualizer"); XEvent event; XIfEvent( display, &event, WaitForNotify, (XPointer) win); GLXPbuffer pbuffer = glXCreatePbuffer( display, configs[ 0 ], pbuffer_create_attributes ); if ( !pbuffer ) { perror( "glXCreatePbuffer" ); exit( 1 ); } GLXWindow glxwin = glXCreateWindow( display, configs[0], win, NULL ); GLXContext context = glXCreateNewContext( display, configs[ 0 ], GLX_RGBA_TYPE, 0, GL_TRUE ); GLXContext pbuffercontext = glXCreateNewContext( display, pb_configs[ 0 ], GLX_RGBA_TYPE, 0, GL_TRUE ); if ( glXMakeCurrent( display, pbuffer, context ) == 0 ) { perror( "glXMakeCurrent" ); exit( 1 ); } if (glXMakeContextCurrent( display, glxwin, glxwin, context ) == 0) { perror( "glXMakeContextCurrent" ); exit( 1 ); } glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); }
// Create the OpenGL or OpenGL ES context // GLFWbool _glfwCreateContextGLX(_GLFWwindow* window, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig) { int attribs[40]; GLXFBConfig native = NULL; GLXContext share = NULL; if (ctxconfig->share) share = ctxconfig->share->context.glx.handle; if (!chooseGLXFBConfig(fbconfig, &native)) { _glfwInputError(GLFW_FORMAT_UNAVAILABLE, "GLX: Failed to find a suitable GLXFBConfig"); return GLFW_FALSE; } if (ctxconfig->client == GLFW_OPENGL_ES_API) { if (!_glfw.glx.ARB_create_context || !_glfw.glx.ARB_create_context_profile || !_glfw.glx.EXT_create_context_es2_profile) { _glfwInputError(GLFW_API_UNAVAILABLE, "GLX: OpenGL ES requested but GLX_EXT_create_context_es2_profile is unavailable"); return GLFW_FALSE; } } if (ctxconfig->forward) { if (!_glfw.glx.ARB_create_context) { _glfwInputError(GLFW_VERSION_UNAVAILABLE, "GLX: Forward compatibility requested but GLX_ARB_create_context_profile is unavailable"); return GLFW_FALSE; } } if (ctxconfig->profile) { if (!_glfw.glx.ARB_create_context || !_glfw.glx.ARB_create_context_profile) { _glfwInputError(GLFW_VERSION_UNAVAILABLE, "GLX: An OpenGL profile requested but GLX_ARB_create_context_profile is unavailable"); return GLFW_FALSE; } } _glfwGrabErrorHandlerX11(); if (_glfw.glx.ARB_create_context) { int index = 0, mask = 0, flags = 0; if (ctxconfig->client == GLFW_OPENGL_API) { if (ctxconfig->forward) flags |= GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE) mask |= GLX_CONTEXT_CORE_PROFILE_BIT_ARB; else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE) mask |= GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; } else mask |= GLX_CONTEXT_ES2_PROFILE_BIT_EXT; if (ctxconfig->debug) flags |= GLX_CONTEXT_DEBUG_BIT_ARB; if (ctxconfig->noerror) flags |= GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR; if (ctxconfig->robustness) { if (_glfw.glx.ARB_create_context_robustness) { if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION) { setGLXattrib(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, GLX_NO_RESET_NOTIFICATION_ARB); } else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET) { setGLXattrib(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, GLX_LOSE_CONTEXT_ON_RESET_ARB); } flags |= GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB; } } if (ctxconfig->release) { if (_glfw.glx.ARB_context_flush_control) { if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE) { setGLXattrib(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB, GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB); } else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH) { setGLXattrib(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB, GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB); } } } // NOTE: Only request an explicitly versioned context when necessary, as // explicitly requesting version 1.0 does not always return the // highest version supported by the driver if (ctxconfig->major != 1 || ctxconfig->minor != 0) { setGLXattrib(GLX_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major); setGLXattrib(GLX_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor); } if (mask) setGLXattrib(GLX_CONTEXT_PROFILE_MASK_ARB, mask); if (flags) setGLXattrib(GLX_CONTEXT_FLAGS_ARB, flags); setGLXattrib(None, None); window->context.glx.handle = _glfw.glx.CreateContextAttribsARB(_glfw.x11.display, native, share, True, attribs); // HACK: This is a fallback for broken versions of the Mesa // implementation of GLX_ARB_create_context_profile that fail // default 1.0 context creation with a GLXBadProfileARB error in // violation of the extension spec if (!window->context.glx.handle) { if (_glfw.x11.errorCode == _glfw.glx.errorBase + GLXBadProfileARB && ctxconfig->client == GLFW_OPENGL_API && ctxconfig->profile == GLFW_OPENGL_ANY_PROFILE && ctxconfig->forward == GLFW_FALSE) { window->context.glx.handle = createLegacyContextGLX(window, native, share); } } } else { window->context.glx.handle = createLegacyContextGLX(window, native, share); } _glfwReleaseErrorHandlerX11(); if (!window->context.glx.handle) { _glfwInputErrorX11(GLFW_VERSION_UNAVAILABLE, "GLX: Failed to create context"); return GLFW_FALSE; } window->context.glx.window = glXCreateWindow(_glfw.x11.display, native, window->x11.handle, NULL); if (!window->context.glx.window) { _glfwInputError(GLFW_PLATFORM_ERROR, "GLX: Failed to create window"); return GLFW_FALSE; } window->context.makeCurrent = makeContextCurrentGLX; window->context.swapBuffers = swapBuffersGLX; window->context.swapInterval = swapIntervalGLX; window->context.extensionSupported = extensionSupportedGLX; window->context.getProcAddress = getProcAddressGLX; window->context.destroy = destroyContextGLX; return GLFW_TRUE; }
struct rtb_window * window_impl_open(struct rutabaga *rtb, int w, int h, const char *title, intptr_t parent) { struct xcb_rutabaga *xrtb = (void *) rtb; struct xrtb_window *self; Display *dpy; xcb_connection_t *xcb_conn; int default_screen; GLXFBConfig *fb_configs, fb_config; XVisualInfo *visual; int nfb_configs; uint32_t event_mask = XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_VISIBILITY_CHANGE | XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW | XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_KEYMAP_STATE; uint32_t value_mask = XCB_CW_BORDER_PIXEL | XCB_CW_BACK_PIXMAP | XCB_CW_BIT_GRAVITY | XCB_CW_EVENT_MASK | XCB_CW_COLORMAP; uint32_t value_list[6]; xcb_colormap_t colormap; xcb_void_cookie_t ck_window, ck_map; xcb_generic_error_t *err; assert(rtb); assert(h > 0); assert(w > 0); if (!(self = calloc(1, sizeof(*self)))) goto err_malloc; self->xrtb = xrtb; dpy = xrtb->dpy; xcb_conn = xrtb->xcb_conn; default_screen = DefaultScreen(dpy); self->screen = find_xcb_screen(xcb_conn, default_screen); if (!self->screen) { ERR("couldn't find XCB screen\n"); goto err_screen; } /** * gl configuration */ fb_configs = glXGetFBConfigs(dpy, default_screen, &nfb_configs); if (!fb_configs || !nfb_configs) { ERR("no GL configurations, bailing out\n"); goto err_gl_config; } fb_config = find_reasonable_fb_config(dpy, xcb_conn, fb_configs, nfb_configs, 0); if (!fb_config) { ERR("no reasonable GL configurations, bailing out\n"); goto err_gl_config; } visual = glXGetVisualFromFBConfig(dpy, fb_config); self->gl_ctx = new_gl_context(dpy, fb_config); if (!self->gl_ctx) { ERR("couldn't create GLX context\n"); goto err_gl_ctx; } /** * window setup */ colormap = xcb_generate_id(xcb_conn); self->xcb_win = xcb_generate_id(xcb_conn); xcb_create_colormap( xcb_conn, XCB_COLORMAP_ALLOC_NONE, colormap, self->screen->root, visual->visualid); value_list[0] = 0; value_list[1] = 0; value_list[2] = XCB_GRAVITY_STATIC; value_list[3] = event_mask; value_list[4] = colormap; value_list[5] = 0; ck_window = xcb_create_window_checked( xcb_conn, visual->depth, self->xcb_win, parent ? (xcb_window_t) parent : self->screen->root, 0, 0, w, h, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, visual->visualid, value_mask, value_list); free(visual); if ((err = xcb_request_check(xcb_conn, ck_window))) { ERR("can't create XCB window: %d\n", err->error_code); goto err_xcb_win; } get_dpi(dpy, default_screen, &self->dpi.x, &self->dpi.y); self->gl_win = glXCreateWindow(dpy, fb_config, self->xcb_win, 0); if (!self->gl_win) { ERR("couldn't create GL window\n"); goto err_gl_win; } if (set_xprop(xcb_conn, self->xcb_win, XCB_ATOM_WM_NAME, title)) set_xprop(xcb_conn, self->xcb_win, XCB_ATOM_WM_NAME, "oh no"); self->gl_draw = self->gl_win; if (!glXMakeContextCurrent( dpy, self->gl_draw, self->gl_draw, self->gl_ctx)) { ERR("couldn't activate GLX context\n"); goto err_gl_make_current; } ck_map = xcb_map_window_checked(xcb_conn, self->xcb_win); if ((err = xcb_request_check(xcb_conn, ck_map))) { ERR("can't map XCB window: %d\n", err->error_code); goto err_win_map; } if (parent) raise_window(xcb_conn, self->xcb_win); else xcb_icccm_set_wm_protocols(xcb_conn, self->xcb_win, xrtb->atoms.wm_protocols, 1, &xrtb->atoms.wm_delete_window); free(fb_configs); uv_mutex_init(&self->lock); return RTB_WINDOW(self); err_win_map: err_gl_make_current: err_gl_win: xcb_destroy_window(xcb_conn, self->xcb_win); err_xcb_win: glXDestroyContext(dpy, self->gl_ctx); err_gl_ctx: err_gl_config: free(fb_configs); err_screen: free(self); err_malloc: return NULL; }
static bool gfx_ctx_glx_set_video_mode(void *data, unsigned width, unsigned height, bool fullscreen) { XEvent event; bool true_full = false, windowed_full; int val, x_off = 0, y_off = 0; XVisualInfo *vi = NULL; XSetWindowAttributes swa = {0}; int (*old_handler)(Display*, XErrorEvent*) = NULL; driver_t *driver = driver_get_ptr(); gfx_ctx_glx_data_t *glx = (gfx_ctx_glx_data_t*)driver->video_context_data; struct sigaction sa = {{0}}; settings_t *settings = config_get_ptr(); sa.sa_handler = glx_sighandler; sa.sa_flags = SA_RESTART; sigemptyset(&sa.sa_mask); sigaction(SIGINT, &sa, NULL); sigaction(SIGTERM, &sa, NULL); if (!glx) return false; windowed_full = settings->video.windowed_fullscreen; true_full = false; vi = glXGetVisualFromFBConfig(glx->g_dpy, glx->g_fbc); if (!vi) goto error; swa.colormap = glx->g_cmap = XCreateColormap(glx->g_dpy, RootWindow(glx->g_dpy, vi->screen), vi->visual, AllocNone); swa.event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask | ButtonReleaseMask | ButtonPressMask; swa.override_redirect = fullscreen ? True : False; if (fullscreen && !windowed_full) { if (x11_enter_fullscreen(glx->g_dpy, width, height, &glx->g_desktop_mode)) { glx->g_should_reset_mode = true; true_full = true; } else RARCH_ERR("[GLX]: Entering true fullscreen failed. Will attempt windowed mode.\n"); } if (settings->video.monitor_index) glx->g_screen = settings->video.monitor_index - 1; #ifdef HAVE_XINERAMA if (fullscreen || glx->g_screen != 0) { unsigned new_width = width; unsigned new_height = height; if (x11_get_xinerama_coord(glx->g_dpy, glx->g_screen, &x_off, &y_off, &new_width, &new_height)) RARCH_LOG("[GLX]: Using Xinerama on screen #%u.\n", glx->g_screen); else RARCH_LOG("[GLX]: Xinerama is not active on screen.\n"); if (fullscreen) { width = new_width; height = new_height; } } #endif RARCH_LOG("[GLX]: X = %d, Y = %d, W = %u, H = %u.\n", x_off, y_off, width, height); glx->g_win = XCreateWindow(glx->g_dpy, RootWindow(glx->g_dpy, vi->screen), x_off, y_off, width, height, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask | (true_full ? CWOverrideRedirect : 0), &swa); XSetWindowBackground(glx->g_dpy, glx->g_win, 0); glx->g_glx_win = glXCreateWindow(glx->g_dpy, glx->g_fbc, glx->g_win, 0); x11_set_window_attr(glx->g_dpy, glx->g_win); if (fullscreen) x11_show_mouse(glx->g_dpy, glx->g_win, false); if (true_full) { RARCH_LOG("[GLX]: Using true fullscreen.\n"); XMapRaised(glx->g_dpy, glx->g_win); } else if (fullscreen) /* We attempted true fullscreen, but failed. Attempt using windowed fullscreen. */ { XMapRaised(glx->g_dpy, glx->g_win); RARCH_LOG("[GLX]: Using windowed fullscreen.\n"); /* We have to move the window to the screen we want to go fullscreen on first. * x_off and y_off usually get ignored in XCreateWindow(). */ x11_move_window(glx->g_dpy, glx->g_win, x_off, y_off, width, height); x11_windowed_fullscreen(glx->g_dpy, glx->g_win); } else { XMapWindow(glx->g_dpy, glx->g_win); // If we want to map the window on a different screen, we'll have to do it by force. // Otherwise, we should try to let the window manager sort it out. // x_off and y_off usually get ignored in XCreateWindow(). if (glx->g_screen) x11_move_window(glx->g_dpy, glx->g_win, x_off, y_off, width, height); } XIfEvent(glx->g_dpy, &event, glx_wait_notify, NULL); if (!glx->g_ctx) { if (glx->g_core_es || glx->g_debug) { int attribs[16]; int *aptr = attribs; if (glx->g_core_es) { *aptr++ = GLX_CONTEXT_MAJOR_VERSION_ARB; *aptr++ = g_major; *aptr++ = GLX_CONTEXT_MINOR_VERSION_ARB; *aptr++ = g_minor; if (glx->g_core_es_core) { /* Technically, we don't have core/compat until 3.2. * Version 3.1 is either compat or not depending on GL_ARB_compatibility. */ *aptr++ = GLX_CONTEXT_PROFILE_MASK_ARB; #ifdef HAVE_OPENGLES2 *aptr++ = GLX_CONTEXT_ES_PROFILE_BIT_EXT; #else *aptr++ = GLX_CONTEXT_CORE_PROFILE_BIT_ARB; #endif } } if (glx->g_debug) { *aptr++ = GLX_CONTEXT_FLAGS_ARB; *aptr++ = GLX_CONTEXT_DEBUG_BIT_ARB; } *aptr = None; glx->g_ctx = glx_create_context_attribs(glx->g_dpy, glx->g_fbc, NULL, True, attribs); if (glx->g_use_hw_ctx) { RARCH_LOG("[GLX]: Creating shared HW context.\n"); glx->g_hw_ctx = glx_create_context_attribs(glx->g_dpy, glx->g_fbc, glx->g_ctx, True, attribs); if (!glx->g_hw_ctx) RARCH_ERR("[GLX]: Failed to create new shared context.\n"); } } else { glx->g_ctx = glXCreateNewContext(glx->g_dpy, glx->g_fbc, GLX_RGBA_TYPE, 0, True); if (glx->g_use_hw_ctx) { glx->g_hw_ctx = glXCreateNewContext(glx->g_dpy, glx->g_fbc, GLX_RGBA_TYPE, glx->g_ctx, True); if (!glx->g_hw_ctx) RARCH_ERR("[GLX]: Failed to create new shared context.\n"); } } if (!glx->g_ctx) { RARCH_ERR("[GLX]: Failed to create new context.\n"); goto error; } } else { driver->video_cache_context_ack = true; RARCH_LOG("[GLX]: Using cached GL context.\n"); } glXMakeContextCurrent(glx->g_dpy, glx->g_glx_win, glx->g_glx_win, glx->g_ctx); XSync(glx->g_dpy, False); g_quit_atom = XInternAtom(glx->g_dpy, "WM_DELETE_WINDOW", False); if (g_quit_atom) XSetWMProtocols(glx->g_dpy, glx->g_win, &g_quit_atom, 1); glXGetConfig(glx->g_dpy, vi, GLX_DOUBLEBUFFER, &val); glx->g_is_double = val; if (glx->g_is_double) { const char *swap_func = NULL; g_pglSwapIntervalEXT = (void (*)(Display*, GLXDrawable, int))glXGetProcAddress((const GLubyte*)"glXSwapIntervalEXT"); g_pglSwapIntervalSGI = (int (*)(int))glXGetProcAddress((const GLubyte*)"glXSwapIntervalSGI"); g_pglSwapInterval = (int (*)(int))glXGetProcAddress((const GLubyte*)"glXSwapIntervalMESA"); if (g_pglSwapIntervalEXT) swap_func = "glXSwapIntervalEXT"; else if (g_pglSwapInterval) swap_func = "glXSwapIntervalMESA"; else if (g_pglSwapIntervalSGI) swap_func = "glXSwapIntervalSGI"; if (!g_pglSwapInterval && !g_pglSwapIntervalEXT && !g_pglSwapIntervalSGI) RARCH_WARN("[GLX]: Cannot find swap interval call.\n"); else RARCH_LOG("[GLX]: Found swap function: %s.\n", swap_func); } else RARCH_WARN("[GLX]: Context is not double buffered!.\n"); gfx_ctx_glx_swap_interval(data, glx->g_interval); /* This can blow up on some drivers. It's not fatal, so override errors for this call. */ old_handler = XSetErrorHandler(glx_nul_handler); XSetInputFocus(glx->g_dpy, glx->g_win, RevertToNone, CurrentTime); XSync(glx->g_dpy, False); XSetErrorHandler(old_handler); XFree(vi); glx->g_has_focus = true; if (!x11_create_input_context(glx->g_dpy, glx->g_win, &glx->g_xim, &glx->g_xic)) goto error; driver->display_type = RARCH_DISPLAY_X11; driver->video_display = (uintptr_t)glx->g_dpy; driver->video_window = (uintptr_t)glx->g_win; glx->g_true_full = true_full; return true; error: if (vi) XFree(vi); ctx_glx_destroy_resources(glx); if (glx) free(glx); return false; }
static int Open (vlc_object_t *obj) { vlc_gl_t *gl = (vlc_gl_t *)obj; if (gl->surface->type != VOUT_WINDOW_TYPE_XID || !vlc_xlib_init (obj)) return VLC_EGENERIC; /* Initialize GLX display */ Display *dpy = XOpenDisplay (gl->surface->display.x11); if (dpy == NULL) return VLC_EGENERIC; vlc_gl_sys_t *sys = malloc (sizeof (*sys)); if (unlikely(sys == NULL)) { XCloseDisplay (dpy); return VLC_ENOMEM; } gl->sys = sys; sys->display = dpy; if (!CheckGLX (obj, dpy)) goto error; /* Determine our pixel format */ XWindowAttributes wa; if (!XGetWindowAttributes (dpy, gl->surface->handle.xid, &wa)) goto error; const int snum = XScreenNumberOfScreen (wa.screen); const VisualID visual = XVisualIDFromVisual (wa.visual); static const int attr[] = { GLX_RED_SIZE, 5, GLX_GREEN_SIZE, 5, GLX_BLUE_SIZE, 5, GLX_DOUBLEBUFFER, True, GLX_X_RENDERABLE, True, GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, None }; int nelem; GLXFBConfig *confs = glXChooseFBConfig (dpy, snum, attr, &nelem); if (confs == NULL) { msg_Err (obj, "cannot choose GLX frame buffer configurations"); goto error; } GLXFBConfig conf; bool found = false; for (int i = 0; i < nelem && !found; i++) { conf = confs[i]; XVisualInfo *vi = glXGetVisualFromFBConfig (dpy, conf); if (vi == NULL) continue; if (vi->visualid == visual) found = true; XFree (vi); } XFree (confs); if (!found) { msg_Err (obj, "cannot match GLX frame buffer configuration"); goto error; } /* Create a drawing surface */ sys->win = glXCreateWindow (dpy, conf, gl->surface->handle.xid, NULL); if (sys->win == None) { msg_Err (obj, "cannot create GLX window"); goto error; } /* Create an OpenGL context */ sys->ctx = glXCreateNewContext (dpy, conf, GLX_RGBA_TYPE, NULL, True); if (sys->ctx == NULL) { glXDestroyWindow (dpy, sys->win); msg_Err (obj, "cannot create GLX context"); goto error; } /* Initialize OpenGL callbacks */ gl->sys = sys; gl->makeCurrent = MakeCurrent; gl->releaseCurrent = ReleaseCurrent; gl->resize = NULL; gl->swap = SwapBuffers; gl->getProcAddress = GetSymbol; #ifdef GLX_ARB_get_proc_address bool is_swap_interval_set = false; MakeCurrent (gl); # ifdef GLX_SGI_swap_control if (!is_swap_interval_set && CheckGLXext (dpy, snum, "GLX_SGI_swap_control")) { PFNGLXSWAPINTERVALSGIPROC SwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC) glXGetProcAddressARB ((const GLubyte *)"glXSwapIntervalSGI"); assert (SwapIntervalSGI != NULL); is_swap_interval_set = !SwapIntervalSGI (1); } # endif # ifdef GLX_EXT_swap_control if (!is_swap_interval_set && CheckGLXext (dpy, snum, "GLX_EXT_swap_control")) { PFNGLXSWAPINTERVALEXTPROC SwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC) glXGetProcAddress ((const GLubyte *)"glXSwapIntervalEXT"); assert (SwapIntervalEXT != NULL); SwapIntervalEXT (dpy, sys->win, 1); is_swap_interval_set = true; } # endif ReleaseCurrent (gl); #endif return VLC_SUCCESS; error: XCloseDisplay (dpy); free (sys); return VLC_EGENERIC; }
void init_display() { int surface_type_id, result, i, value, scrn, num_fbconfigs; GLXFBConfig *fbconfigs; XVisualInfo *visInfo; XSetWindowAttributes attributes; Window root; int attrib_pbuffer[6] = {GLX_PBUFFER_WIDTH, 0, GLX_PBUFFER_HEIGHT, 0, GLX_PRESERVED_CONTENTS, 0}; width = horizontal_size; height = vertical_size; if(chroma_format != CHROMA420) error("we only support 4:2:0 chroma formats\n"); display = XOpenDisplay(NULL); root = XDefaultRootWindow(display); scrn = XDefaultScreen(display); if(!GetPortId(display, &portNum, &surface_type_id)) error("couldn't find a suitable port\n"); #ifdef USE_DLOPEN if(!ResolveFunctions(DLFILENAME)) error("couldn't resolve necessary functions\n"); #endif result = XvMCCreateContext(display, portNum, surface_type_id, coded_picture_width, coded_picture_height, XVMC_DIRECT, &context); if(result != Success) error("couldn't create XvMCContext\n"); for(i = 0; i < numsurfaces; i++) { result = XvMCCreateSurface(display, &context, &surfaces[i]); if(result != Success) { if(i < 4) { XvMCDestroyContext(display, &context); error("couldn't create enough XvMCSurfaces\n"); } else { numsurfaces = i; printf("could only allocate %i surfaces\n", numsurfaces); } } surface_info[i].reference = 0; surface_info[i].sequence_number = 0; } slices = slices * mb_width; XvMCCreateBlocks(display, &context, slices * 6, &blocks); XvMCCreateMacroBlocks(display, &context, slices, ¯o_blocks); fbconfigs = glXChooseFBConfig(display, scrn, attr_fbconfig, &num_fbconfigs); gl_fbconfig = *fbconfigs; /* find the first one with no depth buffer */ for(i = 0; i < num_fbconfigs; i++) { glXGetFBConfigAttrib(display, fbconfigs[i], GLX_DEPTH_SIZE, &value); if(value == 0) { gl_fbconfig = fbconfigs[i]; break; } } PrintVisual(); visInfo = glXGetVisualFromFBConfig(display, gl_fbconfig); attrib_pbuffer[1] = width; attrib_pbuffer[3] = bob ? (height/2) : height; gl_pbuffer = glXCreatePbuffer(display, gl_fbconfig, attrib_pbuffer); gl_context = glXCreateNewContext(display, gl_fbconfig, GLX_RGBA_TYPE, NULL, 1); attributes.colormap = XCreateColormap(display, root, visInfo->visual, AllocNone); window = XCreateWindow(display, root, 0, 0, width, height, 0, visInfo->depth, InputOutput, visInfo->visual, CWColormap, &attributes); gl_window = glXCreateWindow(display, gl_fbconfig, window, NULL); XSelectInput(display, window, KeyPressMask | StructureNotifyMask | Button1MotionMask | ButtonPressMask); XMapWindow(display, window); glXMakeContextCurrent(display, gl_window, gl_pbuffer, gl_context); glDrawBuffer(GL_BACK); glReadBuffer(GL_FRONT_LEFT); tex_w = 1 << PowerOfTwo(width); tex_h = 1 << PowerOfTwo(bob ? (height/2) : height); printf("%i x %i texture\n", tex_w, tex_h); glClearColor (0.0, 0.0, 0.0, 0.0); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexImage2D(GL_TEXTURE_2D, 0, 3, tex_w, tex_h, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); glEnable(GL_TEXTURE_2D); glShadeModel(GL_FLAT); glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(-1.0, 1.0, -1.0, 1.0, 2, 18.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0, 0.0, -8); #ifdef USE_NV_FENCE glGenFencesNV(1, &nvFence); glSetFenceNV(&nvFence, GL_ALL_COMPLETED_NV); #endif XSync(display, 0); uiclp = uiclip+512; for (i= -512; i<512; i++) uiclp[i] = (i<-128) ? 0 : ((i>127) ? 255 : i+128); iclp = iclip+512; for (i= -512; i<512; i++) iclp[i] = (i<-128) ? -128 : ((i>127) ? 127 : i); niclp = niclip+512; for (i= -512; i<512; i++) niclp[i] = (i<-256) ? -256 : ((i>255) ? 255 : i); }
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; }
int main(int argc, char **argv) { opt_data opts; optproc(argc, argv, &opts); if(audio_init(&opts) < 0) exit(1); int x = 0, y = 0, w, h; if(opts.w < 0 && opts.h < 0) opts.w = opts.h = 512; else if(opts.w < 0) opts.w = opts.h; else if(opts.h < 0) opts.h = opts.w; w = opts.w; h = opts.h; XEvent event; dpy = XOpenDisplay( NULL ); if(dpy == NULL) { printf("Error: couldn't open display %s\n", getenv("DISPLAY")); exit(EXIT_FAILURE); } int glx_major, glx_minor; if(!glXQueryVersion(dpy, &glx_major, &glx_minor)) { printf("GLX extension missing!\n"); XCloseDisplay(dpy); exit(EXIT_FAILURE); } printf("GLX version %i.%i\n", glx_major, glx_minor); int glxErrBase, glxEventBase; glXQueryExtension(dpy, &glxErrBase, &glxEventBase); printf("GLX: errorBase = %i, eventBase = %i\n", glxErrBase, glxEventBase); Window xwin, root; int numReturned; GLXFBConfig *fbConfigs; fbConfigs = glXChooseFBConfig( dpy, DefaultScreen(dpy), fbattrib, &numReturned ); if(fbConfigs == NULL) { //TODO: handle this? printf("No suitable fbconfigs!\n"); exit(EXIT_FAILURE); } XVisualInfo *vinfo = glXGetVisualFromFBConfig( dpy, fbConfigs[0] ); root = DefaultRootWindow(dpy); /* window attributes */ XSetWindowAttributes attrs; attrs.background_pixel = 0; attrs.border_pixel = 0; attrs.colormap = XCreateColormap(dpy, root, vinfo->visual, AllocNone); //attrs.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask; attrs.event_mask = StructureNotifyMask | KeyPressMask; unsigned long mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; xwin = XCreateWindow(dpy, root, x, y, w, h, 0, vinfo->depth, InputOutput, vinfo->visual, mask, &attrs); XFree(vinfo); // Set hints and properties: { XSizeHints sizehints; sizehints.x = x; sizehints.y = y; sizehints.width = w; sizehints.height = h; sizehints.flags = USSize | USPosition; XSetNormalHints(dpy, xwin, &sizehints); XSetStandardProperties(dpy, xwin, "Julia-vis", "Julia-vis", None, (char **)NULL, 0, &sizehints); } /* Create a GLX context for OpenGL rendering */ GLXContext context = glXCreateNewContext(dpy, fbConfigs[0], GLX_RGBA_TYPE, NULL, True ); #if 0 GLXContext context = 0; glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0; glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)glXGetProcAddressARB( (const GLubyte *) "glXCreateContextAttribsARB" ); if(strstr(glXQueryExtensionsString(dpy, 0), "GLX_ARB_create_context") || !glXCreateContextAttribsARB) { printf("glXCreateContextAttribsARB() not found ... using old-style GLX context\n"); context = glXCreateNewContext(dpy, fbConfigs[0], GLX_RGBA_TYPE, 0, True); } else { const int context_attribs[] = { GLX_RENDER_TYPE, GLX_RGBA_TYPE, GLX_CONTEXT_MAJOR_VERSION_ARB, 2, GLX_CONTEXT_MINOR_VERSION_ARB, 1, None }; context = glXCreateContextAttribsARB(dpy, fbConfigs[0], NULL, True, context_attribs); } if(context == NULL) { printf("Failed to create context!\n"); return EXIT_FAILURE; } #endif glxWin = glXCreateWindow(dpy, fbConfigs[0], xwin, NULL ); XMapWindow(dpy, xwin); XIfEvent(dpy, &event, WaitForNotify, (XPointer) xwin); glXMakeContextCurrent(dpy, glxWin, glxWin, context); init_gl(&opts, w, h); if(strstr(glXQueryExtensionsString(dpy, 0), "GLX_MESA_swap_control")) { PFNGLXSWAPINTERVALMESAPROC swap_interval = glXGetProcAddressARB("glXSwapIntervalMESA"); swap_interval(1); opts.draw_rate = 300; } if(strstr(glXQueryExtensionsString(dpy, 0), "GLX_INTEL_swap_event")) { glXSelectEvent(dpy, glxWin, GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK); have_intel_swap_event = GL_TRUE; } int debug_maxsrc = 0, debug_pal = 0, show_mandel = 0, show_fps_hist = 0; if(have_intel_swap_event) render_frame(debug_maxsrc, debug_pal, show_mandel, show_fps_hist); while(1) { if(!have_intel_swap_event) render_frame(debug_maxsrc, debug_pal, show_mandel, show_fps_hist); int clear_key = 1; while (XPending(dpy) > 0) { XNextEvent(dpy, &event); if(event.type == glxEventBase + GLX_BufferSwapComplete) { render_frame(debug_maxsrc, debug_pal, show_mandel, show_fps_hist); continue; } switch (event.type) { case Expose: /* we'll redraw below */ break; /*case ConfigureNotify: window_w = event.xconfigure.width; window_h = event.xconfigure.height; if (surface_type == EGL_WINDOW_BIT) reshape(window_w, window_h); break;*/ case KeyPress: { clear_key = 0; char buffer[10]; int r, code; code = XLookupKeysym(&event.xkey, 0); if (code == XK_F1) { debug_maxsrc = !debug_maxsrc; } else if (code == XK_F2) { debug_pal = !debug_pal; } else if (code == XK_F3) { show_mandel = !show_mandel; } else if (code == XK_F4) { show_fps_hist = !show_fps_hist; } else { code = XLookupKeysym(&event.xkey, 1); if(code == XK_Escape) { goto glx_main_loop_quit; } } } break; default: //printf("Bar %i!\n", event.type); break; } } } glx_main_loop_quit: audio_shutdown(); XDestroyWindow(dpy, xwin); XCloseDisplay(dpy); return 0; }