void QVGEGLWindowSurfaceDirect::beginPaint(QWidget *widget)
{
    QEglContext *context = ensureContext(widget);
    if (context) {
        context->makeCurrent(windowSurface);
        isPaintingActive = true;
    }
}
Beispiel #2
0
bool QGLPixelBuffer::hasOpenGLPbuffers()
{
    // See if we have at least 1 configuration that matches the default format.
    QEglContext ctx;
    if (!ctx.openDisplay(0))
        return false;
    QEglProperties configProps;
    qt_egl_set_format(configProps, QInternal::Pbuffer, QGLFormat::defaultFormat());
    configProps.setRenderableType(QEglContext::OpenGL);
    return ctx.chooseConfig(configProps);
}
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;
}
Beispiel #4
0
void QVGLiteWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
{
    Q_UNUSED(widget);
    Q_UNUSED(region);
    Q_UNUSED(offset);
    QEglContext *context = graphicsSystem->context;
    if (context) {
        if (!isPaintingActive)
            qt_vg_make_current(context, graphicsSystem->rootWindow);
        context->swapBuffers();
        qt_vg_done_current(context);
        context->setSurface(EGL_NO_SURFACE);
        isPaintingActive = false;
    }
}
void QVGEGLWindowSurfaceVGImage::endPaint
        (QWidget *widget, const QRegion& region, QImage *image)
{
    Q_UNUSED(region);
    Q_UNUSED(image);
    QEglContext *context = ensureContext(widget);
    if (context) {
        if (backBufferSurface != EGL_NO_SURFACE) {
            if (isPaintingActive)
                vgFlush();
            context->lazyDoneCurrent();
        }
        isPaintingActive = false;
    }
}
bool QVGEGLWindowSurfaceDirect::scroll(QWidget *widget, const QRegion& area, int dx, int dy)
{
#ifdef QVG_BUFFER_SCROLLING
    QEglContext *context = ensureContext(widget);
    if (context) {
        context->makeCurrent(windowSurface);
        QRect scrollRect = area.boundingRect();
        int sx = scrollRect.x();
        int sy = size.height() - scrollRect.y() - scrollRect.height();
        vgSeti(VG_SCISSORING, VG_FALSE);
        vgCopyPixels(sx + dx, sy - dy, sx, sy, scrollRect.width(), scrollRect.height());
        context->lazyDoneCurrent();
        return true;
    }
#endif
    return false;
}
void QVGEGLWindowSurfaceDirect::endPaint
        (QWidget *widget, const QRegion& region, QImage *image)
{
    Q_UNUSED(region);
    Q_UNUSED(image);
    QEglContext *context = ensureContext(widget);
    if (context) {
        if (needToSwap) {
            if (!isPaintingActive)
                context->makeCurrent(windowSurface);
            context->swapBuffers(windowSurface);
            context->lazyDoneCurrent();
        } else if (isPaintingActive) {
            vgFlush();
            context->lazyDoneCurrent();
        }
        isPaintingActive = false;
    }
}
void QVGEGLWindowSurfaceVGImage::beginPaint(QWidget *widget)
{
    QEglContext *context = ensureContext(widget);
    if (context) {
        if (recreateBackBuffer || backBufferSurface == EGL_NO_SURFACE) {
            // Create a VGImage object to act as the back buffer
            // for this window.  We have to create the VGImage with a
            // current context, so activate the main surface for the window.
            context->makeCurrent(mainSurface());
            recreateBackBuffer = false;
            if (backBufferSurface != EGL_NO_SURFACE) {
                eglDestroySurface(QEgl::display(), backBufferSurface);
                backBufferSurface = EGL_NO_SURFACE;
            }
            if (backBuffer != VG_INVALID_HANDLE) {
                vgDestroyImage(backBuffer);
            }
            VGImageFormat format = qt_vg_config_to_vg_format(context);
            backBuffer = vgCreateImage
                (format, size.width(), size.height(),
                 VG_IMAGE_QUALITY_FASTER);
            if (backBuffer != VG_INVALID_HANDLE) {
                // Create an EGL surface for rendering into the VGImage.
                backBufferSurface = eglCreatePbufferFromClientBuffer
                    (QEgl::display(), EGL_OPENVG_IMAGE,
                     (EGLClientBuffer)(backBuffer),
                     context->config(), NULL);
                if (backBufferSurface == EGL_NO_SURFACE) {
                    vgDestroyImage(backBuffer);
                    backBuffer = VG_INVALID_HANDLE;
                }
            }
        }
        if (backBufferSurface != EGL_NO_SURFACE)
            context->makeCurrent(backBufferSurface);
        else
            context->makeCurrent(mainSurface());
        isPaintingActive = true;
    }
}
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;
}
Beispiel #10
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;
}