bool QGLContext::chooseContext(const QGLContext* shareContext) { Q_D(QGLContext); // Validate the device. if (!device()) return false; int devType = device()->devType(); if (devType != QInternal::Pixmap && devType != QInternal::Image && devType != QInternal::Widget) { qWarning("QGLContext::chooseContext(): Cannot create QGLContext's for paint device type %d", devType); return false; } // Get the display and initialize it. d->eglContext = new QEglContext(); d->ownsEglContext = true; d->eglContext->setApi(QEgl::OpenGL); // Construct the configuration we need for this surface. QEglProperties configProps; qt_eglproperties_set_glformat(configProps, d->glFormat); configProps.setDeviceType(devType); configProps.setPaintDeviceFormat(device()); configProps.setRenderableType(QEgl::OpenGL); // Search for a matching configuration, reducing the complexity // each time until we get something that matches. if (!d->eglContext->chooseConfig(configProps)) { delete d->eglContext; d->eglContext = 0; return false; } // Inform the higher layers about the actual format properties. qt_glformat_from_eglconfig(d->glFormat, d->eglContext->config()); // Create a new context for the configuration. if (!d->eglContext->createContext (shareContext ? shareContext->d_func()->eglContext : 0)) { delete d->eglContext; d->eglContext = 0; return false; } d->sharing = d->eglContext->isSharing(); if (d->sharing && shareContext) const_cast<QGLContext *>(shareContext)->d_func()->sharing = true; #if defined(EGL_VERSION_1_1) if (d->glFormat.swapInterval() != -1 && devType == QInternal::Widget) eglSwapInterval(d->eglContext->display(), d->glFormat.swapInterval()); #endif // Create the EGL surface to draw into. d->eglSurface = d->eglContext->createSurface(device()); if (d->eglSurface == EGL_NO_SURFACE) { delete d->eglContext; d->eglContext = 0; return false; } return true; }
// Chooses the EGL config and creates the EGL context bool QGLContext::chooseContext(const QGLContext* shareContext) { Q_D(QGLContext); if (!device()) return false; int devType = device()->devType(); QX11PixmapData *x11PixmapData = 0; if (devType == QInternal::Pixmap) { QPixmapData *pmd = static_cast<QPixmap*>(device())->data_ptr().data(); if (pmd->classId() == QPixmapData::X11Class) x11PixmapData = static_cast<QX11PixmapData*>(pmd); else { // TODO: Replace the pixmap's data with a new QX11PixmapData qWarning("WARNING: Creating a QGLContext on a QPixmap is only supported for X11 pixmap backend"); return false; } } else if ((devType != QInternal::Widget) && (devType != QInternal::Pbuffer)) { qWarning("WARNING: Creating a QGLContext not supported on device type %d", devType); return false; } // Only create the eglContext if we don't already have one: if (d->eglContext == 0) { d->eglContext = new QEglContext(); d->ownsEglContext = true; d->eglContext->setApi(QEgl::OpenGL); // If the device is a widget with WA_TranslucentBackground set, make sure the glFormat // has the alpha channel option set: if (devType == QInternal::Widget) { QWidget* widget = static_cast<QWidget*>(device()); if (widget->testAttribute(Qt::WA_TranslucentBackground)) d->glFormat.setAlpha(true); } // Construct the configuration we need for this surface. QEglProperties configProps; configProps.setDeviceType(devType); configProps.setRenderableType(QEgl::OpenGL); qt_eglproperties_set_glformat(configProps, d->glFormat); // Set buffer preserved for regular QWidgets, QGLWidgets are ok with either preserved or destroyed: if ((devType == QInternal::Widget) && qobject_cast<QGLWidget*>(static_cast<QWidget*>(device())) == 0) configProps.setValue(EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED); if (!d->eglContext->chooseConfig(configProps, QEgl::BestPixelFormat)) { delete d->eglContext; d->eglContext = 0; return false; } // Create a new context for the configuration. QEglContext* eglSharedContext = shareContext ? shareContext->d_func()->eglContext : 0; if (!d->eglContext->createContext(eglSharedContext)) { delete d->eglContext; d->eglContext = 0; return false; } d->sharing = d->eglContext->isSharing(); if (d->sharing && shareContext) const_cast<QGLContext *>(shareContext)->d_func()->sharing = true; } // Inform the higher layers about the actual format properties qt_glformat_from_eglconfig(d->glFormat, d->eglContext->config()); // Do don't create the EGLSurface for everything. // QWidget - yes, create the EGLSurface and store it in QGLContextPrivate::eglSurface // QGLWidget - yes, create the EGLSurface and store it in QGLContextPrivate::eglSurface // QPixmap - yes, create the EGLSurface but store it in QX11PixmapData::gl_surface // QGLPixelBuffer - no, it creates the surface itself and stores it in QGLPixelBufferPrivate::pbuf if (devType == QInternal::Widget) { if (d->eglSurface != EGL_NO_SURFACE) eglDestroySurface(d->eglContext->display(), d->eglSurface); // extraWindowSurfaceCreationProps default to NULL unless were specifically set before d->eglSurface = QEgl::createSurface(device(), d->eglContext->config(), d->extraWindowSurfaceCreationProps); XFlush(X11->display); setWindowCreated(true); } if (x11PixmapData) { // TODO: Actually check to see if the existing surface can be re-used if (x11PixmapData->gl_surface) eglDestroySurface(d->eglContext->display(), (EGLSurface)x11PixmapData->gl_surface); x11PixmapData->gl_surface = (void*)QEgl::createSurface(device(), d->eglContext->config()); } return true; }