Beispiel #1
0
// 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;
}
Beispiel #2
0
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;

}
Beispiel #3
0
QT_BEGIN_NAMESPACE

#ifdef EGL_BIND_TO_TEXTURE_RGBA
#define QGL_RENDER_TEXTURE 1
#else
#define QGL_RENDER_TEXTURE 0
#endif

bool QGLPixelBufferPrivate::init(const QSize &size, const QGLFormat &f, QGLWidget *shareWidget)
{
    // Create the EGL context.
    ctx = new QEglContext();
    ctx->setApi(QEgl::OpenGL);

    // Find the shared context.
    QEglContext *shareContext = 0;
    if (shareWidget && shareWidget->d_func()->glcx)
        shareContext = shareWidget->d_func()->glcx->d_func()->eglContext;

    // Choose an appropriate configuration.  We use the best format
    // we can find, even if it is greater than the requested format.
    // We try for a pbuffer that is capable of texture rendering if possible.
    textureFormat = EGL_NONE;
    if (shareContext) {
        // Use the same configuration as the widget we are sharing with.
        ctx->setConfig(shareContext->config());
#if QGL_RENDER_TEXTURE
        if (ctx->configAttrib(EGL_BIND_TO_TEXTURE_RGBA) == EGL_TRUE)
            textureFormat = EGL_TEXTURE_RGBA;
        else if (ctx->configAttrib(EGL_BIND_TO_TEXTURE_RGB) == EGL_TRUE)
            textureFormat = EGL_TEXTURE_RGB;
#endif
    } else {
        QEglProperties configProps;
        qt_eglproperties_set_glformat(configProps, f);
        configProps.setDeviceType(QInternal::Pbuffer);
        configProps.setRenderableType(ctx->api());
        bool ok = false;
#if QGL_RENDER_TEXTURE
        textureFormat = EGL_TEXTURE_RGBA;
        configProps.setValue(EGL_BIND_TO_TEXTURE_RGBA, EGL_TRUE);
        ok = ctx->chooseConfig(configProps, QEgl::BestPixelFormat);
        if (!ok) {
            // Try again with RGB texture rendering.
            textureFormat = EGL_TEXTURE_RGB;
            configProps.removeValue(EGL_BIND_TO_TEXTURE_RGBA);
            configProps.setValue(EGL_BIND_TO_TEXTURE_RGB, EGL_TRUE);
            ok = ctx->chooseConfig(configProps, QEgl::BestPixelFormat);
            if (!ok) {
                // One last try for a pbuffer with no texture rendering.
                configProps.removeValue(EGL_BIND_TO_TEXTURE_RGB);
                textureFormat = EGL_NONE;
            }
        }
#endif
        if (!ok) {
            if (!ctx->chooseConfig(configProps, QEgl::BestPixelFormat)) {
                delete ctx;
                ctx = 0;
                return false;
            }
        }
    }

    // Retrieve the actual format properties.
    qt_glformat_from_eglconfig(format, ctx->config());

    // Create the attributes needed for the pbuffer.
    QEglProperties attribs;
    attribs.setValue(EGL_WIDTH, size.width());
    attribs.setValue(EGL_HEIGHT, size.height());
#if QGL_RENDER_TEXTURE
    if (textureFormat != EGL_NONE) {
        attribs.setValue(EGL_TEXTURE_FORMAT, textureFormat);
        attribs.setValue(EGL_TEXTURE_TARGET, EGL_TEXTURE_2D);
    }
#endif

    // Create the pbuffer surface.
    pbuf = eglCreatePbufferSurface(ctx->display(), ctx->config(), attribs.properties());
#if QGL_RENDER_TEXTURE
    if (pbuf == EGL_NO_SURFACE && textureFormat != EGL_NONE) {
        // Try again with texture rendering disabled.
        textureFormat = EGL_NONE;
        attribs.removeValue(EGL_TEXTURE_FORMAT);
        attribs.removeValue(EGL_TEXTURE_TARGET);
        pbuf = eglCreatePbufferSurface(ctx->display(), ctx->config(), attribs.properties());
    }
#endif
    if (pbuf == EGL_NO_SURFACE) {
        qWarning() << "QGLPixelBufferPrivate::init(): Unable to create EGL pbuffer surface:" << QEgl::errorString();
        return false;
    }

    // Create a new context for the configuration.
    if (!ctx->createContext(shareContext)) {
        delete ctx;
        ctx = 0;
        return false;
    }

    return true;
}
Beispiel #4
0
    QX11GLSharedContexts()
        : rgbContext(0)
        , argbContext(0)
        , sharedQGLContext(0)
        , sharePixmap(0)
    {
        EGLint rgbConfigId;
        EGLint argbConfigId;

        do {
            EGLConfig rgbConfig = QEgl::defaultConfig(QInternal::Pixmap, QEgl::OpenGL, QEgl::Renderable);
            EGLConfig argbConfig = QEgl::defaultConfig(QInternal::Pixmap, QEgl::OpenGL,
                                                       QEgl::Renderable | QEgl::Translucent);

            eglGetConfigAttrib(QEgl::display(), rgbConfig, EGL_CONFIG_ID, &rgbConfigId);
            eglGetConfigAttrib(QEgl::display(), argbConfig, EGL_CONFIG_ID, &argbConfigId);

            rgbContext = new QEglContext;
            rgbContext->setConfig(rgbConfig);
            rgbContext->createContext();

            if (!rgbContext->isValid())
                break;

            // If the RGB & ARGB configs are the same, use the same egl context for both:
            if (rgbConfig == argbConfig)
                argbContext = rgbContext;

            // Otherwise, create a separate context to be used for ARGB pixmaps:
            if (!argbContext) {
                argbContext = new QEglContext;
                argbContext->setConfig(argbConfig);
                bool success = argbContext->createContext(rgbContext);
                if (!success) {
                    qWarning("QX11GLPixmapData - RGB & ARGB contexts aren't shared");
                    success = argbContext->createContext();
                    if (!success)
                        argbContext = rgbContext; // Might work, worth a shot at least.
                }
            }

            if (!argbContext->isValid())
                break;

            // Create the pixmap which will be used to create the egl surface for the share QGLContext
            QX11PixmapData *rgbPixmapData = new QX11PixmapData(QPixmapData::PixmapType);
            rgbPixmapData->resize(8, 8);
            rgbPixmapData->fill(Qt::red);
            sharePixmap = new QPixmap(rgbPixmapData);
            EGLSurface sharePixmapSurface = QEgl::createSurface(sharePixmap, rgbConfig);
            rgbPixmapData->gl_surface = (void*)sharePixmapSurface;

            // Create the actual QGLContext which will be used for sharing
            sharedQGLContext = new QGLContext(QX11GLPixmapData::glFormat());
            sharedQGLContext->d_func()->eglContext = rgbContext;
            sharedQGLContext->d_func()->eglSurface = sharePixmapSurface;
            sharedQGLContext->d_func()->valid = true;
            qt_glformat_from_eglconfig(sharedQGLContext->d_func()->glFormat, rgbConfig);


            valid = rgbContext->makeCurrent(sharePixmapSurface);

            // If the ARGB & RGB configs are different, check ARGB works too:
            if (argbConfig != rgbConfig) {
                QX11PixmapData *argbPixmapData = new QX11PixmapData(QPixmapData::PixmapType);
                argbPixmapData->resize(8, 8);
                argbPixmapData->fill(Qt::transparent); // Force ARGB
                QPixmap argbPixmap(argbPixmapData); // destroys pixmap data when goes out of scope
                EGLSurface argbPixmapSurface = QEgl::createSurface(&argbPixmap, argbConfig);
                valid = argbContext->makeCurrent(argbPixmapSurface);
                argbContext->doneCurrent();
                eglDestroySurface(QEgl::display(), argbPixmapSurface);
                argbPixmapData->gl_surface = 0;
            }

            if (!valid) {
                qWarning() << "Unable to make pixmap surface current:" << QEgl::errorString();
                break;
            }

            // The pixmap surface destruction hooks are installed by QGLTextureCache, so we
            // must make sure this is instanciated:
            QGLTextureCache::instance();
        } while(0);

        if (!valid)
            cleanup();
        else
            qDebug("Using QX11GLPixmapData with EGL config %d for ARGB and config %d for RGB", argbConfigId, rgbConfigId);

    }
Beispiel #5
0
// 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;
}