コード例 #1
0
QEglContext *QVGEGLWindowSurfaceDirect::ensureContext(QWidget *widget)
{
    QSize newSize = windowSurfaceSize(widget);
    QEglProperties surfaceProps;

#if defined(QVG_RECREATE_ON_SIZE_CHANGE)
#if !defined(QVG_NO_SINGLE_CONTEXT)
    if (context && size != newSize) {
        // The surface size has changed, so we need to recreate it.
        // We can keep the same context and paint engine.
        size = newSize;
        if (isPaintingActive)
            context->doneCurrent();
        context->destroySurface(windowSurface);
#if defined(EGL_VG_ALPHA_FORMAT_PRE_BIT)
        if (isPremultipliedContext(context)) {
            surfaceProps.setValue
                (EGL_VG_ALPHA_FORMAT, EGL_VG_ALPHA_FORMAT_PRE);
        } else {
            surfaceProps.removeValue(EGL_VG_ALPHA_FORMAT);
        }
#endif
        windowSurface = context->createSurface(widget, &surfaceProps);
        isPaintingActive = false;
        needToSwap = true;
    }
#else
    if (context && size != newSize) {
        // The surface size has changed, so we need to recreate
        // the EGL context for the widget.  We also need to recreate
        // the surface's paint engine if context sharing is not
        // enabled because we cannot reuse the existing paint objects
        // in the new context.
        qt_vg_destroy_paint_engine(engine);
        engine = 0;
        context->destroySurface(windowSurface);
        qt_vg_destroy_context(context, QInternal::Widget);
        context = 0;
        windowSurface = EGL_NO_SURFACE;
    }
#endif
#endif
    if (!context) {
        // Create a new EGL context and bind it to the widget surface.
        size = newSize;
        context = qt_vg_create_context(widget, QInternal::Widget);
        if (!context)
            return 0;
        // We want a direct to window rendering surface if possible.
#if defined(QVG_DIRECT_TO_WINDOW)
        surfaceProps.setValue(EGL_RENDER_BUFFER, EGL_SINGLE_BUFFER);
#endif
#if defined(EGL_VG_ALPHA_FORMAT_PRE_BIT)
        if (isPremultipliedContext(context)) {
            surfaceProps.setValue
                (EGL_VG_ALPHA_FORMAT, EGL_VG_ALPHA_FORMAT_PRE);
        } else {
            surfaceProps.removeValue(EGL_VG_ALPHA_FORMAT);
        }
#endif
        EGLSurface surface = context->createSurface(widget, &surfaceProps);
        if (surface == EGL_NO_SURFACE) {
            qt_vg_destroy_context(context, QInternal::Widget);
            context = 0;
            return 0;
        }
        needToSwap = true;
#if defined(QVG_DIRECT_TO_WINDOW)
        // Did we get a direct to window rendering surface?
        EGLint buffer = 0;
        if (eglQueryContext(QEgl::display(), context->context(),
                            EGL_RENDER_BUFFER, &buffer) &&
                buffer == EGL_SINGLE_BUFFER) {
            needToSwap = false;
        }
#endif
        windowSurface = surface;
        isPaintingActive = false;
    }

#if !defined(QVG_NO_PRESERVED_SWAP)
    // Try to force the surface back buffer to preserve its contents.
    if (needToSwap) {
        eglGetError();  // Clear error state first.
        eglSurfaceAttrib(QEgl::display(), windowSurface,
                EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED);
        if (eglGetError() != EGL_SUCCESS) {
            qWarning("QVG: could not enable preserved swap");
        }
    }
#endif
    return context;
}
コード例 #2
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(QEglContext::OpenGL);

    // Open the EGL display.
    if (!ctx->openDisplay(0)) {
        delete ctx;
        ctx = 0;
        return false;
    }

    // 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.
    QEglProperties configProps;
    qt_egl_set_format(configProps, QInternal::Pbuffer, f);
    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, QEglContext::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, QEglContext::BestPixelFormat);
        if (!ok) {
            // One last try for a pbuffer with no texture rendering.
            configProps.removeValue(EGL_BIND_TO_TEXTURE_RGB);
            textureFormat = EGL_NONE;
        }
    }
#else
    textureFormat = EGL_NONE;
#endif
    if (!ok) {
        if (!ctx->chooseConfig(configProps, QEglContext::BestPixelFormat)) {
            delete ctx;
            ctx = 0;
            return false;
        }
    }

    // Retrieve the actual format properties.
    qt_egl_update_format(*ctx, format);

    // 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:" << QEglContext::errorString(eglGetError());
        return false;
    }
    ctx->setSurface(pbuf);

    // Create a new context for the configuration.
    QEglContext *shareContext = 0;
    if (shareWidget && shareWidget->d_func()->glcx)
        shareContext = shareWidget->d_func()->glcx->d_func()->eglContext;
    if (!ctx->createContext(shareContext)) {
        delete ctx;
        ctx = 0;
        return false;
    }

    return true;
}