QWSWindowSurface研究

来源:互联网 发布:mac怎样保存收藏网页 编辑:程序博客网 时间:2024/05/16 09:30
1、创建QWSWindowSurface(QWSWindowSurface或QWSLocalMemSurface
QWidget::setVisible()中进行创建。
        //we have to at least create toplevels before applyX11SpecificCommandLineArguments
        //but not children of non-visible parents
        QWidget *pw = parentWidget();
        if (!testAttribute(Qt::WA_WState_Created)
            && (isWindow() || pw->testAttribute(Qt::WA_WState_Created))) {
            create();
        }
在create()中创建QWidgetBackingStore。
qwidget.cpp : 1438
    // a real toplevel window needs a backing store
    if (isWindow() && windowType() != Qt::Desktop) {
        d->topData()->backingStore.destroy();
        if (hasBackingStoreSupport())
            d->topData()->backingStore.create(this);
    }
qwidget.cpp : 325
QWindowSurface *QWidgetPrivate::createDefaultWindowSurface()
{
    Q_Q(QWidget);

    QWindowSurface *surface;
    if (QApplicationPrivate::graphicsSystem())
        surface = QApplicationPrivate::graphicsSystem()->createWindowSurface(q); //如果设置了graphicssystem,则使用此方式
    else
        surface = createDefaultWindowSurface_sys(); //默认是此方式

    return surface;
}
如果设置了graphicssystem,则是
QWindowSurface *QWSGraphicsSystem::createWindowSurface(QWidget*widget) const
{
    return screen->createSurface(widget);
}
否则调用QScreen的createSurface()
QWindowSurface *QWidgetPrivate::createDefaultWindowSurface_sys()
{
    Q_Q(QWidget);
    if (q->windowType()== Qt::Desktop)
        return 0;
    q->ensurePolished();
    return qt_screen->createSurface(q);
}
对于2D,都调用
QWSWindowSurface* QScreen::createSurface(QWidget*widget) const
{
#ifndef QT_NO_PAINTONSCREEN
    if (isWidgetPaintOnScreen(widget)&& base())
        return new QWSOnScreenSurface(widget);
    else
#endif
    if (QApplication::type()== QApplication::GuiServer)
        return new QWSLocalMemSurface(widget);
#ifndef QT_NO_QWS_MULTIPROCESS
    else
        return new QWSSharedMemSurface(widget);
#endif

    return 0;
}
此时创建的QWSLocalMemSurface没有对应的内存DC(相对其他GUI来说)。
2、给QWSLocalMemSurface分配内存空间。
还是QWidget::setVisible()中,7598行
        if (isWindow() || parentWidget()->isVisible()) {
            // remove posted quit events when showing a new window
            QCoreApplication::removePostedEvents(qApp, QEvent::Quit);

            d->show_helper();

#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS)|| defined(Q_WS_MAC)
            qApp->d_func()->sendSyntheticEnterLeave(this);
#endif
        }
show_helper()中调用了show_sys()
qwidget_qws.cpp :594
        if (QWindowSurface *surface = q->windowSurface()) {
            const QRect frameRect= q->frameGeometry();
            if (surface->geometry()!= frameRect)
                surface->setGeometry(frameRect);
        }
其真正创建在surface的setGeometry()中。
void QWSLocalMemSurface::setGeometry(const QRect&rect)
{
    QSize size = rect.size();

    QWidget *win = window();
    if (win && !win->mask().isEmpty()) {
        const QRegion region = win->mask()
                               & rect.translated(-win->geometry().topLeft());
        size = region.boundingRect().size();
    }

    uchar *deleteLater = 0;
    // In case of a Hide event we need to delete the memory after sending the
    // event to the server in order to let the server animate the event.
    if (size.isEmpty()) {
        deleteLater = mem;
        mem = 0;
    }

    if (img.size() != size) {
        delete[] mem;
        if (size.isEmpty()) {
            mem = 0;
            img = QImage();
        } else {
            const QImage::Format format= preferredImageFormat(win);
            const int bpl = nextMulOf4(bytesPerPixel(format)* size.width());
            const int memsize = bpl * size.height();
            mem = new uchar[memsize];
            img = QImage(mem, size.width(), size.height(), bpl, format);
            setImageMetrics(img, win);
        }
    }

    QWSWindowSurface::setGeometry(rect);
    delete[] deleteLater;
}
原创粉丝点击