From 071914232189735ae6475d44d07f11f90b4729a1 Mon Sep 17 00:00:00 2001 From: Morten Sorvig Date: Tue, 23 Aug 2011 12:51:11 +0200 Subject: 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 Reviewed-by: Gunnar Sletta Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/cocoa/qcocoawindow.mm | 9 ++++++--- src/plugins/platforms/wayland/qwaylandwindow.cpp | 2 +- src/plugins/platforms/windows/qwindowswindow.cpp | 2 +- src/plugins/platforms/xcb/qxcbconnection.cpp | 2 +- src/plugins/platforms/xcb/qxcbwindow.cpp | 2 +- 5 files changed, 10 insertions(+), 7 deletions(-) (limited to 'src/plugins/platforms') diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 78785a8527..ef04fc4238 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -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; } diff --git a/src/plugins/platforms/wayland/qwaylandwindow.cpp b/src/plugins/platforms/wayland/qwaylandwindow.cpp index f685dae729..48da7b537e 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow.cpp +++ b/src/plugins/platforms/wayland/qwaylandwindow.cpp @@ -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())); } } diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 95b770f043..8e10ae694a 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -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); diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index a8ffc5832a..c60e066ed9 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -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: diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 0f3d1d57d1..db8d37e817 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -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) -- cgit v1.2.3