int QPaintDevice::x11Screen() const { const QX11Info *info = qt_x11Info(this); if (info) return info->screen(); return QX11Info::appScreen(); }
void QGLContext::makeCurrent() { Q_D(QGLContext); if (!d->valid) { qWarning("QGLContext::makeCurrent(): Cannot make invalid context current."); return; } const QX11Info *xinfo = qt_x11Info(d->paintDevice); bool ok = true; if (d->paintDevice->devType() == QInternal::Pixmap) { ok = glXMakeCurrent(xinfo->display(), (GLXPixmap)d->gpm, (GLXContext)d->cx); } else if (d->paintDevice->devType() == QInternal::Pbuffer) { ok = glXMakeCurrent(xinfo->display(), (GLXPbuffer)d->pbuf, (GLXContext)d->cx); } else if (d->paintDevice->devType() == QInternal::Widget) { ok = glXMakeCurrent(xinfo->display(), ((QWidget *)d->paintDevice)->winId(), (GLXContext)d->cx); } if (!ok) qWarning("QGLContext::makeCurrent(): Failed."); if (ok) { if (!qgl_context_storage.hasLocalData() && QThread::currentThread()) qgl_context_storage.setLocalData(new QGLThreadContext); if (qgl_context_storage.hasLocalData()) qgl_context_storage.localData()->context = this; currentCtx = this; } }
bool QPaintDevice::x11DefaultVisual() const { const QX11Info *info = qt_x11Info(this); if (info) return info->defaultVisual(); return QX11Info::appDefaultVisual(); }
Qt::HANDLE QPaintDevice::x11Colormap() const { const QX11Info *info = qt_x11Info(this); if (info) return info->colormap(); return QX11Info::appColormap(); }
int QPaintDevice::x11Cells() const { const QX11Info *info = qt_x11Info(this); if (info) return info->cells(); return QX11Info::appCells(); }
int QPaintDevice::x11Depth() const { const QX11Info *info = qt_x11Info(this); if (info) return info->depth(); return QX11Info::appDepth(); }
void *QPaintDevice::x11Visual() const { const QX11Info *info = qt_x11Info(this); if (info) return info->visual(); return QX11Info::appVisual(); }
void QGLContext::doneCurrent() { Q_D(QGLContext); glXMakeCurrent(qt_x11Info(d->paintDevice)->display(), 0, 0); if (qgl_context_storage.hasLocalData()) qgl_context_storage.localData()->context = 0; currentCtx = 0; }
// Set pixel format and other properties based on a paint device. void QEglProperties::setPaintDeviceFormat(QPaintDevice *dev) { if (!dev) return; if (dev->devType() == QInternal::Image) setPixelFormat(static_cast<QImage *>(dev)->format()); else setVisualFormat(qt_x11Info(dev)); }
void VSyncThread::swapGl(QGLWidget* glw, int index) { Q_UNUSED(index); // No need for glw->makeCurrent() here. //qDebug() << "swapGl" << m_timer.elapsed(); #if defined(__APPLE__) glw->swapBuffers(); #elif defined(__WINDOWS__) glw->swapBuffers(); #else const QX11Info *xinfo = qt_x11Info(glw); glXSwapBuffers(xinfo->display(), glw->winId()); #endif }
void QGLContext::swapBuffers() const { Q_D(const QGLContext); if (!d->valid) return; if (!deviceIsPixmap()) { int interval = d->glFormat.swapInterval(); if (interval > 0) { typedef int (*qt_glXGetVideoSyncSGI)(uint *); typedef int (*qt_glXWaitVideoSyncSGI)(int, int, uint *); static qt_glXGetVideoSyncSGI glXGetVideoSyncSGI = 0; static qt_glXWaitVideoSyncSGI glXWaitVideoSyncSGI = 0; static bool resolved = false; if (!resolved) { QString glxExt = QString(QLatin1String(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS))); if (glxExt.contains(QLatin1String("GLX_SGI_video_sync"))) { #if defined(Q_OS_LINUX) || defined(Q_OS_BSD4) void *handle = dlopen(NULL, RTLD_LAZY); if (handle) { glXGetVideoSyncSGI = (qt_glXGetVideoSyncSGI) dlsym(handle, "glXGetVideoSyncSGI"); glXWaitVideoSyncSGI = (qt_glXWaitVideoSyncSGI) dlsym(handle, "glXWaitVideoSyncSGI"); dlclose(handle); } if (!glXGetVideoSyncSGI) #endif { extern const QString qt_gl_library_name(); QLibrary lib(qt_gl_library_name()); glXGetVideoSyncSGI = (qt_glXGetVideoSyncSGI) lib.resolve("glXGetVideoSyncSGI"); glXWaitVideoSyncSGI = (qt_glXWaitVideoSyncSGI) lib.resolve("glXWaitVideoSyncSGI"); } } resolved = true; } if (glXGetVideoSyncSGI && glXWaitVideoSyncSGI) { uint counter; if (!glXGetVideoSyncSGI(&counter)) glXWaitVideoSyncSGI(interval + 1, (counter + interval) % (interval + 1), &counter); } } glXSwapBuffers(qt_x11Info(d->paintDevice)->display(), static_cast<QWidget *>(d->paintDevice)->winId()); } }
void QGLContext::reset() { Q_D(QGLContext); if (!d->valid) return; d->cleanup(); const QX11Info *xinfo = qt_x11Info(d->paintDevice); doneCurrent(); if (d->gpm) glXDestroyGLXPixmap(xinfo->display(), (GLXPixmap)d->gpm); d->gpm = 0; glXDestroyContext(xinfo->display(), (GLXContext)d->cx); if (d->vi) XFree(d->vi); d->vi = 0; d->cx = 0; d->crWin = false; d->sharing = false; d->valid = false; d->transpColor = QColor(); d->initDone = false; qgl_share_reg()->removeShare(this); }
void ShivaVGWindowSurfacePrivate::ensureContext(QWidget *widget) { #if defined(Q_WS_X11) Window win = widget->winId(); if (win != drawable) { if (context) glXDestroyContext(X11->display, context); drawable = win; } if (context == 0) { const QX11Info *xinfo = qt_x11Info(widget); int spec[64]; int i = 0; spec[i++] = GLX_DOUBLEBUFFER; spec[i++] = GLX_DEPTH_SIZE; spec[i++] = 1; spec[i++] = GLX_STENCIL_SIZE; spec[i++] = 1; spec[i++] = GLX_RGBA; spec[i++] = GLX_RED_SIZE; spec[i++] = 1; spec[i++] = GLX_GREEN_SIZE; spec[i++] = 1; spec[i++] = GLX_BLUE_SIZE; spec[i++] = 1; spec[i++] = GLX_SAMPLE_BUFFERS_ARB; spec[i++] = 1; spec[i++] = GLX_SAMPLES_ARB; spec[i++] = 4; spec[i] = XNone; XVisualInfo *visual = glXChooseVisual (xinfo->display(), xinfo->screen(), spec); context = glXCreateContext(X11->display, visual, 0, True); if (!context) qWarning("glXCreateContext: could not create GL context for VG rendering"); } #else Q_UNUSED(widget); #endif #if defined(QVG_USE_FBO) if (needsResize && fbo) { #if defined(Q_WS_X11) glXMakeCurrent(X11->display, drawable, context); #endif glDeleteTextures(1, &texture); glDeleteFramebuffersEXT(1, &fbo); #if defined(Q_WS_X11) glXMakeCurrent(X11->display, 0, 0); #endif fbo = 0; texture = 0; } if (!fbo) { #if defined(Q_WS_X11) glXMakeCurrent(X11->display, drawable, context); #endif glGenFramebuffersEXT(1, &fbo); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo); glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, size.width(), size.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, texture, 0); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); #if defined(Q_WS_X11) glXMakeCurrent(X11->display, 0, 0); #endif } #endif needsResize = false; }
/* See qgl.cpp for qdoc comment. */ void *QGLContext::tryVisual(const QGLFormat& f, int bufDepth) { Q_D(QGLContext); int spec[40]; int i = 0; spec[i++] = GLX_LEVEL; spec[i++] = f.plane(); const QX11Info *xinfo = qt_x11Info(d->paintDevice); #if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_info) static bool useTranspExt = false; static bool useTranspExtChecked = false; if (f.plane() && !useTranspExtChecked && d->paintDevice) { QByteArray estr(glXQueryExtensionsString(xinfo->display(), xinfo->screen())); useTranspExt = estr.contains("GLX_EXT_visual_info"); //# (A bit simplistic; that could theoretically be a substring) if (useTranspExt) { QByteArray cstr(glXGetClientString(xinfo->display(), GLX_VENDOR)); useTranspExt = !cstr.contains("Xi Graphics"); // bug workaround if (useTranspExt) { // bug workaround - some systems (eg. FireGL) refuses to return an overlay // visual if the GLX_TRANSPARENT_TYPE_EXT attribute is specified, even if // the implementation supports transparent overlays int tmpSpec[] = { GLX_LEVEL, f.plane(), GLX_TRANSPARENT_TYPE_EXT, f.rgba() ? GLX_TRANSPARENT_RGB_EXT : GLX_TRANSPARENT_INDEX_EXT, XNone }; XVisualInfo * vinf = glXChooseVisual(xinfo->display(), xinfo->screen(), tmpSpec); if (!vinf) { useTranspExt = false; } } } useTranspExtChecked = true; } if (f.plane() && useTranspExt) { // Required to avoid non-transparent overlay visual(!) on some systems spec[i++] = GLX_TRANSPARENT_TYPE_EXT; spec[i++] = f.rgba() ? GLX_TRANSPARENT_RGB_EXT : GLX_TRANSPARENT_INDEX_EXT; } #endif if (f.doubleBuffer()) spec[i++] = GLX_DOUBLEBUFFER; if (f.depth()) { spec[i++] = GLX_DEPTH_SIZE; spec[i++] = f.depthBufferSize() == -1 ? 1 : f.depthBufferSize(); } if (f.stereo()) { spec[i++] = GLX_STEREO; } if (f.stencil()) { spec[i++] = GLX_STENCIL_SIZE; spec[i++] = f.stencilBufferSize() == -1 ? 1 : f.stencilBufferSize(); } if (f.rgba()) { spec[i++] = GLX_RGBA; spec[i++] = GLX_RED_SIZE; spec[i++] = f.redBufferSize() == -1 ? 1 : f.redBufferSize(); spec[i++] = GLX_GREEN_SIZE; spec[i++] = f.greenBufferSize() == -1 ? 1 : f.greenBufferSize(); spec[i++] = GLX_BLUE_SIZE; spec[i++] = f.blueBufferSize() == -1 ? 1 : f.blueBufferSize(); if (f.alpha()) { spec[i++] = GLX_ALPHA_SIZE; spec[i++] = f.alphaBufferSize() == -1 ? 1 : f.alphaBufferSize(); } if (f.accum()) { spec[i++] = GLX_ACCUM_RED_SIZE; spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize(); spec[i++] = GLX_ACCUM_GREEN_SIZE; spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize(); spec[i++] = GLX_ACCUM_BLUE_SIZE; spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize(); if (f.alpha()) { spec[i++] = GLX_ACCUM_ALPHA_SIZE; spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize(); } } } else { spec[i++] = GLX_BUFFER_SIZE; spec[i++] = bufDepth; } if (f.sampleBuffers()) { spec[i++] = GLX_SAMPLE_BUFFERS_ARB; spec[i++] = 1; spec[i++] = GLX_SAMPLES_ARB; spec[i++] = f.samples() == -1 ? 4 : f.samples(); } spec[i] = XNone; return glXChooseVisual(xinfo->display(), xinfo->screen(), spec); }
bool QGLContext::chooseContext(const QGLContext* shareContext) { Q_D(QGLContext); const QX11Info *xinfo = qt_x11Info(d->paintDevice); Display* disp = xinfo->display(); d->vi = chooseVisual(); if (!d->vi) return false; if (deviceIsPixmap() && (((XVisualInfo*)d->vi)->depth != xinfo->depth() || ((XVisualInfo*)d->vi)->screen != xinfo->screen())) { XFree(d->vi); XVisualInfo appVisInfo; memset(&appVisInfo, 0, sizeof(XVisualInfo)); appVisInfo.visualid = XVisualIDFromVisual((Visual *) xinfo->visual()); appVisInfo.screen = xinfo->screen(); int nvis; d->vi = XGetVisualInfo(disp, VisualIDMask | VisualScreenMask, &appVisInfo, &nvis); if (!d->vi) return false; int useGL; glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_USE_GL, &useGL); if (!useGL) return false; //# Chickening out already... } int res; glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_LEVEL, &res); d->glFormat.setPlane(res); glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_DOUBLEBUFFER, &res); d->glFormat.setDoubleBuffer(res); glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_DEPTH_SIZE, &res); d->glFormat.setDepth(res); if (d->glFormat.depth()) d->glFormat.setDepthBufferSize(res); glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_RGBA, &res); d->glFormat.setRgba(res); glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_RED_SIZE, &res); d->glFormat.setRedBufferSize(res); glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_GREEN_SIZE, &res); d->glFormat.setGreenBufferSize(res); glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_BLUE_SIZE, &res); d->glFormat.setBlueBufferSize(res); glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_ALPHA_SIZE, &res); d->glFormat.setAlpha(res); if (d->glFormat.alpha()) d->glFormat.setAlphaBufferSize(res); glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_ACCUM_RED_SIZE, &res); d->glFormat.setAccum(res); if (d->glFormat.accum()) d->glFormat.setAccumBufferSize(res); glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_STENCIL_SIZE, &res); d->glFormat.setStencil(res); if (d->glFormat.stencil()) d->glFormat.setStencilBufferSize(res); glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_STEREO, &res); d->glFormat.setStereo(res); glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_SAMPLE_BUFFERS_ARB, &res); d->glFormat.setSampleBuffers(res); if (d->glFormat.sampleBuffers()) { glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_SAMPLES_ARB, &res); d->glFormat.setSamples(res); } Bool direct = format().directRendering() ? True : False; if (shareContext && (!shareContext->isValid() || !shareContext->d_func()->cx)) { qWarning("QGLContext::chooseContext(): Cannot share with invalid context"); shareContext = 0; } // 1. Sharing between rgba and color-index will give wrong colors. // 2. Contexts cannot be shared btw. direct/non-direct renderers. // 3. Pixmaps cannot share contexts that are set up for direct rendering. // 4. If the contexts are not created on the same screen, they can't be shared if (shareContext && (format().rgba() != shareContext->format().rgba() || (deviceIsPixmap() && glXIsDirect(disp, (GLXContext)shareContext->d_func()->cx)) || (shareContext->d_func()->screen != xinfo->screen()))) { shareContext = 0; } d->cx = 0; if (shareContext) { d->cx = glXCreateContext(disp, (XVisualInfo *)d->vi, (GLXContext)shareContext->d_func()->cx, direct); d->screen = ((XVisualInfo*)d->vi)->screen; if (d->cx) { QGLContext *share = const_cast<QGLContext *>(shareContext); d->sharing = true; share->d_func()->sharing = true; } } if (!d->cx) { d->cx = glXCreateContext(disp, (XVisualInfo *)d->vi, NULL, direct); d->screen = ((XVisualInfo*)d->vi)->screen; } if (!d->cx) return false; d->glFormat.setDirectRendering(glXIsDirect(disp, (GLXContext)d->cx)); if (deviceIsPixmap()) { #if defined(GLX_MESA_pixmap_colormap) && defined(QGL_USE_MESA_EXT) d->gpm = glXCreateGLXPixmapMESA(disp, (XVisualInfo *)d->vi, qt_x11Handle(d->paintDevice), qt_gl_choose_cmap(disp, (XVisualInfo *)d->vi)); #else d->gpm = (quint32)glXCreateGLXPixmap(disp, (XVisualInfo *)d->vi, qt_x11Handle(d->paintDevice)); #endif if (!d->gpm) return false; } QString glxExt = QString(QLatin1String(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS))); if (glxExt.contains(QLatin1String("GLX_SGI_video_sync"))) { if (d->glFormat.swapInterval() == -1) d->glFormat.setSwapInterval(0); } else { d->glFormat.setSwapInterval(-1); } return true; }