static QEglContext *createContext(QPaintDevice *device) { QEglContext *context; // Create the context object and open the display. context = new QEglContext(); context->setApi(QEgl::OpenVG); if (!context->openDisplay(device)) { delete context; return 0; } // Set the swap interval for the display. QByteArray interval = qgetenv("QT_VG_SWAP_INTERVAL"); if (!interval.isEmpty()) eglSwapInterval(context->display(), interval.toInt()); else eglSwapInterval(context->display(), 1); // Choose an appropriate configuration for rendering into the device. QEglProperties configProps; configProps.setPaintDeviceFormat(device); int redSize = configProps.value(EGL_RED_SIZE); if (redSize == EGL_DONT_CARE || redSize == 0) configProps.setPixelFormat(QImage::Format_ARGB32); // XXX #ifndef QVG_SCISSOR_CLIP // If we are using the mask to clip, then explicitly request a mask. configProps.setValue(EGL_ALPHA_MASK_SIZE, 1); #endif #ifdef EGL_VG_ALPHA_FORMAT_PRE_BIT configProps.setValue(EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT | EGL_VG_ALPHA_FORMAT_PRE_BIT); configProps.setRenderableType(QEgl::OpenVG); if (!context->chooseConfig(configProps)) { // Try again without the "pre" bit. configProps.setValue(EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT); if (!context->chooseConfig(configProps)) { delete context; return 0; } } #else configProps.setValue(EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT); configProps.setRenderableType(QEgl::OpenVG); if (!context->chooseConfig(configProps)) { delete context; return 0; } #endif // Construct a new EGL context for the selected configuration. if (!context->createContext()) { delete context; return 0; } return context; }
static QEglContext *createContext(QPaintDevice *device) { QEglContext *context; // Create the context object and open the display. context = new QEglContext(); context->setApi(QEgl::OpenVG); // Set the swap interval for the display. QByteArray interval = qgetenv("QT_VG_SWAP_INTERVAL"); if (!interval.isEmpty()) eglSwapInterval(QEgl::display(), interval.toInt()); else eglSwapInterval(QEgl::display(), 1); #ifdef EGL_RENDERABLE_TYPE // Has the user specified an explicit EGL configuration to use? QByteArray configId = qgetenv("QT_VG_EGL_CONFIG"); if (!configId.isEmpty()) { EGLint cfgId = configId.toInt(); EGLint properties[] = { EGL_CONFIG_ID, cfgId, EGL_NONE }; EGLint matching = 0; EGLConfig cfg; if (eglChooseConfig (QEgl::display(), properties, &cfg, 1, &matching) && matching > 0) { // Check that the selected configuration actually supports OpenVG // and then create the context with it. EGLint id = 0; EGLint type = 0; eglGetConfigAttrib (QEgl::display(), cfg, EGL_CONFIG_ID, &id); eglGetConfigAttrib (QEgl::display(), cfg, EGL_RENDERABLE_TYPE, &type); if (cfgId == id && (type & EGL_OPENVG_BIT) != 0) { context->setConfig(cfg); if (!context->createContext()) { delete context; return 0; } return context; } else { qWarning("QT_VG_EGL_CONFIG: %d is not a valid OpenVG configuration", int(cfgId)); } } } #endif // Choose an appropriate configuration for rendering into the device. QEglProperties configProps; configProps.setPaintDeviceFormat(device); int redSize = configProps.value(EGL_RED_SIZE); if (redSize == EGL_DONT_CARE || redSize == 0) configProps.setPixelFormat(QImage::Format_ARGB32); // XXX #ifndef QVG_SCISSOR_CLIP // If we are using the mask to clip, then explicitly request a mask. configProps.setValue(EGL_ALPHA_MASK_SIZE, 1); #endif #ifdef EGL_VG_ALPHA_FORMAT_PRE_BIT configProps.setValue(EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_VG_ALPHA_FORMAT_PRE_BIT); configProps.setRenderableType(QEgl::OpenVG); if (!context->chooseConfig(configProps)) { // Try again without the "pre" bit. configProps.setValue(EGL_SURFACE_TYPE, EGL_WINDOW_BIT); if (!context->chooseConfig(configProps)) { delete context; return 0; } } #else configProps.setValue(EGL_SURFACE_TYPE, EGL_WINDOW_BIT); configProps.setRenderableType(QEgl::OpenVG); if (!context->chooseConfig(configProps)) { delete context; return 0; } #endif // Construct a new EGL context for the selected configuration. if (!context->createContext()) { delete context; return 0; } return context; }
// Chooses the EGL config and creates the EGL context bool QGLContext::chooseContext(const QGLContext* shareContext) // almost same as in qgl_x11egl.cpp { Q_D(QGLContext); if (!device()) return false; int devType = device()->devType(); if ((devType != QInternal::Widget) && (devType != QInternal::Pbuffer)) { qWarning("WARNING: Creating a QGLContext not supported on device type %d", devType); return false; } // Get the display and initialize it. if (d->eglContext == 0) { d->eglContext = new QEglContext(); d->ownsEglContext = true; d->eglContext->setApi(QEgl::OpenGL); if (d->glFormat.samples() == EGL_DONT_CARE) { // Allow apps to override ability to use multisampling by setting an environment variable. Eg: // qputenv("QT_SYMBIAN_DISABLE_GL_MULTISAMPLE", "1"); // Added to allow camera app to start with limited memory. if (!QSymbianGraphicsSystemEx::hasBCM2727() && !qgetenv("QT_SYMBIAN_DISABLE_GL_MULTISAMPLE").toInt()) { // Most likely we have hw support for multisampling // so let's enable it. d->glFormat.setSampleBuffers(1); d->glFormat.setSamples(4); } else { d->glFormat.setSampleBuffers(0); d->glFormat.setSamples(0); } } // 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.setPaintDeviceFormat(device()); configProps.setRenderableType(QEgl::OpenGL); configProps.setValue(EGL_SURFACE_TYPE, EGL_WINDOW_BIT|EGL_SWAP_BEHAVIOR_PRESERVED_BIT); qt_eglproperties_set_glformat(configProps, d->glFormat); 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 // 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); d->eglSurface = QEgl::createSurface(device(), d->eglContext->config()); eglGetError(); // Clear error state first. #ifdef QGL_NO_PRESERVED_SWAP eglSurfaceAttrib(QEgl::display(), d->eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED); if (eglGetError() != EGL_SUCCESS) qWarning("QGLContext: could not enable destroyed swap behaviour"); #else eglSurfaceAttrib(QEgl::display(), d->eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED); if (eglGetError() != EGL_SUCCESS) qWarning("QGLContext: could not enable preserved swap behaviour"); #endif setWindowCreated(true); } return true; }
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; }