Cocoa: Fix qmlscene flicker on startup.

The SG render thread was racing window creation in
the GUI thread, which would cause flicker if the
window won the race and was shown before the SG
thread had a frame ready.

Send a synchronous expose event before showing the
window - this will wait for the SG render thread.

In addition, don't defer NSwindow creation. The GL
context setup is done before the window is shown
and needs a fully created window.

New API: QWindowSystemInterface::handleSynchronousExposeEvent
Retire: QWindowSystemInterface::handleExposeEvent

Change-Id: I0bb46089d16ec4882aaac8db67b57d15e0f51531
Reviewed-on: http://codereview.qt.nokia.com/3399
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Gunnar Sletta <gunnar.sletta@nokia.com>
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@nokia.com>
bb10
Morten Sorvig 2011-08-23 12:51:11 +02:00 committed by Gunnar Sletta
parent 090ee21eac
commit 0719142321
7 changed files with 13 additions and 10 deletions

View File

@ -276,10 +276,10 @@ void QWindowSystemInterface::handleUnmapEvent(QWindow *tlw)
QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
}
void QWindowSystemInterface::handleExposeEvent(QWindow *tlw, const QRegion &region)
void QWindowSystemInterface::handleSynchronousExposeEvent(QWindow *tlw, const QRegion &region)
{
QWindowSystemInterfacePrivate::ExposeEvent *e = new QWindowSystemInterfacePrivate::ExposeEvent(tlw, region);
QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
QGuiApplicationPrivate::processWindowSystemEvent(e); // send event immediately.
}
bool QWindowSystemInterface::sendWindowSystemEvents(QAbstractEventDispatcher *eventDispatcher, QEventLoop::ProcessEventsFlags flags)

View File

@ -105,7 +105,7 @@ public:
static void handleMapEvent(QWindow *w);
static void handleUnmapEvent(QWindow *w);
static void handleExposeEvent(QWindow *w, const QRegion &region);
static void handleSynchronousExposeEvent(QWindow *tlw, const QRegion &region);
// Drag and drop. These events are sent immediately.
static Qt::DropAction handleDrag(QWindow *w, QMimeData *dropData, const QPoint &p);

View File

@ -121,8 +121,10 @@ void QCocoaWindow::setVisible(bool visible)
if (window()->transientParent())
setGeometry(window()->geometry());
// Make sure the QWindow has a frame ready before we show the NSWindow.
QWindowSystemInterface::handleSynchronousExposeEvent(window(), QRect(QPoint(), geometry().size()));
[m_nsWindow makeKeyAndOrderFront:nil];
QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size()));
} else {
[m_nsWindow orderOut:nil];
}
@ -319,7 +321,7 @@ QNSWindow * QCocoaWindow::createWindow()
panel = [[NSPanel alloc] initWithContentRect:frame
styleMask:m_windowAttributes
backing:NSBackingStoreBuffered
defer:YES];
defer:NO]; // see window case below
// ### crashes
// [panel setFloatingPanel:needFloating];
// [panel setWorksWhenModal:worksWhenModal];
@ -330,7 +332,8 @@ QNSWindow * QCocoaWindow::createWindow()
window = [[QNSWindow alloc] initWithContentRect:frame
styleMask:(NSResizableWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSTitledWindowMask)
backing:NSBackingStoreBuffered
defer:YES];
defer:NO]; // Deferring window creation breaks OpenGL (the GL context is set up
// before the window is shown and needs a proper window.).
break;
}

View File

@ -125,7 +125,7 @@ void QWaylandWindow::attach(QWaylandBuffer *buffer)
mBuffer = buffer;
if (mSurface) {
wl_surface_attach(mSurface, buffer->buffer(),0,0);
QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size()));
QWindowSystemInterface::handleSynchronousExposeEvent(window(), QRect(QPoint(), geometry().size()));
}
}

View File

@ -902,7 +902,7 @@ void QWindowsWindow::handleWmPaint(HWND hwnd, UINT,
if (QWindowsContext::verboseIntegration)
qDebug() << __FUNCTION__ << this << window() << updateRect;
QWindowSystemInterface::handleExposeEvent(window(), QRegion(updateRect));
QWindowSystemInterface::handleSynchronousExposeEvent(window(), QRegion(updateRect));
clearFlag(WithinWmPaint);
m_hdc = 0;
EndPaint(hwnd, &ps);

View File

@ -472,7 +472,7 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
switch (response_type) {
case XCB_EXPOSE:
HANDLE_PLATFORM_WINDOW_EVENT(xcb_expose_event_t, window, handleExposeEvent);
HANDLE_PLATFORM_WINDOW_EVENT(xcb_expose_event_t, window, handleSynchronousExposeEvent);
case XCB_BUTTON_PRESS:
HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_press_event_t, event, handleButtonPressEvent);
case XCB_BUTTON_RELEASE:

View File

@ -1074,7 +1074,7 @@ QXcbEGLSurface *QXcbWindow::eglSurface() const
void QXcbWindow::handleExposeEvent(const xcb_expose_event_t *event)
{
QRect rect(event->x, event->y, event->width, event->height);
QWindowSystemInterface::handleExposeEvent(window(), rect);
QWindowSystemInterface::handleSynchronousExposeEvent(window(), rect);
}
void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *event)