diff options
Diffstat (limited to 'src/plugins/platforms/xcb/qglxintegration.cpp')
-rw-r--r-- | src/plugins/platforms/xcb/qglxintegration.cpp | 238 |
1 files changed, 16 insertions, 222 deletions
diff --git a/src/plugins/platforms/xcb/qglxintegration.cpp b/src/plugins/platforms/xcb/qglxintegration.cpp index e94b6a6..190221c 100644 --- a/src/plugins/platforms/xcb/qglxintegration.cpp +++ b/src/plugins/platforms/xcb/qglxintegration.cpp @@ -51,218 +51,29 @@ #include <GL/glx.h> #include "qglxintegration.h" +#include "qglxconvenience.h" #if defined(Q_OS_LINUX) || defined(Q_OS_BSD4) #include <dlfcn.h> #endif -QMutex QGLXContext::m_defaultSharedContextMutex(QMutex::Recursive); - -QVector<int> QGLXContext::buildSpec(const QPlatformWindowFormat &format) -{ - QVector<int> spec(48); - int i = 0; - - spec[i++] = GLX_LEVEL; - spec[i++] = 0; - spec[i++] = GLX_DRAWABLE_TYPE; spec[i++] = GLX_WINDOW_BIT; - - if (format.rgba()) { - spec[i++] = GLX_RENDER_TYPE; spec[i++] = GLX_RGBA_BIT; - spec[i++] = GLX_RED_SIZE; spec[i++] = (format.redBufferSize() == -1) ? 1 : format.redBufferSize(); - spec[i++] = GLX_GREEN_SIZE; spec[i++] = (format.greenBufferSize() == -1) ? 1 : format.greenBufferSize(); - spec[i++] = GLX_BLUE_SIZE; spec[i++] = (format.blueBufferSize() == -1) ? 1 : format.blueBufferSize(); - if (format.alpha()) { - spec[i++] = GLX_ALPHA_SIZE; spec[i++] = (format.alphaBufferSize() == -1) ? 1 : format.alphaBufferSize(); - } - - spec[i++] = GLX_ACCUM_RED_SIZE; spec[i++] = (format.accumBufferSize() == -1) ? 1 : format.accumBufferSize(); - spec[i++] = GLX_ACCUM_GREEN_SIZE; spec[i++] = (format.accumBufferSize() == -1) ? 1 : format.accumBufferSize(); - spec[i++] = GLX_ACCUM_BLUE_SIZE; spec[i++] = (format.accumBufferSize() == -1) ? 1 : format.accumBufferSize(); - - if (format.alpha()) { - spec[i++] = GLX_ACCUM_ALPHA_SIZE; spec[i++] = (format.accumBufferSize() == -1) ? 1 : format.accumBufferSize(); - } - - } else { - spec[i++] = GLX_RENDER_TYPE; spec[i++] = GLX_COLOR_INDEX_BIT; //I'm really not sure if this works.... - spec[i++] = GLX_BUFFER_SIZE; spec[i++] = 8; - } - - spec[i++] = GLX_DOUBLEBUFFER; spec[i++] = format.doubleBuffer() ? True : False; - spec[i++] = GLX_STEREO; spec[i++] = format.stereo() ? True : False; - - if (format.depth()) { - spec[i++] = GLX_DEPTH_SIZE; spec[i++] = (format.depthBufferSize() == -1) ? 1 : format.depthBufferSize(); - } - - if (format.stencil()) { - spec[i++] = GLX_STENCIL_SIZE; spec[i++] = (format.stencilBufferSize() == -1) ? 1 : format.stencilBufferSize(); - } - if (format.sampleBuffers()) { - spec[i++] = GLX_SAMPLE_BUFFERS_ARB; - spec[i++] = 1; - spec[i++] = GLX_SAMPLES_ARB; - spec[i++] = format.samples() == -1 ? 4 : format.samples(); - } - - spec[i++] = None; - return spec; -} - -GLXFBConfig QGLXContext::findConfig(const QXcbScreen *screen, const QPlatformWindowFormat &format) -{ - bool reduced = true; - GLXFBConfig chosenConfig = 0; - QPlatformWindowFormat reducedFormat = format; - while (!chosenConfig && reduced) { - QVector<int> spec = buildSpec(reducedFormat); - int confcount = 0; - GLXFBConfig *configs; - configs = glXChooseFBConfig(DISPLAY_FROM_XCB(screen), screen->screenNumber(), spec.constData(), &confcount); - if (confcount) - { - for (int i = 0; i < confcount; i++) { - chosenConfig = configs[i]; - // Make sure we try to get an ARGB visual if the format asked for an alpha: - if (reducedFormat.alpha()) { - int alphaSize; - glXGetFBConfigAttrib(DISPLAY_FROM_XCB(screen), configs[i], GLX_ALPHA_SIZE, &alphaSize); - if (alphaSize > 0) - break; - } else { - break; // Just choose the first in the list if there's no alpha requested - } - } - - XFree(configs); - } - reducedFormat = reducePlatformWindowFormat(reducedFormat,&reduced); - } - - if (!chosenConfig) - qWarning("Warning no context created"); - - return chosenConfig; -} - -XVisualInfo *QGLXContext::findVisualInfo(const QXcbScreen *screen, const QPlatformWindowFormat &format) -{ - GLXFBConfig config = QGLXContext::findConfig(screen,format); - XVisualInfo *visualInfo = glXGetVisualFromFBConfig(DISPLAY_FROM_XCB(screen), config); - return visualInfo; -} - -QPlatformWindowFormat QGLXContext::platformWindowFromGLXFBConfig(Display *display, GLXFBConfig config, GLXContext ctx) -{ - QPlatformWindowFormat format; - int redSize = 0; - int greenSize = 0; - int blueSize = 0; - int alphaSize = 0; - int depthSize = 0; - int stencilSize = 0; - int sampleBuffers = 0; - int sampleCount = 0; - int level = 0; - int rgba = 0; - int stereo = 0; - int accumSizeA = 0; - int accumSizeR = 0; - int accumSizeG = 0; - int accumSizeB = 0; - - XVisualInfo *vi = glXGetVisualFromFBConfig(display,config); - glXGetConfig(display,vi,GLX_RGBA,&rgba); - XFree(vi); - glXGetFBConfigAttrib(display, config, GLX_RED_SIZE, &redSize); - glXGetFBConfigAttrib(display, config, GLX_GREEN_SIZE, &greenSize); - glXGetFBConfigAttrib(display, config, GLX_BLUE_SIZE, &blueSize); - glXGetFBConfigAttrib(display, config, GLX_ALPHA_SIZE, &alphaSize); - glXGetFBConfigAttrib(display, config, GLX_DEPTH_SIZE, &depthSize); - glXGetFBConfigAttrib(display, config, GLX_STENCIL_SIZE, &stencilSize); - glXGetFBConfigAttrib(display, config, GLX_SAMPLES, &sampleBuffers); - glXGetFBConfigAttrib(display, config, GLX_LEVEL, &level); - glXGetFBConfigAttrib(display, config, GLX_STEREO, &stereo); - glXGetFBConfigAttrib(display, config, GLX_ACCUM_ALPHA_SIZE, &accumSizeA); - glXGetFBConfigAttrib(display, config, GLX_ACCUM_RED_SIZE, &accumSizeR); - glXGetFBConfigAttrib(display, config, GLX_ACCUM_GREEN_SIZE, &accumSizeG); - glXGetFBConfigAttrib(display, config, GLX_ACCUM_BLUE_SIZE, &accumSizeB); - - format.setRedBufferSize(redSize); - format.setGreenBufferSize(greenSize); - format.setBlueBufferSize(blueSize); - format.setAlphaBufferSize(alphaSize); - format.setDepthBufferSize(depthSize); - format.setStencilBufferSize(stencilSize); - format.setSampleBuffers(sampleBuffers); - if (format.sampleBuffers()) { - glXGetFBConfigAttrib(display, config, GLX_SAMPLES_ARB, &sampleCount); - format.setSamples(sampleCount); - } - - format.setDirectRendering(glXIsDirect(display, ctx)); - format.setRgba(rgba); - format.setStereo(stereo); - format.setAccumBufferSize(accumSizeB); - - return format; -} - -QPlatformWindowFormat QGLXContext::reducePlatformWindowFormat(const QPlatformWindowFormat &format, bool *reduced) -{ - QPlatformWindowFormat retFormat = format; - *reduced = true; - - if (retFormat.sampleBuffers()) { - retFormat.setSampleBuffers(false); - } else if (retFormat.stereo()) { - retFormat.setStereo(false); - } else if (retFormat.accum()) { - retFormat.setAccum(false); - }else if (retFormat.stencil()) { - retFormat.setStencil(false); - }else if (retFormat.alpha()) { - retFormat.setAlpha(false); - }else if (retFormat.depth()) { - retFormat.setDepth(false); - }else if (retFormat.doubleBuffer()) { - retFormat.setDoubleBuffer(false); - }else{ - *reduced = false; - } - return retFormat; -} - QGLXContext::QGLXContext(Window window, QXcbScreen *screen, const QPlatformWindowFormat &format) : QPlatformGLContext() , m_screen(screen) , m_drawable((Drawable)window) , m_context(0) { - + Q_XCB_NOOP(m_screen->connection()); const QPlatformGLContext *sharePlatformContext; - if (format.useDefaultSharedContext()) { - if (!QPlatformGLContext::defaultSharedContext()) { - if (m_defaultSharedContextMutex.tryLock()){ - createDefaultSharedContex(screen); - m_defaultSharedContextMutex.unlock(); - } else { - m_defaultSharedContextMutex.lock(); //wait to the the shared context is created - m_defaultSharedContextMutex.unlock(); - } - } - sharePlatformContext = QPlatformGLContext::defaultSharedContext(); - } else { - sharePlatformContext = format.sharedGLContext(); - } + sharePlatformContext = format.sharedGLContext(); GLXContext shareGlxContext = 0; if (sharePlatformContext) shareGlxContext = static_cast<const QGLXContext*>(sharePlatformContext)->glxContext(); - GLXFBConfig config = findConfig(screen,format); + GLXFBConfig config = qglx_findConfig(DISPLAY_FROM_XCB(screen),screen->screenNumber(),format); m_context = glXCreateNewContext(DISPLAY_FROM_XCB(screen), config, GLX_RGBA_TYPE, shareGlxContext, TRUE); - m_windowFormat = QGLXContext::platformWindowFromGLXFBConfig(DISPLAY_FROM_XCB(screen), config, m_context); + m_windowFormat = qglx_platformWindowFromGLXFBConfig(DISPLAY_FROM_XCB(screen), config, m_context); + Q_XCB_NOOP(m_screen->connection()); } QGLXContext::QGLXContext(QXcbScreen *screen, Drawable drawable, GLXContext context) @@ -273,56 +84,39 @@ QGLXContext::QGLXContext(QXcbScreen *screen, Drawable drawable, GLXContext conte QGLXContext::~QGLXContext() { + Q_XCB_NOOP(m_screen->connection()); if (m_context) glXDestroyContext(DISPLAY_FROM_XCB(m_screen), m_context); -} - -void QGLXContext::createDefaultSharedContex(QXcbScreen *screen) -{ - int x = 0; - int y = 0; - int w = 3; - int h = 3; - - QPlatformWindowFormat format = QPlatformWindowFormat::defaultFormat(); - GLXContext context; - GLXFBConfig config = findConfig(screen,format); - if (config) { - XVisualInfo *visualInfo = glXGetVisualFromFBConfig(DISPLAY_FROM_XCB(screen), config); - Colormap cmap = XCreateColormap(DISPLAY_FROM_XCB(screen), screen->root(), visualInfo->visual, AllocNone); - XSetWindowAttributes a; - a.colormap = cmap; - Window sharedWindow = XCreateWindow(DISPLAY_FROM_XCB(screen), screen->root(), x, y, w, h, - 0, visualInfo->depth, InputOutput, visualInfo->visual, - CWColormap, &a); - - context = glXCreateNewContext(DISPLAY_FROM_XCB(screen), config, GLX_RGBA_TYPE, 0, TRUE); - QPlatformGLContext *sharedContext = new QGLXContext(screen, sharedWindow, context); - QPlatformGLContext::setDefaultSharedContext(sharedContext); - } else { - qWarning("Warning no shared context created"); - } + Q_XCB_NOOP(m_screen->connection()); } void QGLXContext::makeCurrent() { + Q_XCB_NOOP(m_screen->connection()); QPlatformGLContext::makeCurrent(); glXMakeCurrent(DISPLAY_FROM_XCB(m_screen), m_drawable, m_context); + Q_XCB_NOOP(m_screen->connection()); } void QGLXContext::doneCurrent() { + Q_XCB_NOOP(m_screen->connection()); QPlatformGLContext::doneCurrent(); glXMakeCurrent(DISPLAY_FROM_XCB(m_screen), 0, 0); + Q_XCB_NOOP(m_screen->connection()); } void QGLXContext::swapBuffers() { + Q_XCB_NOOP(m_screen->connection()); glXSwapBuffers(DISPLAY_FROM_XCB(m_screen), m_drawable); + doneCurrent(); + Q_XCB_NOOP(m_screen->connection()); } void* QGLXContext::getProcAddress(const QString& procName) { + Q_XCB_NOOP(m_screen->connection()); typedef void *(*qt_glXGetProcAddressARB)(const GLubyte *); static qt_glXGetProcAddressARB glXGetProcAddressARB = 0; static bool resolved = false; |