From 08a62af7c58927c37a92a5749bc87be1ae3d6d2d Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 1 Apr 2016 14:53:35 +0200 Subject: Windows QPA: Don't send geometry change after window creation for maximized/fullscreen. For these states, geometry change will be sent from the code called by setWindowState(); the geometry obtained immediately after window creation is then no longer valid. Task-number: QTBUG-52231 Change-Id: Ia7cbe95e73c5dd4126bb63d448b83f2cab6a53a1 Reviewed-by: Oliver Wolff --- src/plugins/platforms/windows/qwindowsintegration.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index 27ec258f37..bf238c3e77 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -318,10 +318,14 @@ QPlatformWindow *QWindowsIntegration::createPlatformWindow(QWindow *window) cons if (requested.flags != obtained.flags) window->setFlags(obtained.flags); - // Trigger geometry/screen change signals of QWindow. + // Trigger geometry change (unless it has a special state in which case setWindowState() + // will send the message) and screen change signals of QWindow. if ((obtained.flags & Qt::Desktop) != Qt::Desktop) { - if (requested.geometry != obtained.geometry) + const Qt::WindowState state = window->windowState(); + if (state != Qt::WindowMaximized && state != Qt::WindowFullScreen + && requested.geometry != obtained.geometry) { QWindowSystemInterface::handleGeometryChange(window, obtained.geometry); + } QPlatformScreen *screen = result->screenForGeometry(obtained.geometry); if (screen && result->screen() != screen) QWindowSystemInterface::handleWindowScreenChanged(window, screen->screen()); -- cgit v1.2.3 From 8c3e671239c83238fc036f8a94dde04920c43871 Mon Sep 17 00:00:00 2001 From: Joni Poikelin Date: Fri, 1 Apr 2016 10:52:37 +0300 Subject: Fix assert with Meta modifier Meta modifier is not found in some configurations which triggers an assert. Instead of assert, ignore the modifier if it is not found. Task-number: QTBUG-52298 Change-Id: I258cee4014a30162afebb423eadaf07ef0ed6a1f Reviewed-by: Paul Olav Tvete --- src/plugins/platforms/xcb/qxcbkeyboard.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp index 631dd17908..1eeb59a665 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp +++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp @@ -996,7 +996,6 @@ QList QXcbKeyboard::possibleKeys(const QKeyEvent *event) const Q_ASSERT(shiftMod < 32); Q_ASSERT(altMod < 32); Q_ASSERT(controlMod < 32); - Q_ASSERT(metaMod < 32); xkb_mod_mask_t depressed; int qtKey = 0; @@ -1017,7 +1016,7 @@ QList QXcbKeyboard::possibleKeys(const QKeyEvent *event) const depressed |= (1 << shiftMod); if (neededMods & Qt::ControlModifier) depressed |= (1 << controlMod); - if (neededMods & Qt::MetaModifier) + if (metaMod < 32 && neededMods & Qt::MetaModifier) depressed |= (1 << metaMod); xkb_state_update_mask(kb_state, depressed, latchedMods, lockedMods, 0, 0, lockedLayout); sym = xkb_state_key_get_one_sym(kb_state, keycode); -- cgit v1.2.3 From 17d17a5d72d4f98b692c8ab8a7037aa29b503dae Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Tue, 5 Apr 2016 12:59:17 +0200 Subject: winrt: Change input panel behavior to platform default Native applications do open the native input pane when the touch release happens, not during press. Widget applications seem to not ask the theme, so it was acting like native there already. For Qt Quick applications the platform theme is queried, now returning true for SetFocusOnTouchRelease. As a side-effect this also fixes QTBUG-52295, as showInputPanel() at press time causes issues with focus handling, causing the input pane to disappear again. Task-number: QTBUG-52295 Change-Id: I6da6a0126f695233b7c8a399a1549a8b7c824af2 Reviewed-by: Friedemann Kleint Reviewed-by: Oliver Wolff --- src/plugins/platforms/winrt/qwinrttheme.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/winrt/qwinrttheme.cpp b/src/plugins/platforms/winrt/qwinrttheme.cpp index 7ef13fd0aa..bc3ba210c9 100644 --- a/src/plugins/platforms/winrt/qwinrttheme.cpp +++ b/src/plugins/platforms/winrt/qwinrttheme.cpp @@ -355,7 +355,7 @@ QVariant QWinRTTheme::styleHint(QPlatformIntegration::StyleHint hint) case QPlatformIntegration::PasswordMaskCharacter: return defaultThemeHint(PasswordMaskCharacter); case QPlatformIntegration::SetFocusOnTouchRelease: - return false; + return true; case QPlatformIntegration::ShowIsMaximized: return true; case QPlatformIntegration::MousePressAndHoldInterval: -- cgit v1.2.3 From 58c23ae1619fb4afaae9c8eb2527c0906baef97b Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 6 Apr 2016 09:57:43 +0200 Subject: Windows QPA: Check QWindowsStaticOpenGLContext in nativeResourceForIntegration(). The instance of QWindowsStaticOpenGLContext has been observed to be 0. Task-number: QTBUG-52387 Change-Id: I1ca97c6df0d96e732ae62354e03f465cd461bcb4 Reviewed-by: Joerg Bornemann --- src/plugins/platforms/windows/qwindowsnativeinterface.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp index 659ef79c18..add6d6b1f0 100644 --- a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp +++ b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp @@ -138,8 +138,10 @@ void *QWindowsNativeInterface::nativeResourceForIntegration(const QByteArray &re #ifdef QT_NO_OPENGL Q_UNUSED(resource) #else - if (resourceType(resource) == GlHandleType) - return QWindowsIntegration::staticOpenGLContext()->moduleHandle(); + if (resourceType(resource) == GlHandleType) { + if (const QWindowsStaticOpenGLContext *sc = QWindowsIntegration::staticOpenGLContext()) + return sc->moduleHandle(); + } #endif return 0; -- cgit v1.2.3 From c7ec317822258e652e74af4449b1237a4755688f Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 6 Apr 2016 13:22:57 +0200 Subject: Direct2D QPA: Fix build with clang-cl. Remove overzealous constexpr triggering errors like: in file included from .\qwindowsdirect2dpaintengine.cpp:44: ./qwindowsdirect2dhelpers.h(58,37) : error: constexpr function never produces a constant expression [-Winvalid-constexpr] Q_DECL_CONSTEXPR inline D2D1_RECT_F to_d2d_rect_f(const QRectF &qrect) ^ ./qwindowsdirect2dhelpers.h(60,12) : note: non-constexpr function 'RectF' cannot be used in a constant expression return D2D1::RectF(qrect.x(), qrect.y(), qrect.x() + qrect.width(), qrect.y() + qrect.height()); ^ C:\Program Files (x86)\Windows Kits\10\include\10.0.10586.0\um\d2d1helper.h(160,5) : note: declared here RectF( ^ Task-number: QTBUG-50860 Change-Id: I0bb4d17b7a7db69c5cc7e286ef0b8ff104f72b2e Reviewed-by: Joerg Bornemann --- src/plugins/platforms/direct2d/qwindowsdirect2dhelpers.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dhelpers.h b/src/plugins/platforms/direct2d/qwindowsdirect2dhelpers.h index 08886854ee..228c60aaf6 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dhelpers.h +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dhelpers.h @@ -44,37 +44,37 @@ QT_BEGIN_NAMESPACE -Q_DECL_CONSTEXPR inline D2D1_RECT_U to_d2d_rect_u(const QRect &qrect) +inline D2D1_RECT_U to_d2d_rect_u(const QRect &qrect) { return D2D1::RectU(qrect.x(), qrect.y(), qrect.x() + qrect.width(), qrect.y() + qrect.height()); } -Q_DECL_CONSTEXPR inline D2D1_RECT_F to_d2d_rect_f(const QRectF &qrect) +inline D2D1_RECT_F to_d2d_rect_f(const QRectF &qrect) { return D2D1::RectF(qrect.x(), qrect.y(), qrect.x() + qrect.width(), qrect.y() + qrect.height()); } -Q_DECL_CONSTEXPR inline D2D1_SIZE_U to_d2d_size_u(const QSizeF &qsize) +inline D2D1_SIZE_U to_d2d_size_u(const QSizeF &qsize) { return D2D1::SizeU(qsize.width(), qsize.height()); } -Q_DECL_CONSTEXPR inline D2D1_SIZE_U to_d2d_size_u(const QSize &qsize) +inline D2D1_SIZE_U to_d2d_size_u(const QSize &qsize) { return D2D1::SizeU(qsize.width(), qsize.height()); } -Q_DECL_CONSTEXPR inline D2D1_POINT_2F to_d2d_point_2f(const QPointF &qpoint) +inline D2D1_POINT_2F to_d2d_point_2f(const QPointF &qpoint) { return D2D1::Point2F(qpoint.x(), qpoint.y()); } -Q_DECL_CONSTEXPR inline D2D1::ColorF to_d2d_color_f(const QColor &c) +inline D2D1::ColorF to_d2d_color_f(const QColor &c) { return D2D1::ColorF(c.redF(), c.greenF(), c.blueF(), c.alphaF()); } -Q_DECL_CONSTEXPR inline D2D1_MATRIX_3X2_F to_d2d_matrix_3x2_f(const QTransform &transform) +inline D2D1_MATRIX_3X2_F to_d2d_matrix_3x2_f(const QTransform &transform) { return D2D1::Matrix3x2F(transform.m11(), transform.m12(), transform.m21(), transform.m22(), -- cgit v1.2.3 From e4e62496ac62deab0e8f6ae9f064cf153b31d2fa Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 1 Apr 2016 15:31:16 +0200 Subject: Windows QPA: Scale hotspot of custom cursors correctly. Separate factors in QWindowsCursor::createPixmapCursor() and apply factor to the hotspot. Task-number: QTBUG-52276 Change-Id: Ia5a5db39ddc2bc4215a23ff8625431af9b4a76d8 Reviewed-by: Adam Light Reviewed-by: Oliver Wolff --- src/plugins/platforms/windows/qwindowscursor.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qwindowscursor.cpp b/src/plugins/platforms/windows/qwindowscursor.cpp index cda741c226..844fe23517 100644 --- a/src/plugins/platforms/windows/qwindowscursor.cpp +++ b/src/plugins/platforms/windows/qwindowscursor.cpp @@ -97,9 +97,9 @@ QWindowsPixmapCursorCacheKey::QWindowsPixmapCursorCacheKey(const QCursor &c) HCURSOR QWindowsCursor::createPixmapCursor(QPixmap pixmap, const QPoint &hotSpot, qreal scaleFactor) { HCURSOR cur = 0; - scaleFactor /= pixmap.devicePixelRatioF(); - if (!qFuzzyCompare(scaleFactor, 1)) { - pixmap = pixmap.scaled((scaleFactor * QSizeF(pixmap.size())).toSize(), + const qreal pixmapScaleFactor = scaleFactor / pixmap.devicePixelRatioF(); + if (!qFuzzyCompare(pixmapScaleFactor, 1)) { + pixmap = pixmap.scaled((pixmapScaleFactor * QSizeF(pixmap.size())).toSize(), Qt::KeepAspectRatio, Qt::SmoothTransformation); } QBitmap mask = pixmap.mask(); @@ -113,8 +113,8 @@ HCURSOR QWindowsCursor::createPixmapCursor(QPixmap pixmap, const QPoint &hotSpot ICONINFO ii; ii.fIcon = 0; - ii.xHotspot = DWORD(hotSpot.x()); - ii.yHotspot = DWORD(hotSpot.y()); + ii.xHotspot = DWORD(qRound(hotSpot.x() * scaleFactor)); + ii.yHotspot = DWORD(qRound(hotSpot.y() * scaleFactor)); ii.hbmMask = im; ii.hbmColor = ic; -- cgit v1.2.3 From 5e38706624998e6fc3679fa2c65770fea644d08b Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Wed, 6 Apr 2016 11:51:09 +0200 Subject: Reduce verbosity for QT_XCB_GL_INTEGRATION=none When QT_XCB_GL_INTEGRATION=none we were printing: 1) qt.xcb.glintegration: QT_XCB_GL_INTEGRATION is set to "none" 2) qt.xcb.glintegration: Choosing xcb gl-integration based on following priority () 3) qt.xcb.glintegration: Failed to create xcb gl-integration Omit line 2 (useless) and line 3 (misleading). Change-Id: If5e65a5bc8cc4a1fa97858049a26aac9a9535950 Reviewed-by: Shawn Rutledge --- src/plugins/platforms/xcb/qxcbconnection.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 4fee772cd6..e1e2ec5d24 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -653,17 +653,19 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra } } - qCDebug(QT_XCB_GLINTEGRATION) << "Choosing xcb gl-integration based on following priority\n" << glIntegrationNames; - for (int i = 0; i < glIntegrationNames.size() && !m_glIntegration; i++) { - m_glIntegration = QXcbGlIntegrationFactory::create(glIntegrationNames.at(i)); - if (m_glIntegration && !m_glIntegration->initialize(this)) { - qCDebug(QT_XCB_GLINTEGRATION) << "Failed to initialize xcb gl-integration" << glIntegrationNames.at(i); - delete m_glIntegration; - m_glIntegration = Q_NULLPTR; + if (!glIntegrationNames.isEmpty()) { + qCDebug(QT_XCB_GLINTEGRATION) << "Choosing xcb gl-integration based on following priority\n" << glIntegrationNames; + for (int i = 0; i < glIntegrationNames.size() && !m_glIntegration; i++) { + m_glIntegration = QXcbGlIntegrationFactory::create(glIntegrationNames.at(i)); + if (m_glIntegration && !m_glIntegration->initialize(this)) { + qCDebug(QT_XCB_GLINTEGRATION) << "Failed to initialize xcb gl-integration" << glIntegrationNames.at(i); + delete m_glIntegration; + m_glIntegration = Q_NULLPTR; + } } + if (!m_glIntegration) + qCDebug(QT_XCB_GLINTEGRATION) << "Failed to create xcb gl-integration"; } - if (!m_glIntegration) - qCDebug(QT_XCB_GLINTEGRATION) << "Failed to create xcb gl-integration"; sync(); } -- cgit v1.2.3 From 282ebf9bd2b52c75659ed55396cf3593c1f2a299 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Thu, 7 Apr 2016 13:29:00 +0200 Subject: xcb: replace qt.xcb.glintegration logging category with qt.qpa.gl This is more concise, consistent with Windows, and fits the pattern that all logging categories in QPA plugins should begin with qt.qpa. Change-Id: Ica169b547cb3d816e6e2c0449f0e4a0c58883b9a Reviewed-by: Gatis Paeglis --- src/plugins/platforms/xcb/gl_integrations/qxcbglintegration.cpp | 2 +- src/plugins/platforms/xcb/gl_integrations/qxcbglintegration.h | 2 +- .../platforms/xcb/gl_integrations/xcb_egl/qxcbeglintegration.cpp | 6 +++--- .../platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.cpp | 6 +++--- src/plugins/platforms/xcb/qxcbconnection.cpp | 8 ++++---- 5 files changed, 12 insertions(+), 12 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/xcb/gl_integrations/qxcbglintegration.cpp b/src/plugins/platforms/xcb/gl_integrations/qxcbglintegration.cpp index f2ea56b45a..59401d2ce7 100644 --- a/src/plugins/platforms/xcb/gl_integrations/qxcbglintegration.cpp +++ b/src/plugins/platforms/xcb/gl_integrations/qxcbglintegration.cpp @@ -41,7 +41,7 @@ QT_BEGIN_NAMESPACE -Q_LOGGING_CATEGORY(QT_XCB_GLINTEGRATION, "qt.xcb.glintegration") +Q_LOGGING_CATEGORY(lcQpaGl, "qt.qpa.gl") QXcbGlIntegration::QXcbGlIntegration() { diff --git a/src/plugins/platforms/xcb/gl_integrations/qxcbglintegration.h b/src/plugins/platforms/xcb/gl_integrations/qxcbglintegration.h index 6cc96d39be..719d2ace90 100644 --- a/src/plugins/platforms/xcb/gl_integrations/qxcbglintegration.h +++ b/src/plugins/platforms/xcb/gl_integrations/qxcbglintegration.h @@ -50,7 +50,7 @@ class QPlatformOffscreenSurface; class QOffscreenSurface; class QXcbNativeInterfaceHandler; -Q_XCB_EXPORT Q_DECLARE_LOGGING_CATEGORY(QT_XCB_GLINTEGRATION) +Q_XCB_EXPORT Q_DECLARE_LOGGING_CATEGORY(lcQpaGl) class Q_XCB_EXPORT QXcbGlIntegration { diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglintegration.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglintegration.cpp index 29f92a1049..f546cda4ad 100644 --- a/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglintegration.cpp +++ b/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglintegration.cpp @@ -51,7 +51,7 @@ QXcbEglIntegration::QXcbEglIntegration() : m_connection(Q_NULLPTR) , m_egl_display(EGL_NO_DISPLAY) { - qCDebug(QT_XCB_GLINTEGRATION) << "Xcb EGL gl-integration created"; + qCDebug(lcQpaGl) << "Xcb EGL gl-integration created"; } QXcbEglIntegration::~QXcbEglIntegration() @@ -69,13 +69,13 @@ bool QXcbEglIntegration::initialize(QXcbConnection *connection) bool success = eglInitialize(m_egl_display, &major, &minor); if (!success) { m_egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY); - qCDebug(QT_XCB_GLINTEGRATION) << "Xcb EGL gl-integration retrying with display" << m_egl_display; + qCDebug(lcQpaGl) << "Xcb EGL gl-integration retrying with display" << m_egl_display; success = eglInitialize(m_egl_display, &major, &minor); } m_native_interface_handler.reset(new QXcbEglNativeInterfaceHandler(connection->nativeInterface())); - qCDebug(QT_XCB_GLINTEGRATION) << "Xcb EGL gl-integration successfully initialized"; + qCDebug(lcQpaGl) << "Xcb EGL gl-integration successfully initialized"; return success; } diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.cpp index 3e963ccaa8..a3668df59a 100644 --- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.cpp +++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.cpp @@ -93,7 +93,7 @@ QXcbGlxIntegration::QXcbGlxIntegration() : m_connection(Q_NULLPTR) , m_glx_first_event(0) { - qCDebug(QT_XCB_GLINTEGRATION) << "Xcb GLX gl-integration created"; + qCDebug(lcQpaGl) << "Xcb GLX gl-integration created"; } QXcbGlxIntegration::~QXcbGlxIntegration() @@ -118,7 +118,7 @@ bool QXcbGlxIntegration::initialize(QXcbConnection *connection) xcb_glx_query_version_reply_t *xglx_query = xcb_glx_query_version_reply(m_connection->xcb_connection(), xglx_query_cookie, &error); if (!xglx_query || error) { - qCWarning(QT_XCB_GLINTEGRATION) << "QXcbConnection: Failed to initialize GLX"; + qCWarning(lcQpaGl) << "QXcbConnection: Failed to initialize GLX"; free(error); return false; } @@ -127,7 +127,7 @@ bool QXcbGlxIntegration::initialize(QXcbConnection *connection) m_native_interface_handler.reset(new QXcbGlxNativeInterfaceHandler(connection->nativeInterface())); - qCDebug(QT_XCB_GLINTEGRATION) << "Xcb GLX gl-integration successfully initialized"; + qCDebug(lcQpaGl) << "Xcb GLX gl-integration successfully initialized"; return true; } diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index e1e2ec5d24..cb222842db 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -644,7 +644,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra glIntegrationNames << QStringLiteral("xcb_glx") << QStringLiteral("xcb_egl"); QString glIntegrationName = QString::fromLocal8Bit(qgetenv("QT_XCB_GL_INTEGRATION")); if (!glIntegrationName.isEmpty()) { - qCDebug(QT_XCB_GLINTEGRATION) << "QT_XCB_GL_INTEGRATION is set to" << glIntegrationName; + qCDebug(lcQpaGl) << "QT_XCB_GL_INTEGRATION is set to" << glIntegrationName; if (glIntegrationName != QLatin1String("none")) { glIntegrationNames.removeAll(glIntegrationName); glIntegrationNames.prepend(glIntegrationName); @@ -654,17 +654,17 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra } if (!glIntegrationNames.isEmpty()) { - qCDebug(QT_XCB_GLINTEGRATION) << "Choosing xcb gl-integration based on following priority\n" << glIntegrationNames; + qCDebug(lcQpaGl) << "Choosing xcb gl-integration based on following priority\n" << glIntegrationNames; for (int i = 0; i < glIntegrationNames.size() && !m_glIntegration; i++) { m_glIntegration = QXcbGlIntegrationFactory::create(glIntegrationNames.at(i)); if (m_glIntegration && !m_glIntegration->initialize(this)) { - qCDebug(QT_XCB_GLINTEGRATION) << "Failed to initialize xcb gl-integration" << glIntegrationNames.at(i); + qCDebug(lcQpaGl) << "Failed to initialize xcb gl-integration" << glIntegrationNames.at(i); delete m_glIntegration; m_glIntegration = Q_NULLPTR; } } if (!m_glIntegration) - qCDebug(QT_XCB_GLINTEGRATION) << "Failed to create xcb gl-integration"; + qCDebug(lcQpaGl) << "Failed to create xcb gl-integration"; } sync(); -- cgit v1.2.3 From f931e5e72d4617023bbea46cba2c0d61bb1efa4f Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Thu, 7 Apr 2016 15:07:04 +0200 Subject: add cross-platform tablet->mouse event synth; enable on Android It's urgent to fix the issue that on Android, it became impossible to interact with any widget or MouseArea which handles only mouse events but not tablet events, using the stylus, because stylus events are sent only as QTabletEvents. Before 5.6 (change 01d78ba86a631386a4d47b7c12d2a359da28f517) they were sent as touch events, and mouse events were synthesized from those. Whereas on other platforms, every QTabletEvent is followed by a synthesized QMouseEvent. This fix proceeds in the direction that event synthesis should be done in cross-platform code so that platform plugins don't have to repeat it, following the same pattern as for touch->mouse synthesis. Just as in that case, the application can disable it, and the platform plugin can also report that it's unnecessary for Qt to do the synthesis because the platform already does. So QTBUG-51618 is fixed, but QTBUG-47007 requires us to remove the tablet->mouse synthesis from all platform plugins, because the plugin does not know whether the tablet event was accepted or not, so it does not have enough information to decide whether to synthesize a mouse event. Synthesis has been unconditional until now, which contradicts what the documentation says: the mouse event should be sent only if the tablet event is NOT accepted. We can now gradually make this promise come true. [ChangeLog][QtCore][Tablet support] A synthetic mouse event will no longer be sent after every QTabletEvent, only after those which are not accepted (as documented). Task-number: QTBUG-47007 Task-number: QTBUG-51618 Change-Id: I99404e0c2b39bbca4377be6fd48e0c6b20338466 Reviewed-by: Laszlo Agocs --- src/plugins/platforms/android/androidjnimain.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp index 516fe60c8c..51849aa688 100644 --- a/src/plugins/platforms/android/androidjnimain.cpp +++ b/src/plugins/platforms/android/androidjnimain.cpp @@ -864,6 +864,7 @@ Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void */*reserved*/) __android_log_print(ANDROID_LOG_FATAL, "Qt", "registerNatives failed"); return -1; } + QWindowSystemInterfacePrivate::TabletEvent::setPlatformSynthesizesMouse(false); m_javaVM = vm; return JNI_VERSION_1_4; -- cgit v1.2.3 From 89034600939bbfe241ba3d6136abf7bb6961db52 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Mon, 15 Feb 2016 11:16:39 +0300 Subject: QtBase: use erase and std::remove_if with QList and QVector ... instead of using removeAt in a loop, with quadratic complexity. Change-Id: I38b49e56b12c396db9fc0f1b75d8fb43c503a7f6 Reviewed-by: Marc Mutz --- src/plugins/platforms/ios/qiosmenu.mm | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosmenu.mm b/src/plugins/platforms/ios/qiosmenu.mm index 84707319d7..db1b5b8cc8 100644 --- a/src/plugins/platforms/ios/qiosmenu.mm +++ b/src/plugins/platforms/ios/qiosmenu.mm @@ -48,6 +48,9 @@ #include "qiosintegration.h" #include "qiostextresponder.h" +#include +#include + // m_currentMenu points to the currently visible menu. // Only one menu will be visible at a time, and if a second menu // is shown on top of a first, the first one will be told to hide. @@ -525,14 +528,10 @@ bool QIOSMenu::eventFilter(QObject *obj, QEvent *event) QIOSMenuItemList QIOSMenu::visibleMenuItems() const { - QIOSMenuItemList visibleMenuItems = m_menuItems; - - for (int i = visibleMenuItems.count() - 1; i >= 0; --i) { - QIOSMenuItem *item = visibleMenuItems.at(i); - if (!item->m_enabled || !item->m_visible || item->m_separator) - visibleMenuItems.removeAt(i); - } - + QIOSMenuItemList visibleMenuItems; + visibleMenuItems.reserve(m_menuItems.size()); + std::copy_if(m_menuItems.begin(), m_menuItems.end(), std::back_inserter(visibleMenuItems), + [](QIOSMenuItem *item) { return item->m_enabled && item->m_visible && !item->m_separator; }); return visibleMenuItems; } -- cgit v1.2.3 From 5f39a0ef8d037ed8d1fa19d5514308ed4a2ca161 Mon Sep 17 00:00:00 2001 From: Louai Al-Khanji Date: Thu, 3 Mar 2016 14:16:29 -0800 Subject: X11: Better support non-32bit visuals This patch improves support for non-32bit screen configurations on X. The patch mostly touches the xcb platform plugin but the changes to the glx convenience functions do affect e.g. the offscreen plugin as well. Since QWindow instances are now by default of type RasterGL instead of Raster the majority of all windows are in fact instances of QXcbGlxWindow. This means that the eventual QSurfaceFormat that we use is chosen based on the available OpenGL configurations. Here the GLX config resolution code did not do a very good job in trying to find the closest match relative to the requested QSurfaceFormat, instead preferring higher bit depths. This is an issue since many configurations support 32-bit windows even if the screen itself has a root window with depth 16. In particular, servers supporting both GLX and Render are very likely to have such visuals. Particularly affected are remote X connections - even if the application itself makes no use of OpenGL at all! The changes introduced by this patch are as follows: 1. Improve the GLX visual selection logic 2. Improve the xcb visual selection logic 3. Remove duplicated visual lookup for OpenGL-enabled windows 4. Configure the default QSurfaceFormat to match the primary screen depth Change-Id: Id1c176359e63a4581410e20350db5ac2c083e1cf Reviewed-by: Lars Knoll Reviewed-by: Laszlo Agocs --- .../gl_integrations/xcb_egl/qxcbeglintegration.cpp | 5 +- .../xcb/gl_integrations/xcb_egl/qxcbeglwindow.cpp | 23 +-- .../xcb/gl_integrations/xcb_egl/qxcbeglwindow.h | 7 +- .../gl_integrations/xcb_glx/qglxintegration.cpp | 2 +- .../xcb/gl_integrations/xcb_glx/qglxintegration.h | 2 +- .../gl_integrations/xcb_glx/qxcbglxintegration.cpp | 2 +- .../xcb/gl_integrations/xcb_glx/qxcbglxwindow.cpp | 12 +- .../xcb/gl_integrations/xcb_glx/qxcbglxwindow.h | 3 +- src/plugins/platforms/xcb/qxcbscreen.cpp | 66 ++++++++- src/plugins/platforms/xcb/qxcbscreen.h | 3 + src/plugins/platforms/xcb/qxcbwindow.cpp | 165 ++++++++------------- src/plugins/platforms/xcb/qxcbwindow.h | 4 +- 12 files changed, 165 insertions(+), 129 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglintegration.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglintegration.cpp index f546cda4ad..079f0466dc 100644 --- a/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglintegration.cpp +++ b/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglintegration.cpp @@ -87,7 +87,7 @@ QXcbWindow *QXcbEglIntegration::createWindow(QWindow *window) const QPlatformOpenGLContext *QXcbEglIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const { QXcbScreen *screen = static_cast(context->screen()->handle()); - QXcbEglContext *platformContext = new QXcbEglContext(context->format(), + QXcbEglContext *platformContext = new QXcbEglContext(screen->surfaceFormatFor(context->format()), context->shareHandle(), eglDisplay(), screen->connection(), @@ -98,7 +98,8 @@ QPlatformOpenGLContext *QXcbEglIntegration::createPlatformOpenGLContext(QOpenGLC QPlatformOffscreenSurface *QXcbEglIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const { - return new QEGLPbuffer(eglDisplay(), surface->requestedFormat(), surface); + QXcbScreen *screen = static_cast(surface->screen()->handle()); + return new QEGLPbuffer(eglDisplay(), screen->surfaceFormatFor(surface->requestedFormat()), surface); } void *QXcbEglIntegration::xlib_display() const diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglwindow.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglwindow.cpp index 777dfac535..69b7dfbdbf 100644 --- a/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglwindow.cpp +++ b/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglwindow.cpp @@ -59,15 +59,19 @@ QXcbEglWindow::~QXcbEglWindow() eglDestroySurface(m_glIntegration->eglDisplay(), m_surface); } -void QXcbEglWindow::resolveFormat() +void QXcbEglWindow::resolveFormat(const QSurfaceFormat &format) { - m_config = q_configFromGLFormat(m_glIntegration->eglDisplay(), window()->requestedFormat(), true); - m_format = q_glFormatFromConfig(m_glIntegration->eglDisplay(), m_config, m_format); + m_config = q_configFromGLFormat(m_glIntegration->eglDisplay(), format); + m_format = q_glFormatFromConfig(m_glIntegration->eglDisplay(), m_config, format); } -void *QXcbEglWindow::createVisual() -{ #ifdef XCB_USE_XLIB +const xcb_visualtype_t *QXcbEglWindow::createVisual() +{ + QXcbScreen *scr = xcbScreen(); + if (!scr) + return QXcbWindow::createVisual(); + Display *xdpy = static_cast(m_glIntegration->xlib_display()); VisualID id = QXlibEglIntegration::getCompatibleVisualId(xdpy, m_glIntegration->eglDisplay(), m_config); @@ -78,11 +82,12 @@ void *QXcbEglWindow::createVisual() XVisualInfo *visualInfo; int matchingCount = 0; visualInfo = XGetVisualInfo(xdpy, VisualIDMask, &visualInfoTemplate, &matchingCount); - return visualInfo; -#else - return QXcbWindow::createVisual(); -#endif + const xcb_visualtype_t *xcb_visualtype = scr->visualForId(visualInfo->visualid); + XFree(visualInfo); + + return xcb_visualtype; } +#endif void QXcbEglWindow::create() { diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglwindow.h b/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglwindow.h index f36f53d168..48fc6dce70 100644 --- a/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglwindow.h +++ b/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglwindow.h @@ -60,8 +60,11 @@ public: protected: void create() Q_DECL_OVERRIDE; - void resolveFormat() Q_DECL_OVERRIDE; - void *createVisual() Q_DECL_OVERRIDE; + void resolveFormat(const QSurfaceFormat &format) Q_DECL_OVERRIDE; + +#ifdef XCB_USE_XLIB + const xcb_visualtype_t *createVisual() Q_DECL_OVERRIDE; +#endif private: QXcbEglIntegration *m_glIntegration; diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp index 4290ec54fc..5580f81a7a 100644 --- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp +++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp @@ -715,8 +715,8 @@ bool QGLXContext::supportsThreading() QGLXPbuffer::QGLXPbuffer(QOffscreenSurface *offscreenSurface) : QPlatformOffscreenSurface(offscreenSurface) - , m_format(offscreenSurface->requestedFormat()) , m_screen(static_cast(offscreenSurface->screen()->handle())) + , m_format(m_screen->surfaceFormatFor(offscreenSurface->requestedFormat())) , m_pbuffer(0) { GLXFBConfig config = qglx_findConfig(DISPLAY_FROM_XCB(m_screen), m_screen->screenNumber(), m_format); diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.h b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.h index f00d96e6d5..bf1f1b324b 100644 --- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.h +++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.h @@ -106,8 +106,8 @@ public: GLXPbuffer pbuffer() const { return m_pbuffer; } private: - QSurfaceFormat m_format; QXcbScreen *m_screen; + QSurfaceFormat m_format; GLXPbuffer m_pbuffer; }; diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.cpp index a3668df59a..d536121521 100644 --- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.cpp +++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.cpp @@ -189,7 +189,7 @@ QXcbWindow *QXcbGlxIntegration::createWindow(QWindow *window) const QPlatformOpenGLContext *QXcbGlxIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const { QXcbScreen *screen = static_cast(context->screen()->handle()); - QGLXContext *platformContext = new QGLXContext(screen, context->format(), + QGLXContext *platformContext = new QGLXContext(screen, screen->surfaceFormatFor(context->format()), context->shareHandle(), context->nativeHandle()); context->setNativeHandle(platformContext->nativeHandle()); return platformContext; diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxwindow.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxwindow.cpp index 36503f4a7c..8ae83b8084 100644 --- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxwindow.cpp +++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxwindow.cpp @@ -53,17 +53,15 @@ QXcbGlxWindow::~QXcbGlxWindow() { } -void QXcbGlxWindow::resolveFormat() -{ - m_format = window()->requestedFormat(); //qglx_findVisualInfo sets the resovled format -} - -void *QXcbGlxWindow::createVisual() +const xcb_visualtype_t *QXcbGlxWindow::createVisual() { QXcbScreen *scr = xcbScreen(); if (!scr) return Q_NULLPTR; - return qglx_findVisualInfo(DISPLAY_FROM_XCB(scr), scr->screenNumber(), &m_format); + XVisualInfo *visualInfo = qglx_findVisualInfo(DISPLAY_FROM_XCB(scr), scr->screenNumber(), &m_format); + const xcb_visualtype_t *xcb_visualtype = scr->visualForId(visualInfo->visualid); + XFree(visualInfo); + return xcb_visualtype; } QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxwindow.h b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxwindow.h index 1954f972f1..9519245130 100644 --- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxwindow.h +++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxwindow.h @@ -52,8 +52,7 @@ public: ~QXcbGlxWindow(); protected: - void resolveFormat() Q_DECL_OVERRIDE; - void *createVisual() Q_DECL_OVERRIDE; + const xcb_visualtype_t *createVisual() Q_DECL_OVERRIDE; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp index 67a9b2f190..4cb1b29152 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.cpp +++ b/src/plugins/platforms/xcb/qxcbscreen.cpp @@ -47,6 +47,7 @@ #include #include +#include #include #include @@ -359,6 +360,69 @@ void QXcbScreen::windowShown(QXcbWindow *window) } } +QSurfaceFormat QXcbScreen::surfaceFormatFor(const QSurfaceFormat &format) const +{ + const xcb_visualid_t xcb_visualid = connection()->hasDefaultVisualId() ? connection()->defaultVisualId() + : screen()->root_visual; + const xcb_visualtype_t *xcb_visualtype = visualForId(xcb_visualid); + + const int redSize = qPopulationCount(xcb_visualtype->red_mask); + const int greenSize = qPopulationCount(xcb_visualtype->green_mask); + const int blueSize = qPopulationCount(xcb_visualtype->blue_mask); + + QSurfaceFormat result = format; + + if (result.redBufferSize() < 0) + result.setRedBufferSize(redSize); + + if (result.greenBufferSize() < 0) + result.setGreenBufferSize(greenSize); + + if (result.blueBufferSize() < 0) + result.setBlueBufferSize(blueSize); + + return result; +} + +const xcb_visualtype_t *QXcbScreen::visualForFormat(const QSurfaceFormat &format) const +{ + QVector candidates; + + for (auto ii = m_visuals.constBegin(); ii != m_visuals.constEnd(); ++ii) { + const xcb_visualtype_t &xcb_visualtype = ii.value(); + + const int redSize = qPopulationCount(xcb_visualtype.red_mask); + const int greenSize = qPopulationCount(xcb_visualtype.green_mask); + const int blueSize = qPopulationCount(xcb_visualtype.blue_mask); + const int alphaSize = depthOfVisual(xcb_visualtype.visual_id) - redSize - greenSize - blueSize; + + if (format.redBufferSize() != -1 && redSize != format.redBufferSize()) + continue; + + if (format.greenBufferSize() != -1 && greenSize != format.greenBufferSize()) + continue; + + if (format.blueBufferSize() != -1 && blueSize != format.blueBufferSize()) + continue; + + if (format.alphaBufferSize() != -1 && alphaSize != format.alphaBufferSize()) + continue; + + candidates.append(&xcb_visualtype); + } + + if (candidates.isEmpty()) + return nullptr; + + // Try to find a RGB visual rather than e.g. BGR or GBR + for (const xcb_visualtype_t *candidate : qAsConst(candidates)) + if (qCountTrailingZeroBits(candidate->blue_mask) == 0) + return candidate; + + // Did not find anything we like, just grab the first one and hope for the best + return candidates.first(); +} + void QXcbScreen::sendStartupMessage(const QByteArray &message) const { xcb_window_t rootWindow = root(); @@ -403,7 +467,7 @@ quint8 QXcbScreen::depthOfVisual(xcb_visualid_t visualid) const QImage::Format QXcbScreen::format() const { - return QImage::Format_RGB32; + return qt_xcb_imageFormatForVisual(connection(), screen()->root_depth, visualForId(screen()->root_visual)); } QDpi QXcbScreen::virtualDpi() const diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h index 30c5073459..8716af29b5 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.h +++ b/src/plugins/platforms/xcb/qxcbscreen.h @@ -155,6 +155,9 @@ public: QString windowManagerName() const { return m_windowManagerName; } bool syncRequestSupported() const { return m_syncRequestSupported; } + QSurfaceFormat surfaceFormatFor(const QSurfaceFormat &format) const; + + const xcb_visualtype_t *visualForFormat(const QSurfaceFormat &format) const; const xcb_visualtype_t *visualForId(xcb_visualid_t) const; quint8 depthOfVisual(xcb_visualid_t) const; diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 13eecbfb4f..a97420380c 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -382,18 +382,6 @@ void QXcbWindow::create() return; } - const quint32 mask = XCB_CW_BACK_PIXMAP | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_SAVE_UNDER | XCB_CW_EVENT_MASK; - const quint32 values[] = { - // XCB_CW_BACK_PIXMAP - XCB_NONE, - // XCB_CW_OVERRIDE_REDIRECT - type == Qt::Popup || type == Qt::ToolTip || (window()->flags() & Qt::BypassWindowManagerHint), - // XCB_CW_SAVE_UNDER - type == Qt::Popup || type == Qt::Tool || type == Qt::SplashScreen || type == Qt::ToolTip || type == Qt::Drawer, - // XCB_CW_EVENT_MASK - defaultEventMask - }; - // Parameters to XCreateWindow() are frame corner + inner size. // This fits in case position policy is frame inclusive. There is // currently no way to implement it for frame-exclusive geometries. @@ -424,108 +412,76 @@ void QXcbWindow::create() } } - resolveFormat(); - -#ifdef XCB_USE_XLIB - if (window()->surfaceType() != QSurface::RasterSurface - && QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)) { - XVisualInfo *visualInfo = Q_NULLPTR; - if (connection()->hasDefaultVisualId()) - visualInfo = CREATE_VISUALINFO_FROM_DEFAULT_VISUALID(this); - if (!visualInfo) - visualInfo = static_cast(createVisual()); - - if (Q_UNLIKELY(!visualInfo && window()->surfaceType() == QSurface::OpenGLSurface)) - qFatal("Could not initialize OpenGL"); - - if (!visualInfo && window()->surfaceType() == QSurface::RasterGLSurface) { - qWarning("Could not initialize OpenGL for RasterGLSurface, reverting to RasterSurface."); - window()->setSurfaceType(QSurface::RasterSurface); - } - - if (visualInfo) { - m_depth = visualInfo->depth; - m_imageFormat = imageFormatForVisual(visualInfo->depth, visualInfo->red_mask, visualInfo->blue_mask, &m_imageRgbSwap); - Colormap cmap = XCreateColormap(DISPLAY_FROM_XCB(this), xcb_parent_id, visualInfo->visual, AllocNone); + resolveFormat(platformScreen->surfaceFormatFor(window()->requestedFormat())); - XSetWindowAttributes a; - a.background_pixel = WhitePixel(DISPLAY_FROM_XCB(this), platformScreen->screenNumber()); - a.border_pixel = BlackPixel(DISPLAY_FROM_XCB(this), platformScreen->screenNumber()); - a.colormap = cmap; + const xcb_visualtype_t *visual = Q_NULLPTR; - m_visualId = visualInfo->visualid; + if (connection()->hasDefaultVisualId()) { + visual = platformScreen->visualForId(connection()->defaultVisualId()); + if (!visual) + qWarning() << "Failed to use requested visual id."; + } - m_window = XCreateWindow(DISPLAY_FROM_XCB(this), xcb_parent_id, rect.x(), rect.y(), rect.width(), rect.height(), - 0, visualInfo->depth, InputOutput, visualInfo->visual, - CWBackPixel|CWBorderPixel|CWColormap, &a); + if (!visual) + visual = createVisual(); - XFree(visualInfo); - } + if (!visual) { + qWarning() << "Falling back to using screens root_visual."; + visual = platformScreen->visualForId(platformScreen->screen()->root_visual); } -#endif - if (!m_window) - { - m_window = xcb_generate_id(xcb_connection()); - m_visualId = UINT_MAX; - const xcb_visualtype_t *visual = Q_NULLPTR; - m_depth = platformScreen->screen()->root_depth; + Q_ASSERT(visual); - uint32_t mask = 0; - uint32_t values[3]; + m_visualId = visual->visual_id; + m_depth = platformScreen->depthOfVisual(m_visualId); + m_imageFormat = imageFormatForVisual(m_depth, visual->red_mask, visual->blue_mask, &m_imageRgbSwap); + xcb_colormap_t colormap = 0; - if (connection()->hasDefaultVisualId()) { - m_visualId = connection()->defaultVisualId(); - visual = platformScreen->visualForId(m_visualId); - } + quint32 mask = XCB_CW_BACK_PIXMAP + | XCB_CW_BORDER_PIXEL + | XCB_CW_BIT_GRAVITY + | XCB_CW_OVERRIDE_REDIRECT + | XCB_CW_SAVE_UNDER + | XCB_CW_EVENT_MASK; - if (!visual) { - if (connection()->hasDefaultVisualId()) - qWarning("Failed to use default visual id. Falling back to using screens root_visual"); - - m_visualId = platformScreen->screen()->root_visual; - - if (m_format.alphaBufferSize() == 8) { - xcb_depth_iterator_t depthIter = xcb_screen_allowed_depths_iterator(platformScreen->screen()); - while (depthIter.rem) { - if (depthIter.data->depth == 32) { - xcb_visualtype_iterator_t visualIter = xcb_depth_visuals_iterator(depthIter.data); - if (visualIter.rem) { - m_visualId = visualIter.data->visual_id; - m_depth = 32; - uint32_t colormap = xcb_generate_id(xcb_connection()); - xcb_create_colormap(xcb_connection(), XCB_COLORMAP_ALLOC_NONE, colormap, - xcb_parent_id, m_visualId); - mask |= XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | XCB_CW_COLORMAP; - values[0] = platformScreen->screen()->white_pixel; - values[1] = platformScreen->screen()->black_pixel; - values[2] = colormap; - break; - } - } - xcb_depth_next(&depthIter); - } - } + static const bool haveOpenGL = QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL); - visual = platformScreen->visualForId(m_visualId); - } + if ((window()->supportsOpenGL() && haveOpenGL) || m_format.hasAlpha()) { + colormap = xcb_generate_id(xcb_connection()); + Q_XCB_CALL(xcb_create_colormap(xcb_connection(), + XCB_COLORMAP_ALLOC_NONE, + colormap, + xcb_parent_id, + m_visualId)); - m_imageFormat = imageFormatForVisual(m_depth, visual->red_mask, visual->blue_mask, &m_imageRgbSwap); - Q_XCB_CALL(xcb_create_window(xcb_connection(), - m_depth, - m_window, // window id - xcb_parent_id, // parent window id - rect.x(), - rect.y(), - rect.width(), - rect.height(), - 0, // border width - XCB_WINDOW_CLASS_INPUT_OUTPUT, // window class - m_visualId, // visual - mask, - values)); + mask |= XCB_CW_COLORMAP; } + quint32 values[] = { + XCB_BACK_PIXMAP_NONE, + platformScreen->screen()->black_pixel, + XCB_GRAVITY_NORTH_WEST, + type == Qt::Popup || type == Qt::ToolTip || (window()->flags() & Qt::BypassWindowManagerHint), + type == Qt::Popup || type == Qt::Tool || type == Qt::SplashScreen || type == Qt::ToolTip || type == Qt::Drawer, + defaultEventMask, + colormap + }; + + m_window = xcb_generate_id(xcb_connection()); + Q_XCB_CALL(xcb_create_window(xcb_connection(), + m_depth, + m_window, // window id + xcb_parent_id, // parent window id + rect.x(), + rect.y(), + rect.width(), + rect.height(), + 0, // border width + XCB_WINDOW_CLASS_INPUT_OUTPUT, // window class + m_visualId, // visual + mask, + values)); + connection()->addWindowEventListener(m_window, this); Q_XCB_CALL(xcb_change_window_attributes(xcb_connection(), m_window, mask, values)); @@ -2560,6 +2516,12 @@ void QXcbWindow::updateSyncRequestCounter() } } +const xcb_visualtype_t *QXcbWindow::createVisual() +{ + return xcbScreen() ? xcbScreen()->visualForFormat(m_format) + : nullptr; +} + bool QXcbWindow::setKeyboardGrabEnabled(bool grab) { if (grab && !connection()->canGrab()) @@ -2831,3 +2793,4 @@ QXcbScreen *QXcbWindow::xcbScreen() const } QT_END_NAMESPACE + diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index 7b70dc2ef8..9ad0153ca2 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -182,8 +182,8 @@ public Q_SLOTS: void updateSyncRequestCounter(); protected: - virtual void resolveFormat() { m_format = window()->requestedFormat(); } - virtual void *createVisual() { return Q_NULLPTR; } + virtual void resolveFormat(const QSurfaceFormat &format) { m_format = format; } + virtual const xcb_visualtype_t *createVisual(); QXcbScreen *parentScreen(); -- cgit v1.2.3 From b9d386f2ccd69c7f6a766a6d90a6024eeb48e90a Mon Sep 17 00:00:00 2001 From: Louai Al-Khanji Date: Fri, 1 Apr 2016 10:58:29 -0700 Subject: xcb: Optimize non-shm backing store flushing Unfortunately the functions in xcb-image are quite slow, both for the subimage generation and the byte order swapping. xcb_image_subimage is implemented as a pixel by pixel copy, and the xcb byte swapping is done manually without utilizing potential CPU instructions to accelerate the swap. Replace both with their Qt equivalents. Change-Id: I1fe1fe5d9576fdf2bab4a8c401d2a6bb842c2727 Reviewed-by: Lars Knoll Reviewed-by: Laszlo Agocs --- src/plugins/platforms/xcb/qxcbbackingstore.cpp | 109 ++++++++++++++++++++----- 1 file changed, 88 insertions(+), 21 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp index f87ba0db72..844ed8f579 100644 --- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp +++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp @@ -58,6 +58,7 @@ #include #include #include +#include #include QT_BEGIN_NAMESPACE @@ -107,6 +108,7 @@ private: // do a server-side copy on expose instead of sending the pixels every time xcb_pixmap_t m_xcb_pixmap; QRegion m_pendingFlush; + QByteArray m_flushBuffer; bool m_hasAlpha; }; @@ -287,11 +289,84 @@ void QXcbShmImage::ensureGC(xcb_drawable_t dst) } } +static inline void copy_unswapped(char *dst, int dstBytesPerLine, const QImage &img, const QRect &rect) +{ + const uchar *srcData = img.constBits(); + const int srcBytesPerLine = img.bytesPerLine(); + + const int leftOffset = rect.left() * img.depth() >> 3; + const int bottom = rect.bottom() + 1; + + for (int yy = rect.top(); yy < bottom; ++yy) { + const uchar *src = srcData + yy * srcBytesPerLine + leftOffset; + ::memmove(dst, src, dstBytesPerLine); + dst += dstBytesPerLine; + } +} + +template +static inline void copy_swapped(Pixel *dst, const QImage &img, const QRect &rect) +{ + const uchar *srcData = img.constBits(); + const int srcBytesPerLine = img.bytesPerLine(); + + const int left = rect.left(); + const int right = rect.right() + 1; + const int bottom = rect.bottom() + 1; + + for (int yy = rect.top(); yy < bottom; ++yy) { + const Pixel *src = reinterpret_cast(srcData + yy * srcBytesPerLine) + left; + + for (int xx = left; xx < right; ++xx) + *dst++ = qbswap(*src++); + } +} + +static QImage native_sub_image(QByteArray *buffer, const QImage &src, int x, int y, int w, int h, bool swap) +{ + const QRect rect(x, y, w, h); + + if (!swap && src.rect() == rect) + return src; + + const int dstStride = w * src.depth() >> 3; + buffer->resize(h * dstStride); + + if (swap) { + switch (src.depth()) { + case 32: + copy_swapped(reinterpret_cast(buffer->data()), src, rect); + break; + case 16: + copy_swapped(reinterpret_cast(buffer->data()), src, rect); + break; + } + } else { + copy_unswapped(buffer->data(), dstStride, src, rect); + } + + return QImage(reinterpret_cast(buffer->constData()), w, h, dstStride, src.format()); +} + void QXcbShmImage::flushPixmap(const QRegion ®ion) { const QVector rects = m_pendingFlush.intersected(region).rects(); m_pendingFlush -= region; + xcb_image_t xcb_subimage; + memset(&xcb_subimage, 0, sizeof(xcb_image_t)); + + xcb_subimage.format = m_xcb_image->format; + xcb_subimage.scanline_pad = m_xcb_image->scanline_pad; + xcb_subimage.depth = m_xcb_image->depth; + xcb_subimage.bpp = m_xcb_image->bpp; + xcb_subimage.unit = m_xcb_image->unit; + xcb_subimage.plane_mask = m_xcb_image->plane_mask; + xcb_subimage.byte_order = (xcb_image_order_t) connection()->setup()->image_byte_order; + xcb_subimage.bit_order = m_xcb_image->bit_order; + + const bool needsByteSwap = xcb_subimage.byte_order != m_xcb_image->byte_order; + for (const QRect &rect : rects) { // 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. @@ -308,37 +383,29 @@ void QXcbShmImage::flushPixmap(const QRegion ®ion) // 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 = rect.x(); - int src_y = rect.y(); - int target_x = rect.x(); - int target_y = rect.y(); - int width = rect.width(); + const int x = rect.x(); + int y = rect.y(); + const int width = rect.width(); int height = rect.height(); while (height > 0) { - int rows = std::min(height, rows_per_put); + const int rows = std::min(height, rows_per_put); + const QImage subImage = native_sub_image(&m_flushBuffer, m_qimage, x, y, width, rows, needsByteSwap); - xcb_image_t *subimage = xcb_image_subimage(m_xcb_image, src_x, src_y, width, rows, - 0, 0, 0); - - // Convert the image to the native byte order. - xcb_image_t *native_subimage = xcb_image_native(xcb_connection(), subimage, 1); + xcb_subimage.width = width; + xcb_subimage.height = rows; + xcb_subimage.data = const_cast(subImage.constBits()); + xcb_image_annotate(&xcb_subimage); xcb_image_put(xcb_connection(), m_xcb_pixmap, m_gc, - native_subimage, - target_x, - target_y, + &xcb_subimage, + x, + y, 0); - if (native_subimage != subimage) - xcb_image_destroy(native_subimage); - - xcb_image_destroy(subimage); - - src_y += rows; - target_y += rows; + y += rows; height -= rows; } } -- cgit v1.2.3