void GlxBackend::present() { if (lastDamage().isEmpty()) return; const QSize &screenSize = screens()->size(); const QRegion displayRegion(0, 0, screenSize.width(), screenSize.height()); const bool fullRepaint = supportsBufferAge() || (lastDamage() == displayRegion); if (fullRepaint) { if (m_haveINTELSwapEvent) Compositor::self()->aboutToSwapBuffers(); if (haveSwapInterval) { if (gs_tripleBufferNeedsDetection) { glXWaitGL(); m_swapProfiler.begin(); } glXSwapBuffers(display(), glxWindow); if (gs_tripleBufferNeedsDetection) { glXWaitGL(); if (char result = m_swapProfiler.end()) { gs_tripleBufferUndetected = gs_tripleBufferNeedsDetection = false; if (result == 'd' && GLPlatform::instance()->driver() == Driver_NVidia) { // TODO this is a workaround, we should get __GL_YIELD set before libGL checks it if (qstrcmp(qgetenv("__GL_YIELD"), "USLEEP")) { options->setGlPreferBufferSwap(0); setSwapInterval(0); result = 0; // hint proper behavior qCWarning(KWIN_CORE) << "\nIt seems you are using the nvidia driver without triple buffering\n" "You must export __GL_YIELD=\"USLEEP\" to prevent large CPU overhead on synced swaps\n" "Preferably, enable the TripleBuffer Option in the xorg.conf Device\n" "For this reason, the tearing prevention has been disabled.\n" "See https://bugs.kde.org/show_bug.cgi?id=322060\n"; } } setBlocksForRetrace(result == 'd'); } } else if (blocksForRetrace()) { // at least the nvidia blob manages to swap async, ie. return immediately on double // buffering - what messes our timing calculation and leads to laggy behavior #346275 glXWaitGL(); } } else { waitSync(); glXSwapBuffers(display(), glxWindow); } if (supportsBufferAge()) { glXQueryDrawable(display(), glxWindow, GLX_BACK_BUFFER_AGE_EXT, (GLuint *) &m_bufferAge); } } else if (m_haveMESACopySubBuffer) { foreach (const QRect & r, lastDamage().rects()) { // convert to OpenGL coordinates int y = screenSize.height() - r.y() - r.height(); glXCopySubBufferMESA(display(), glxWindow, r.x(), y, r.width(), r.height()); } } else { // Copy Pixels (horribly slow on Mesa)
void GlxBackend::present() { if (lastDamage().isEmpty()) return; const QRegion displayRegion(0, 0, displayWidth(), displayHeight()); const bool fullRepaint = supportsBufferAge() || (lastDamage() == displayRegion); if (fullRepaint) { if (haveSwapInterval) { if (gs_tripleBufferNeedsDetection) { glXWaitGL(); m_swapProfiler.begin(); } glXSwapBuffers(display(), glxWindow); if (gs_tripleBufferNeedsDetection) { glXWaitGL(); if (char result = m_swapProfiler.end()) { gs_tripleBufferUndetected = gs_tripleBufferNeedsDetection = false; if (result == 'd' && GLPlatform::instance()->driver() == Driver_NVidia) { // TODO this is a workaround, we should get __GL_YIELD set before libGL checks it if (qstrcmp(qgetenv("__GL_YIELD"), "USLEEP")) { options->setGlPreferBufferSwap(0); setSwapInterval(0); qWarning() << "\nIt seems you are using the nvidia driver without triple buffering\n" "You must export __GL_YIELD=\"USLEEP\" to prevent large CPU overhead on synced swaps\n" "Preferably, enable the TripleBuffer Option in the xorg.conf Device\n" "For this reason, the tearing prevention has been disabled.\n" "See https://bugs.kde.org/show_bug.cgi?id=322060\n"; } } setBlocksForRetrace(result == 'd'); } } } else { waitSync(); glXSwapBuffers(display(), glxWindow); } if (supportsBufferAge()) { glXQueryDrawable(display(), glxWindow, GLX_BACK_BUFFER_AGE_EXT, (GLuint *) &m_bufferAge); } } else if (glXCopySubBuffer) { foreach (const QRect & r, lastDamage().rects()) { // convert to OpenGL coordinates int y = displayHeight() - r.y() - r.height(); glXCopySubBuffer(display(), glxWindow, r.x(), y, r.width(), r.height()); } } else { // Copy Pixels (horribly slow on Mesa)
void resize(int w, int h) { if (w == width && h == height) { return; } glXWaitGL(); // We need to ensure that pending events are processed here, and XSync // with discard = True guarantees that, but it appears the limited // event processing we do so far is sufficient //XSync(display, True); Drawable::resize(w, h); // Tell the window manager to respect the requested size XSizeHints size_hints; size_hints.max_width = size_hints.min_width = w; size_hints.max_height = size_hints.min_height = h; size_hints.flags = PMinSize | PMaxSize; XSetWMNormalHints(display, window, &size_hints); XResizeWindow(display, window, w, h); waitForEvent(ConfigureNotify); glXWaitX(); }
void _gdk_gl_pixmap_destroy (GdkGLPixmap *glpixmap) { GdkGLPixmapImplX11 *impl = GDK_GL_PIXMAP_IMPL_X11 (glpixmap); Display *xdisplay; GDK_GL_NOTE_FUNC_PRIVATE (); if (impl->is_destroyed) return; xdisplay = GDK_GL_CONFIG_XDISPLAY (impl->glconfig); if (impl->glxpixmap == glXGetCurrentDrawable ()) { glXWaitGL (); GDK_GL_NOTE_FUNC_IMPL ("glXMakeCurrent"); glXMakeCurrent (xdisplay, None, NULL); } GDK_GL_NOTE_FUNC_IMPL ("glXDestroyGLXPixmap"); glXDestroyGLXPixmap (xdisplay, impl->glxpixmap); impl->glxpixmap = None; impl->is_destroyed = TRUE; }
void gl_finish() { glFlush(); #ifndef _WIN32 glXWaitGL(); #endif }
void _gdk_gl_window_destroy (GdkGLWindow *glwindow) { GdkGLWindowImplX11 *impl = GDK_GL_WINDOW_IMPL_X11 (glwindow); Display *xdisplay; GdkGL_GLX_MESA_release_buffers *mesa_ext; GDK_GL_NOTE_FUNC_PRIVATE (); if (impl->is_destroyed) return; xdisplay = GDK_GL_CONFIG_XDISPLAY (impl->glconfig); if (impl->glxwindow == glXGetCurrentDrawable ()) { glXWaitGL (); GDK_GL_NOTE_FUNC_IMPL ("glXMakeCurrent"); glXMakeCurrent (xdisplay, None, NULL); } /* If GLX_MESA_release_buffers is supported. */ mesa_ext = gdk_gl_get_GLX_MESA_release_buffers (impl->glconfig); if (mesa_ext) { GDK_GL_NOTE_FUNC_IMPL ("glXReleaseBuffersMESA"); mesa_ext->glXReleaseBuffersMESA (xdisplay, impl->glxwindow); } impl->glxwindow = None; impl->is_destroyed = TRUE; }
Word NewGameWindow(Word NewVidSize) { XSizeHints sizehints; if (NewVidSize == VidSize) return VidSize; if (NewVidSize < 4) { w = VidXs[NewVidSize]; h = VidYs[NewVidSize]; v = VidVs[NewVidSize]; } else { fprintf(stderr, "Invalid Vid size: %d\n", NewVidSize); exit(EXIT_FAILURE); } sizehints.min_width = w; sizehints.min_height = h; sizehints.flags = PMinSize; XSetWMNormalHints(dpy, win, &sizehints); XResizeWindow(dpy, win, w, h); SetAPalette(rBlackPal); ClearTheScreen(BLACK); BlastScreen(); VidSize = NewVidSize; XSync(dpy, False); glXWaitGL(); glXWaitX(); HandleEvents(); return VidSize; }
JNIEXPORT void JNICALL GLX_NATIVE(glXWaitGL) (JNIEnv *env, jclass that) { GLX_NATIVE_ENTER(env, that, glXWaitGL_FUNC); glXWaitGL(); GLX_NATIVE_EXIT(env, that, glXWaitGL_FUNC); }
void draw() { int i; GLfloat width, height; glXWaitX(); check_gl(__LINE__); //XGrabServer(dpy); glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); check_gl(__LINE__); draw_background(); for (i=0; i<MAX_CLIENTS; i++) { if (workspace == NULL || workspace[i].window == 0) break; Client client = workspace[i]; width = (GLfloat) client.geom.width; height = (GLfloat) client.geom.height; //info("Drawing %d window => 0x%x, %g x %g\n", i, client.window, width, height); if(client.geom.depth == 32) { info("Using blending\n"); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); // X windows are premultiplied } else glDisable(GL_BLEND); glEnable(client.target); check_gl(__LINE__); glBindTexture(client.target, client.texture); check_gl(__LINE__); glXBindTexImageProc(dpy, client.glxpixmap, GLX_FRONT_LEFT_EXT, NULL); check_gl(__LINE__); glTexParameterf(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_LINEAR); check_gl(__LINE__); glBegin(GL_QUADS); glColor3d(1.0, 1.0, 1.0); glTexCoord2f(left*width, bottom*height); glVertex3f(0.00f, 0.000f, 1.0f); glTexCoord2f(left*width, top*height); glVertex3f(0.00f, height, 1.0f); glTexCoord2f(right*width, top*height); glVertex3f(width, height, 1.0f); glTexCoord2f(right*width, bottom*height); glVertex3f(width, 0.000f, 1.0f); glEnd(); check_gl(__LINE__); glBindTexture(client.target, 0); check_gl(__LINE__); glDisable(client.target); check_gl(__LINE__); glXReleaseTexImageProc(dpy, client.glxpixmap, GLX_FRONT_LEFT_EXT); check_gl(__LINE__); } glXWaitGL(); check_gl(__LINE__); glXSwapBuffers(dpy, canvas); check_gl(__LINE__); usleep(2000); // 50Hz XEvent ev; ev.type = ClientMessage; ev.xclient.display = dpy; ev.xclient.window = root; ev.xclient.format = 8; XSendEvent(dpy, overlay, False, SubstructureNotifyMask, &ev); XFlush(dpy); //XUngrabServer(dpy); }
//================================================================ void* GLB_Create () { //================================================================ /// GLB_Create create opengl-window (used by GUI_gl__) GtkWidget *area; int xscreen, i1; GdkScreen *screen; GdkVisual *visual; Window root; XVisualInfo *xvisual; Colormap xcolormap; int attributes[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, True, GLX_DEPTH_SIZE, 24, None }; GLB_x_id = 0; // reset area = gtk_drawing_area_new (); gtk_widget_set_double_buffered (area, FALSE); GLB_display = gdk_x11_get_default_xdisplay (); xscreen = DefaultScreen (GLB_display); screen = gdk_screen_get_default (); // printf(" screenNr = %d\n",gdk_screen_get_number(screen)); xvisual = glXChooseVisual (GLB_display, xscreen, attributes); // printf(" xvisualid=%d\n",xvisual->visualid); visual = gdk_x11_screen_lookup_visual (screen, xvisual->visualid); root = RootWindow (GLB_display, xscreen); xcolormap = XCreateColormap (GLB_display, root, xvisual->visual, AllocNone); glXGetConfig (GLB_display, xvisual, GLX_RED_SIZE, &i1); printf(" GLX_RED_SIZE=%d\n",i1); glXGetConfig (GLB_display, xvisual, GLX_DEPTH_SIZE, &i1); printf(" GLX_DEPTH_SIZE=%d\n",i1); // Gtk2 only: //colormap = gdk_x11_colormap_foreign_new (visual, xcolormap); //gtk_widget_set_colormap (area, colormap); GLB_x_context = glXCreateContext (GLB_display, xvisual, NULL, TRUE); // free (xvisual); glXWaitX(); glXWaitGL(); return area; }
void show(void) { if (visible) { return; } glXWaitGL(); showWindow(window); glXWaitX(); Drawable::show(); }
void show(void) override { if (!window || visible) { return; } glXWaitGL(); showWindow(window); glXWaitX(); Drawable::show(); }
void show(void) { if (visible) { return; } glXWaitGL(); XMapWindow(display, window); waitForEvent(MapNotify); glXWaitX(); Drawable::show(); }
void color_resultbg() { float redcol, greencol, bluecol; redcol = (float)mr/255.0; greencol = (float)mg/255.0; bluecol = (float)mb/255.0; glXWaitX(); glXMakeCurrent(dpy,bgwindowid,bg_context); glClearColor(redcol,greencol,bluecol,1.0); glClear(GL_COLOR_BUFFER_BIT); if (doubleBuffer == GL_TRUE) glXSwapBuffers(dpy, bgwindowid); glClear(GL_COLOR_BUFFER_BIT); if (doubleBuffer == GL_TRUE) glXSwapBuffers(dpy, bgwindowid); glXWaitGL(); }
int XdevLOpenGLContextGLX::makeCurrent(XdevLWindow* window) { // Display* xdisplay = static_cast<Display*>(window->getInternal(XdevLInternalName("X11_DISPLAY"))); // if(nullptr == xdisplay) { // return RET_FAILED; // } // // Window xwindow = (Window)(window->getInternal(XdevLInternalName("X11_WINDOW"))); // if(None == xdisplay) { // return RET_FAILED; // } glXWaitGL(); if(glXMakeCurrent(m_display, m_window, m_glxContext) == True) { return RET_SUCCESS; } return RET_FAILED; }
static void clutter_backend_glx_redraw (ClutterBackend *backend, ClutterStage *stage) { ClutterStageGLX *stage_glx; ClutterStageX11 *stage_x11; ClutterStageWindow *impl; impl = _clutter_stage_get_window (stage); if (G_UNLIKELY (impl == NULL)) { CLUTTER_NOTE (BACKEND, "Stage [%p] has no implementation", stage); return; } g_assert (CLUTTER_IS_STAGE_GLX (impl)); stage_x11 = CLUTTER_STAGE_X11 (impl); stage_glx = CLUTTER_STAGE_GLX (impl); /* this will cause the stage implementation to be painted */ clutter_actor_paint (CLUTTER_ACTOR (stage)); cogl_flush (); if (stage_x11->xwin != None) { /* wait for the next vblank */ CLUTTER_NOTE (BACKEND, "Waiting for vblank"); glx_wait_for_vblank (CLUTTER_BACKEND_GLX (backend)); /* push on the screen */ CLUTTER_NOTE (BACKEND, "glXSwapBuffers (display: %p, window: 0x%lx)", stage_x11->xdpy, (unsigned long) stage_x11->xwin); glXSwapBuffers (stage_x11->xdpy, stage_x11->xwin); } else { /* offscreen */ glXWaitGL (); CLUTTER_GLERR (); } }
void resize(int w, int h) { if (w == width && h == height) { return; } glXWaitGL(); // We need to ensure that pending events are processed here, and XSync // with discard = True guarantees that, but it appears the limited // event processing we do so far is sufficient //XSync(display, True); Drawable::resize(w, h); resizeWindow(window, w, h); glXWaitX(); }
static DFBResult update_screen( DFBX11 *x11, const DFBRectangle *clip, CoreSurfaceBufferLock *lock, XWindow *xw ) { void *dst; void *src; unsigned int offset = 0; XImage *ximage; CoreSurface *surface; CoreSurfaceAllocation *allocation; DFBX11Shared *shared; DFBRectangle rect; bool direct = false; D_ASSERT( x11 != NULL ); DFB_RECTANGLE_ASSERT( clip ); D_DEBUG_AT( X11_Update, "%s( %4d,%4d-%4dx%4d )\n", __FUNCTION__, DFB_RECTANGLE_VALS( clip ) ); CORE_SURFACE_BUFFER_LOCK_ASSERT( lock ); shared = x11->shared; D_ASSERT( shared != NULL ); XLockDisplay( x11->display ); if (!xw) { XUnlockDisplay( x11->display ); return DFB_OK; } allocation = lock->allocation; CORE_SURFACE_ALLOCATION_ASSERT( allocation ); surface = allocation->surface; D_ASSERT( surface != NULL ); rect.x = rect.y = 0; rect.w = xw->width; rect.h = xw->height; if (!dfb_rectangle_intersect( &rect, clip )) { XUnlockDisplay( x11->display ); return DFB_OK; } D_DEBUG_AT( X11_Update, " -> %4d,%4d-%4dx%4d\n", DFB_RECTANGLE_VALS( &rect ) ); #ifdef USE_GLX /* Check for GLX allocation... */ if (allocation->pool == shared->glx_pool && lock->handle) { LocalPixmap *pixmap = lock->handle; D_MAGIC_ASSERT( pixmap, LocalPixmap ); /* ...and just call SwapBuffers... */ //D_DEBUG_AT( X11_Update, " -> Calling glXSwapBuffers( 0x%lx )...\n", alloc->drawable ); //glXSwapBuffers( x11->display, alloc->drawable ); D_DEBUG_AT( X11_Update, " -> Copying from GLXPixmap...\n" ); glXWaitGL(); XCopyArea( x11->display, pixmap->pixmap, xw->window, xw->gc, rect.x, rect.y, rect.w, rect.h, rect.x, rect.y ); glXWaitX(); XUnlockDisplay( x11->display ); return DFB_OK; } #endif /* Check for our special native allocation... */ if (allocation->pool == shared->x11image_pool && lock->handle) { x11Image *image = lock->handle; D_MAGIC_ASSERT( image, x11Image ); /* ...and directly XShmPutImage from that. */ ximage = image->ximage; direct = true; } else { /* ...or copy or convert into XShmImage or XImage allocated with the XWindow. */ ximage = xw->ximage; offset = xw->ximage_offset; xw->ximage_offset = (offset ? 0 : ximage->height / 2); /* make sure the 16-bit input formats are properly 2-pixel-clipped */ switch (surface->config.format) { case DSPF_I420: case DSPF_YV12: case DSPF_NV12: case DSPF_NV21: if (rect.y & 1) { rect.y--; rect.h++; } /* fall through */ case DSPF_YUY2: case DSPF_UYVY: case DSPF_NV16: if (rect.x & 1) { rect.x--; rect.w++; } default: /* no action */ break; } dst = xw->virtualscreen + rect.x * xw->bpp + (rect.y + offset) * ximage->bytes_per_line; src = lock->addr + DFB_BYTES_PER_LINE( surface->config.format, rect.x ) + rect.y * lock->pitch; switch (xw->depth) { case 32: dfb_convert_to_argb( surface->config.format, src, lock->pitch, surface->config.size.h, dst, ximage->bytes_per_line, rect.w, rect.h ); break; case 24: dfb_convert_to_rgb32( surface->config.format, src, lock->pitch, surface->config.size.h, dst, ximage->bytes_per_line, rect.w, rect.h ); break; case 16: if (surface->config.format == DSPF_LUT8) { int width = rect.w; int height = rect.h; const u8 *src8 = src; u16 *dst16 = dst; CorePalette *palette = surface->palette; int x; while (height--) { for (x=0; x<width; x++) { DFBColor color = palette->entries[src8[x]]; dst16[x] = PIXEL_RGB16( color.r, color.g, color.b ); } src8 += lock->pitch; dst16 += ximage->bytes_per_line / 2; } } else { dfb_convert_to_rgb16( surface->config.format, src, lock->pitch, surface->config.size.h, dst, ximage->bytes_per_line, rect.w, rect.h ); } break; case 15: dfb_convert_to_rgb555( surface->config.format, src, lock->pitch, surface->config.size.h, dst, ximage->bytes_per_line, rect.w, rect.h ); break; default: D_ONCE( "unsupported depth %d", xw->depth ); } } D_ASSERT( ximage != NULL ); /* Wait for previous data to be processed... */ XSync( x11->display, False ); /* ...and immediately queue or send the next! */ if (x11->use_shm) { /* Just queue the command, it's XShm :) */ XShmPutImage( xw->display, xw->window, xw->gc, ximage, rect.x, rect.y + offset, rect.x, rect.y, rect.w, rect.h, False ); /* Make sure the queue has really happened! */ XFlush( x11->display ); } else /* Initiate transfer of buffer... */ XPutImage( xw->display, xw->window, xw->gc, ximage, rect.x, rect.y + offset, rect.x, rect.y, rect.w, rect.h ); /* Wait for display if single buffered and not converted... */ if (direct && !(surface->config.caps & DSCAPS_FLIPPING)) XSync( x11->display, False ); XUnlockDisplay( x11->display ); return DFB_OK; }
DECLEXPORT(EGLBoolean) eglWaitClient(void) { glXWaitGL(); return clearEGLError(); }
xdl_int XdevLOpenGLContextGLX::initOpenGL(Display* display, Window window) { // // Get all supported extensions. // std::string tmp(glXQueryExtensionsString(display, DefaultScreen(display))); std::vector<std::string> exlist; xstd::tokenize(tmp, exlist, " "); for(auto extension : exlist) { extensionsList.push_back(XdevLString(extension)); } std::vector<int> attribute_list; // --------------------------------------------------------------------------- // Prepare the attribute values for the glXChooseVisual function // attribute_list.push_back(GLX_X_RENDERABLE); attribute_list.push_back(True); // We are going to use the normal RGBA color type, not the color index type. attribute_list.push_back(GLX_RENDER_TYPE); attribute_list.push_back(GLX_RGBA_BIT); // This window is going to use only Window type, that means we can't use PBuffers. // Valid values are GLX WINDOW BIT, GLX PIXMAP BIT, GLX PBUFFER BIT. All can be used at the same time. attribute_list.push_back(GLX_DRAWABLE_TYPE); attribute_list.push_back(GLX_WINDOW_BIT); if(m_attributes.red_size > 0) { attribute_list.push_back(GLX_RED_SIZE); attribute_list.push_back(m_attributes.red_size); } if(m_attributes.green_size > 0) { attribute_list.push_back(GLX_GREEN_SIZE); attribute_list.push_back(m_attributes.green_size); } if(m_attributes.blue_size > 0) { attribute_list.push_back(GLX_BLUE_SIZE); attribute_list.push_back(m_attributes.blue_size); } if(m_attributes.alpha_size > 0) { attribute_list.push_back(GLX_ALPHA_SIZE); attribute_list.push_back(m_attributes.alpha_size); } if((m_attributes.red_size > 0) || (m_attributes.green_size > 0) || (m_attributes.blue_size > 0) || (m_attributes.alpha_size > 0) ) { attribute_list.push_back(GLX_BUFFER_SIZE); attribute_list.push_back(m_attributes.color_buffer_size); } attribute_list.push_back(GLX_DEPTH_SIZE); attribute_list.push_back(m_attributes.depth_size); attribute_list.push_back(GLX_STENCIL_SIZE); attribute_list.push_back(m_attributes.stencil_size); // attribute_list.push_back(GLX_ACCUM_RED_SIZE); // attribute_list.push_back(m_attributes.accum_red_size); // // attribute_list.push_back(GLX_ACCUM_GREEN_SIZE); // attribute_list.push_back(m_attributes.accum_green_size); // // attribute_list.push_back(GLX_ACCUM_BLUE_SIZE); // attribute_list.push_back(m_attributes.accum_blue_size); // // attribute_list.push_back(GLX_ACCUM_ALPHA_SIZE); // attribute_list.push_back(m_attributes.accum_alpha_size); if(m_attributes.stereo > 0) { attribute_list.push_back(GLX_STEREO); attribute_list.push_back(True); } if(m_attributes.multisample_buffers > 0) { attribute_list.push_back(GLX_SAMPLE_BUFFERS); attribute_list.push_back(GL_TRUE); attribute_list.push_back(GLX_SAMPLES); attribute_list.push_back(m_attributes.multisample_samples); } if(m_attributes.double_buffer > 0) { attribute_list.push_back(GLX_DOUBLEBUFFER); attribute_list.push_back(GL_TRUE); } attribute_list.push_back(None); // // Get all supported visual configurations. // xdl_int numberOfConfigs; GLXFBConfig *fbcfg = glXChooseFBConfig(display, DefaultScreen(display), attribute_list.data(), &numberOfConfigs); if(!fbcfg) { XDEVL_MODULE_ERROR("glXChooseFBConfig failed\n"); return RET_FAILED; } // // Retrieve the X Visual associated with a GLXFBConfig // int best_fbc = -1; int worst_fbc = -1; int best_num_samples = -1; int worst_num_samples = 999; for(auto i = 0; i < numberOfConfigs; i++) { XVisualInfo* vi = glXGetVisualFromFBConfig(display, fbcfg[i]); if(nullptr != vi) { int sample_buffer, samples; glXGetFBConfigAttrib(display, fbcfg[i], GLX_SAMPLE_BUFFERS, &sample_buffer); glXGetFBConfigAttrib(display, fbcfg[i], GLX_SAMPLES, &samples); if(best_fbc < 0 || (sample_buffer && samples) > best_num_samples) { best_fbc = i; best_num_samples = samples; } if(worst_fbc < 0 || (!sample_buffer && samples) < worst_num_samples) { worst_fbc = i; worst_num_samples = samples; } } XFree(vi); } /// Now get the GLXFBConfig for the best match. GLXFBConfig bestFbc = fbcfg[best_fbc]; XFree(fbcfg); XDEVL_MODULEX_INFO(XdevLOpenGLContextGLX, "--- GLXFBConfig ---\n"); dumpConfigInfo(bestFbc); XDEVL_MODULEX_INFO(XdevLOpenGLContextGLX, "-------------------\n"); m_visualInfo = glXGetVisualFromFBConfig(display, bestFbc); // Change the windows color map. XSetWindowAttributes swa; swa.colormap = XCreateColormap(display, RootWindow(display, m_visualInfo->screen), m_visualInfo->visual, AllocNone); XChangeWindowAttributes(display, window, CWColormap, &swa); glXWaitGL(); // TODO: This is the easiest way to create a visual for X11. You should do that in a better way cengiz. // m_visualInfo = glXChooseVisual(display, DefaultScreen(display), attribute_list.data()); // if(nullptr == m_visualInfo) { // XDEVL_MODULE_ERROR("glXChooseVisual failed. Please try different framebuffer, depthbuffer, stencilbuffer values.\n"); // return RET_FAILED; // } // // Set OpenGL 3.0 > attributes. // std::vector<int> opengl_profile_attribute_list; opengl_profile_attribute_list.push_back(GLX_CONTEXT_MAJOR_VERSION_ARB); opengl_profile_attribute_list.push_back(m_attributes.context_major_version); opengl_profile_attribute_list.push_back(GLX_CONTEXT_MINOR_VERSION_ARB); opengl_profile_attribute_list.push_back(m_attributes.context_minor_version); if((m_attributes.context_flags & XDEVL_OPENGL_CONTEXT_FLAGS_DEBUG_BIT) || (m_attributes.context_flags & XDEVL_OPENGL_CONTEXT_FLAGS_FORWARD_COMPATIBLE_BIT)) { opengl_profile_attribute_list.push_back(GLX_CONTEXT_FLAGS_ARB); if(m_attributes.context_flags == XDEVL_OPENGL_CONTEXT_FLAGS_DEBUG_BIT) { opengl_profile_attribute_list.push_back(GLX_CONTEXT_DEBUG_BIT_ARB); } else if(m_attributes.context_flags == XDEVL_OPENGL_CONTEXT_FLAGS_FORWARD_COMPATIBLE_BIT) { opengl_profile_attribute_list.push_back(GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB); } } if((m_attributes.context_profile_mask == XDEVL_OPENGL_CONTEXT_CORE_PROFILE) || (m_attributes.context_profile_mask == XDEVL_OPENGL_CONTEXT_COMPATIBILITY)) { opengl_profile_attribute_list.push_back(GLX_CONTEXT_PROFILE_MASK_ARB); if(m_attributes.context_profile_mask == XDEVL_OPENGL_CONTEXT_CORE_PROFILE) { opengl_profile_attribute_list.push_back(GLX_CONTEXT_CORE_PROFILE_BIT_ARB); } else if(m_attributes.context_profile_mask == XDEVL_OPENGL_CONTEXT_COMPATIBILITY) { opengl_profile_attribute_list.push_back(GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB); } } opengl_profile_attribute_list.push_back(None); XDEVL_MODULEX_INFO(XdevLOpenGLContextGLX, "OpenGL: " << m_attributes.context_major_version << "." << m_attributes.context_minor_version << std::endl); // // Try to use new ARB_create_context and ARB_create_context_profile // auto sharedContext = m_shareContext ? m_shareContext->getNativeContext() : nullptr; if(nullptr != glXCreateContextAttribs) { // // Create the context. // m_glxContext = glXCreateContextAttribs(display, bestFbc, sharedContext, True, opengl_profile_attribute_list.data()); if(nullptr == m_glxContext) { XDEVL_MODULEX_ERROR(XdevLOpenGLContextGLX, "glXCreateContext failed.\n"); return RET_FAILED; } // // Check for other erros. // glXWaitGL(); if(xdl_true == contextErrorOccured) { // m_glxContext = glXCreateContext(display, m_visualInfo, sharedContext, GL_TRUE); } } else { // // OK, not supported, let's use old function. // m_glxContext = glXCreateContext(display, m_visualInfo, sharedContext, GL_TRUE); if(nullptr == m_glxContext) { XDEVL_MODULEX_ERROR(XdevLOpenGLContextGLX, "glXCreateContext failed.\n"); return RET_FAILED; } } // setEnableFSAA(xdl_true); // // Make it current. // // GLXWindow glxWindow = glXCreateWindow(display, bestFbc, window, nullptr); // GLXDrawable drawable = glxWindow; // glXMakeContextCurrent(display, drawable, drawable, m_glxContext); if(glXMakeCurrent(display, window, m_glxContext) == False) { return RET_FAILED; } return RET_SUCCESS; }