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();
}
//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);
}
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;
}
{
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);
}
{
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);
}
{
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;
}
{
#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
}
// 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);
}
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;
}
{
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;
}