示例#1
0
void QXcbShmImage::put(xcb_window_t window, const QPoint &target, const QRect &source)
{
    Q_XCB_NOOP(connection());
    if (m_gc_window != window) {
        if (m_gc)
            Q_XCB_CALL(xcb_free_gc(xcb_connection(), m_gc));

        m_gc = xcb_generate_id(xcb_connection());
        Q_XCB_CALL(xcb_create_gc(xcb_connection(), m_gc, window, 0, 0));

        m_gc_window = window;
    }

    Q_XCB_NOOP(connection());
    xcb_image_shm_put(xcb_connection(),
                      window,
                      m_gc,
                      m_xcb_image,
                      m_shm_info,
                      source.x(),
                      source.y(),
                      target.x(),
                      target.y(),
                      source.width(),
                      source.height(),
                      false);
    Q_XCB_NOOP(connection());

    m_dirty = m_dirty | source;

    xcb_flush(xcb_connection());
    Q_XCB_NOOP(connection());
}
示例#2
0
 bool makeCurrent(QPlatformSurface *surface)
 {
     Q_XCB_NOOP(m_connection);
     bool ret = QEGLPlatformContext::makeCurrent(surface);
     Q_XCB_NOOP(m_connection);
     return ret;
 }
示例#3
0
void QXcbWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
{
    QRect bounds = region.boundingRect();

    if (size().isEmpty() || !geometry().contains(bounds))
        return;

    Q_XCB_NOOP(connection());

    QXcbWindow *window = static_cast<QXcbWindow *>(widget->window()->platformWindow());

    extern QWidgetData* qt_widget_data(QWidget *);
    QPoint widgetOffset = qt_qwidget_data(widget)->wrect.topLeft();

    QVector<QRect> rects = region.rects();
    for (int i = 0; i < rects.size(); ++i)
        m_image->put(window->window(), rects.at(i).topLeft() - widgetOffset, rects.at(i).translated(offset));

    Q_XCB_NOOP(connection());

    if (m_syncingResize) {
        xcb_flush(xcb_connection());
        connection()->sync();
        m_syncingResize = false;
        window->updateSyncRequestCounter();
    }
}
示例#4
0
void QGLXContext::doneCurrent()
{
    Q_XCB_NOOP(m_screen->connection());
    QPlatformGLContext::doneCurrent();
    glXMakeCurrent(DISPLAY_FROM_XCB(m_screen), 0, 0);
    Q_XCB_NOOP(m_screen->connection());
}
示例#5
0
QGLXContext::~QGLXContext()
{
    Q_XCB_NOOP(m_screen->connection());
    if (m_context)
        glXDestroyContext(DISPLAY_FROM_XCB(m_screen), m_context);
    Q_XCB_NOOP(m_screen->connection());
}
示例#6
0
void QXcbBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
{
    if (!m_image || m_image->size().isEmpty())
        return;

    QSize imageSize = m_image->size();

    QRegion clipped = region;
    clipped &= QRect(0, 0, window->width(), window->height());
    clipped &= QRect(0, 0, imageSize.width(), imageSize.height()).translated(-offset);

    QRect bounds = clipped.boundingRect();

    if (bounds.isNull())
        return;

    Q_XCB_NOOP(connection());

    QXcbWindow *platformWindow = static_cast<QXcbWindow *>(window->handle());

    QVector<QRect> rects = clipped.rects();
    for (int i = 0; i < rects.size(); ++i)
        m_image->put(platformWindow->xcb_window(), rects.at(i).topLeft(), rects.at(i).translated(offset));

    Q_XCB_NOOP(connection());

    if (m_syncingResize) {
        xcb_flush(xcb_connection());
        connection()->sync();
        m_syncingResize = false;
        platformWindow->updateSyncRequestCounter();
    }
}
示例#7
0
void QGLXContext::swapBuffers()
{
    Q_XCB_NOOP(m_screen->connection());
    glXSwapBuffers(DISPLAY_FROM_XCB(m_screen), m_drawable);
    doneCurrent();
    Q_XCB_NOOP(m_screen->connection());
}
示例#8
0
void QGLXContext::makeCurrent()
{
    Q_XCB_NOOP(m_screen->connection());
    QPlatformGLContext::makeCurrent();
    glXMakeCurrent(DISPLAY_FROM_XCB(m_screen), m_drawable, m_context);
    Q_XCB_NOOP(m_screen->connection());
}
示例#9
0
 QEGLXcbPlatformContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share,
                        EGLDisplay display, QXcbConnection *c)
     : QEGLPlatformContext(glFormat, share, display)
     , m_connection(c)
 {
     Q_XCB_NOOP(m_connection);
 }
示例#10
0
void QXcbWindowSurface::resize(const QSize &size)
{
    if (size == QWindowSurface::size())
        return;

    Q_XCB_NOOP(connection());
    QWindowSurface::resize(size);

    QXcbScreen *screen = static_cast<QXcbScreen *>(QPlatformScreen::platformScreenForWidget(window()));

    delete m_image;
    m_image = new QXcbShmImage(screen, size);
    Q_XCB_NOOP(connection());

    m_syncingResize = true;
}
示例#11
0
void* QGLXContext::getProcAddress(const QString& procName)
{
    Q_XCB_NOOP(m_screen->connection());
    typedef void *(*qt_glXGetProcAddressARB)(const GLubyte *);
    static qt_glXGetProcAddressARB glXGetProcAddressARB = 0;
    static bool resolved = false;

    if (resolved && !glXGetProcAddressARB)
        return 0;
    if (!glXGetProcAddressARB) {
        QList<QByteArray> glxExt = QByteArray(glXGetClientString(DISPLAY_FROM_XCB(m_screen), GLX_EXTENSIONS)).split(' ');
        if (glxExt.contains("GLX_ARB_get_proc_address")) {
#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4)
            void *handle = dlopen(NULL, RTLD_LAZY);
            if (handle) {
                glXGetProcAddressARB = (qt_glXGetProcAddressARB) dlsym(handle, "glXGetProcAddressARB");
                dlclose(handle);
            }
            if (!glXGetProcAddressARB)
#endif
            {
                extern const QString qt_gl_library_name();
//                QLibrary lib(qt_gl_library_name());
                QLibrary lib(QLatin1String("GL"));
                glXGetProcAddressARB = (qt_glXGetProcAddressARB) lib.resolve("glXGetProcAddressARB");
            }
        }
        resolved = true;
    }
    if (!glXGetProcAddressARB)
        return 0;
    return glXGetProcAddressARB(reinterpret_cast<const GLubyte *>(procName.toLatin1().data()));
}
示例#12
0
QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size, uint depth, QImage::Format format)
    : QXcbObject(screen->connection())
    , m_gc(0)
    , m_gc_window(0)
{
    Q_XCB_NOOP(connection());
    m_xcb_image = xcb_image_create_native(xcb_connection(),
                                          size.width(),
                                          size.height(),
                                          XCB_IMAGE_FORMAT_Z_PIXMAP,
                                          depth,
                                          0,
                                          ~0,
                                          0);

    m_shm_info.shmid = shmget (IPC_PRIVATE,
          m_xcb_image->stride * m_xcb_image->height, IPC_CREAT|0777);

    m_shm_info.shmaddr = m_xcb_image->data = (quint8 *)shmat (m_shm_info.shmid, 0, 0);
    m_shm_info.shmseg = xcb_generate_id(xcb_connection());

    xcb_generic_error_t *error = xcb_request_check(xcb_connection(), xcb_shm_attach_checked(xcb_connection(), m_shm_info.shmseg, m_shm_info.shmid, false));
    if (error) {
        qWarning() << "QXcbWindowSurface: Unable to attach to shared memory segment";
        free(error);
    }

    if (shmctl(m_shm_info.shmid, IPC_RMID, 0) == -1)
        qWarning() << "QXcbWindowSurface: Error while marking the shared memory segment to be destroyed";

    m_qimage = QImage( (uchar*) m_xcb_image->data, m_xcb_image->width, m_xcb_image->height, m_xcb_image->stride, format);
}
示例#13
0
QGLXContext::QGLXContext(Window window, QXcbScreen *screen, const QPlatformWindowFormat &format)
    : QPlatformGLContext()
    , m_screen(screen)
    , m_drawable((Drawable)window)
    , m_context(0)
{
    Q_XCB_NOOP(m_screen->connection());
    const QPlatformGLContext *sharePlatformContext;
    sharePlatformContext = format.sharedGLContext();
    GLXContext shareGlxContext = 0;
    if (sharePlatformContext)
        shareGlxContext = static_cast<const QGLXContext*>(sharePlatformContext)->glxContext();

    GLXFBConfig config = qglx_findConfig(DISPLAY_FROM_XCB(screen),screen->screenNumber(),format);
    m_context = glXCreateNewContext(DISPLAY_FROM_XCB(screen), config, GLX_RGBA_TYPE, shareGlxContext, TRUE);
    m_windowFormat = qglx_platformWindowFromGLXFBConfig(DISPLAY_FROM_XCB(screen), config, m_context);
    Q_XCB_NOOP(m_screen->connection());
}
示例#14
0
void QXcbBackingStore::resize(const QSize &size, const QRegion &)
{
    if (m_image && size == m_image->size())
        return;

    Q_XCB_NOOP(connection());

    QXcbScreen *screen = static_cast<QXcbScreen *>(window()->screen()->handle());
    QPlatformWindow *pw = window()->handle();
    if (!pw) {
        window()->create();
        pw = window()->handle();
    }
    QXcbWindow* win = static_cast<QXcbWindow *>(pw);

    delete m_image;
    m_image = new QXcbShmImage(screen, size, win->depth(), win->imageFormat());
    Q_XCB_NOOP(connection());

    m_syncingResize = true;
}
示例#15
0
QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size, uint depth, QImage::Format format)
    : QXcbObject(screen->connection())
    , m_gc(0)
    , m_gc_window(0)
{
    Q_XCB_NOOP(connection());
    m_xcb_image = xcb_image_create_native(xcb_connection(),
                                          size.width(),
                                          size.height(),
                                          XCB_IMAGE_FORMAT_Z_PIXMAP,
                                          depth,
                                          0,
                                          ~0,
                                          0);

    const int segmentSize = m_xcb_image->stride * m_xcb_image->height;
    if (!segmentSize)
        return;

    int id = shmget(IPC_PRIVATE, segmentSize, IPC_CREAT | 0600);
    if (id == -1)
        qWarning("QXcbShmImage: shmget() failed (%d) for size %d (%dx%d)",
                 errno, segmentSize, size.width(), size.height());
    else
        m_shm_info.shmid = id;
    m_shm_info.shmaddr = m_xcb_image->data = (quint8 *)shmat (m_shm_info.shmid, 0, 0);
    m_shm_info.shmseg = xcb_generate_id(xcb_connection());

    const xcb_query_extension_reply_t *shm_reply = xcb_get_extension_data(xcb_connection(), &xcb_shm_id);
    bool shm_present = shm_reply != NULL && shm_reply->present;
    xcb_generic_error_t *error = NULL;
    if (shm_present)
        error = xcb_request_check(xcb_connection(), xcb_shm_attach_checked(xcb_connection(), m_shm_info.shmseg, m_shm_info.shmid, false));
    if (!shm_present || error) {
        free(error);

        shmdt(m_shm_info.shmaddr);
        shmctl(m_shm_info.shmid, IPC_RMID, 0);

        m_shm_info.shmaddr = 0;

        m_xcb_image->data = (uint8_t *)malloc(segmentSize);
    } else {
        if (shmctl(m_shm_info.shmid, IPC_RMID, 0) == -1)
            qWarning() << "QXcbBackingStore: Error while marking the shared memory segment to be destroyed";
    }

    m_qimage = QImage( (uchar*) m_xcb_image->data, m_xcb_image->width, m_xcb_image->height, m_xcb_image->stride, format);
}
示例#16
0
 void doneCurrent()
 {
     Q_XCB_NOOP(m_connection);
     QEGLPlatformContext::doneCurrent();
     Q_XCB_NOOP(m_connection);
 }
示例#17
0
void QXcbShmImage::put(xcb_window_t window, const QPoint &target, const QRect &source)
{
    Q_XCB_NOOP(connection());
    if (m_gc_window != window) {
        if (m_gc)
            Q_XCB_CALL(xcb_free_gc(xcb_connection(), m_gc));

        m_gc = xcb_generate_id(xcb_connection());
        Q_XCB_CALL(xcb_create_gc(xcb_connection(), m_gc, window, 0, 0));

        m_gc_window = window;
    }

    Q_XCB_NOOP(connection());
    if (m_shm_info.shmaddr) {
        xcb_image_shm_put(xcb_connection(),
                          window,
                          m_gc,
                          m_xcb_image,
                          m_shm_info,
                          source.x(),
                          source.y(),
                          target.x(),
                          target.y(),
                          source.width(),
                          source.height(),
                          false);
    } else {
        // If we upload the whole image in a single chunk, the result might be
        // larger than the server's maximum request size and stuff breaks.
        // To work around that, we upload the image in chunks where each chunk
        // is small enough for a single request.
        int src_x = source.x();
        int src_y = source.y();
        int target_x = target.x();
        int target_y = target.y();
        int width = source.width();
        int height = source.height();

        // We must make sure that each request is not larger than max_req_size.
        // Each request takes req_size + m_xcb_image->stride * height bytes.
        uint32_t max_req_size = xcb_get_maximum_request_length(xcb_connection());
        uint32_t req_size = sizeof(xcb_put_image_request_t);
        int rows_per_put = (max_req_size - req_size) / m_xcb_image->stride;

        // This assert could trigger if a single row has more pixels than fit in
        // a single PutImage request. However, max_req_size is guaranteed to be
        // at least 16384 bytes. That should be enough for quite large images.
        Q_ASSERT(rows_per_put > 0);

        while (height > 0) {
            int rows = std::min(height, rows_per_put);

            xcb_image_t *subimage = xcb_image_subimage(m_xcb_image, src_x, src_y, width, rows,
                                                       0, 0, 0);
            xcb_image_put(xcb_connection(),
                          window,
                          m_gc,
                          subimage,
                          target_x,
                          target_y,
                          0);

            xcb_image_destroy(subimage);

            src_y += rows;
            target_y += rows;
            height -= rows;
        }
    }
    Q_XCB_NOOP(connection());

    m_dirty = m_dirty | source;

    xcb_flush(xcb_connection());
    Q_XCB_NOOP(connection());
}
示例#18
0
 void swapBuffers(QPlatformSurface *surface)
 {
     Q_XCB_NOOP(m_connection);
     QEGLPlatformContext::swapBuffers(surface);
     Q_XCB_NOOP(m_connection);
 }