diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2018-04-15 01:00:18 +0200 |
---|---|---|
committer | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2018-04-15 01:00:18 +0200 |
commit | 4aa6f54fec9d199f97759945118451c52767b2ce (patch) | |
tree | 5dc695cd4718437b5015aaef3a02463c61bc5dc2 /src/plugins/platforms | |
parent | 369e7572bac94bb5b83ef881012fdc4a86829496 (diff) | |
parent | d5ac11891d8237ca2f02390ffd0ff103578b520e (diff) |
Merge remote-tracking branch 'origin/5.11' into dev
Change-Id: I8c353b4c53e90434453c76691eac39a894d23b49
Diffstat (limited to 'src/plugins/platforms')
-rw-r--r-- | src/plugins/platforms/winrt/qwinrteglcontext.cpp | 6 | ||||
-rw-r--r-- | src/plugins/platforms/winrt/qwinrteglcontext.h | 1 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbbackingstore.cpp | 14 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbconnection.cpp | 11 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbconnection.h | 10 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbcursor.cpp | 57 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbcursor.h | 16 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbwindow.cpp | 22 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbwindow.h | 3 |
9 files changed, 81 insertions, 59 deletions
diff --git a/src/plugins/platforms/winrt/qwinrteglcontext.cpp b/src/plugins/platforms/winrt/qwinrteglcontext.cpp index 8a250c516a..eeb79be2e6 100644 --- a/src/plugins/platforms/winrt/qwinrteglcontext.cpp +++ b/src/plugins/platforms/winrt/qwinrteglcontext.cpp @@ -354,6 +354,12 @@ QFunctionPointer QWinRTEGLContext::getProcAddress(const char *procName) return eglGetProcAddress(procName); } +bool QWinRTEGLContext::isValid() const +{ + Q_D(const QWinRTEGLContext); + return d->eglContext != EGL_NO_CONTEXT; +} + EGLDisplay QWinRTEGLContext::display() { return g->eglDisplay; diff --git a/src/plugins/platforms/winrt/qwinrteglcontext.h b/src/plugins/platforms/winrt/qwinrteglcontext.h index 5c75aa90d0..325dc82c40 100644 --- a/src/plugins/platforms/winrt/qwinrteglcontext.h +++ b/src/plugins/platforms/winrt/qwinrteglcontext.h @@ -60,6 +60,7 @@ public: QSurfaceFormat format() const override; QFunctionPointer getProcAddress(const char *procName) override; + bool isValid() const override; static EGLDisplay display(); private: diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp index 659d1c53cb..8cfcc49f9a 100644 --- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp +++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp @@ -219,12 +219,14 @@ void QXcbBackingStoreImage::create(const QSize &size, const xcb_format_t *fmt, Q if (!segmentSize) return; - if (hasShm() && m_segmentSize > 0 && (m_segmentSize < segmentSize || m_segmentSize / 2 >= segmentSize)) - destroyShmSegment(m_segmentSize); - if (!hasShm() && connection()->hasShm()) - { - qCDebug(lcQpaXcb) << "creating shared memory" << segmentSize << "for" << size << "depth" << fmt->depth << "bits" << fmt->bits_per_pixel; - createShmSegment(segmentSize); + if (connection()->hasShm()) { + if (m_shm_info.shmaddr && (m_segmentSize < segmentSize || m_segmentSize / 2 >= segmentSize)) + destroyShmSegment(m_segmentSize); + if (!m_shm_info.shmaddr) { + qCDebug(lcQpaXcb) << "creating shared memory" << segmentSize << "for" + << size << "depth" << fmt->depth << "bits" << fmt->bits_per_pixel; + createShmSegment(segmentSize); + } } m_xcb_image->data = m_shm_info.shmaddr ? m_shm_info.shmaddr : (uint8_t *)malloc(segmentSize); diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 94dbb76117..6f1a3e3c19 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -2109,17 +2109,22 @@ void QXcbConnection::initializeXRender() { #if QT_CONFIG(xcb_render) const xcb_query_extension_reply_t *reply = xcb_get_extension_data(m_connection, &xcb_render_id); - if (!reply || !reply->present) + if (!reply || !reply->present) { + qCDebug(lcQpaXcb, "XRender extension not present on the X server"); return; + } auto xrender_query = Q_XCB_REPLY(xcb_render_query_version, m_connection, XCB_RENDER_MAJOR_VERSION, XCB_RENDER_MINOR_VERSION); - if (!xrender_query || (xrender_query->major_version == 0 && xrender_query->minor_version < 5)) { - qWarning("QXcbConnection: Failed to initialize XRender"); + if (!xrender_query) { + qCWarning(lcQpaXcb, "xcb_render_query_version failed"); return; } + has_render_extension = true; + m_xrenderVersion.first = xrender_query->major_version; + m_xrenderVersion.second = xrender_query->minor_version; #endif } diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index 9e16d15b20..3b42d7cf22 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -464,7 +464,13 @@ public: bool hasXRandr() const { return has_randr_extension; } bool hasInputShape() const { return has_input_shape; } bool hasXKB() const { return has_xkb; } - bool hasXRender() const { return has_render_extension; } + bool hasXRender(int major = -1, int minor = -1) const + { + if (has_render_extension && major != -1 && minor != -1) + return m_xrenderVersion >= qMakePair(major, minor); + + return has_render_extension; + } bool hasXInput2() const { return m_xi2Enabled; } bool hasShm() const { return has_shm; } bool hasShmFd() const { return has_shm_fd; } @@ -685,6 +691,8 @@ private: bool has_shm = false; bool has_shm_fd = false; + QPair<int, int> m_xrenderVersion; + Qt::MouseButtons m_buttonState = 0; Qt::MouseButton m_button = Qt::NoButton; diff --git a/src/plugins/platforms/xcb/qxcbcursor.cpp b/src/plugins/platforms/xcb/qxcbcursor.cpp index 34b7d0d236..8d151b760b 100644 --- a/src/plugins/platforms/xcb/qxcbcursor.cpp +++ b/src/plugins/platforms/xcb/qxcbcursor.cpp @@ -301,6 +301,9 @@ QXcbCursorCacheKey::QXcbCursorCacheKey(const QCursor &c) QXcbCursor::QXcbCursor(QXcbConnection *conn, QXcbScreen *screen) : QXcbObject(conn), m_screen(screen), m_gtkCursorThemeInitialized(false) { + // see NUM_BITMAPS in libXcursor/src/xcursorint.h + m_bitmapCache.setMaxCost(8); + if (cursorCount++) return; @@ -351,37 +354,38 @@ QXcbCursor::~QXcbCursor() } #ifndef QT_NO_CURSOR -void QXcbCursor::changeCursor(QCursor *cursor, QWindow *widget) +void QXcbCursor::changeCursor(QCursor *cursor, QWindow *window) { - QXcbWindow *w = 0; - if (widget && widget->handle()) - w = static_cast<QXcbWindow *>(widget->handle()); - else - // No X11 cursor control when there is no widget under the cursor + if (!window || !window->handle()) return; xcb_cursor_t c = XCB_CURSOR_NONE; - bool isBitmapCursor = false; - if (cursor) { + const QXcbCursorCacheKey key(*cursor); const Qt::CursorShape shape = cursor->shape(); - isBitmapCursor = shape == Qt::BitmapCursor; - if (!isBitmapCursor) { - const QXcbCursorCacheKey key(*cursor); - CursorHash::iterator it = m_cursorHash.find(key); - if (it == m_cursorHash.end()) { - it = m_cursorHash.insert(key, createFontCursor(shape)); + if (shape == Qt::BitmapCursor) { + auto *bitmap = m_bitmapCache.object(key); + if (bitmap) { + c = bitmap->cursor; + } else { + c = createBitmapCursor(cursor); + m_bitmapCache.insert(key, new CachedCursor(xcb_connection(), c)); } - c = it.value(); } else { - // Do not cache bitmap cursors, as otherwise they have unclear - // lifetime (we effectively leak xcb_cursor_t). - c = createBitmapCursor(cursor); + auto it = m_cursorHash.find(key); + if (it == m_cursorHash.end()) { + c = createFontCursor(shape); + m_cursorHash.insert(key, c); + } else { + c = it.value(); + } } } - w->setCursor(c, isBitmapCursor); + auto *w = static_cast<QXcbWindow *>(window->handle()); + xcb_change_window_attributes(xcb_connection(), w->xcb_window(), XCB_CW_CURSOR, &c); + xcb_flush(xcb_connection()); } static int cursorIdForShape(int cshape) @@ -597,12 +601,19 @@ xcb_cursor_t QXcbCursor::createFontCursor(int cshape) xcb_cursor_t QXcbCursor::createBitmapCursor(QCursor *cursor) { - xcb_connection_t *conn = xcb_connection(); QPoint spot = cursor->hotSpot(); xcb_cursor_t c = XCB_NONE; - if (cursor->pixmap().depth() > 1) - c = qt_xcb_createCursorXRender(m_screen, cursor->pixmap().toImage(), spot); - if (!c) { + if (cursor->pixmap().depth() > 1) { +#if QT_CONFIG(xcb_render) + if (connection()->hasXRender(0, 5)) + c = qt_xcb_createCursorXRender(m_screen, cursor->pixmap().toImage(), spot); + else + qCWarning(lcQpaXcb, "xrender >= 0.5 required to create pixmap cursors"); +#else + qCWarning(lcQpaXcb, "This build of Qt does not support pixmap cursors"); +#endif + } else { + xcb_connection_t *conn = xcb_connection(); xcb_pixmap_t cp = qt_xcb_XPixmapFromBitmap(m_screen, cursor->bitmap()->toImage()); xcb_pixmap_t mp = qt_xcb_XPixmapFromBitmap(m_screen, cursor->mask()->toImage()); c = xcb_generate_id(conn); diff --git a/src/plugins/platforms/xcb/qxcbcursor.h b/src/plugins/platforms/xcb/qxcbcursor.h index e3f88518fe..5bc806381c 100644 --- a/src/plugins/platforms/xcb/qxcbcursor.h +++ b/src/plugins/platforms/xcb/qxcbcursor.h @@ -43,6 +43,8 @@ #include <qpa/qplatformcursor.h> #include "qxcbscreen.h" +#include <QtCore/QCache> + QT_BEGIN_NAMESPACE #ifndef QT_NO_CURSOR @@ -76,7 +78,7 @@ public: QXcbCursor(QXcbConnection *conn, QXcbScreen *screen); ~QXcbCursor(); #ifndef QT_NO_CURSOR - void changeCursor(QCursor *cursor, QWindow *widget) override; + void changeCursor(QCursor *cursor, QWindow *window) override; #endif QPoint pos() const override; void setPos(const QPoint &pos) override; @@ -89,9 +91,20 @@ public: #endif private: + #ifndef QT_NO_CURSOR typedef QHash<QXcbCursorCacheKey, xcb_cursor_t> CursorHash; + struct CachedCursor + { + explicit CachedCursor(xcb_connection_t *conn, xcb_cursor_t c) + : cursor(c), connection(conn) {} + ~CachedCursor() { xcb_free_cursor(connection, cursor); } + xcb_cursor_t cursor; + xcb_connection_t *connection; + }; + typedef QCache<QXcbCursorCacheKey, CachedCursor> BitmapCursorCache; + xcb_cursor_t createFontCursor(int cshape); xcb_cursor_t createBitmapCursor(QCursor *cursor); xcb_cursor_t createNonStandardCursor(int cshape); @@ -100,6 +113,7 @@ private: QXcbScreen *m_screen; #ifndef QT_NO_CURSOR CursorHash m_cursorHash; + BitmapCursorCache m_bitmapCache; #endif #if QT_CONFIG(xcb_xlib) && QT_CONFIG(library) static void cursorThemePropertyChanged(QXcbVirtualDesktop *screen, diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index a19d69af41..01eb88eea7 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -560,10 +560,6 @@ void QXcbWindow::create() QXcbWindow::~QXcbWindow() { - if (m_currentBitmapCursor != XCB_CURSOR_NONE) { - xcb_free_cursor(xcb_connection(), m_currentBitmapCursor); - } - destroy(); } @@ -2591,24 +2587,6 @@ bool QXcbWindow::setMouseGrabEnabled(bool grab) return result; } -void QXcbWindow::setCursor(xcb_cursor_t cursor, bool isBitmapCursor) -{ - xcb_connection_t *conn = xcb_connection(); - - xcb_change_window_attributes(conn, m_window, XCB_CW_CURSOR, &cursor); - xcb_flush(conn); - - if (m_currentBitmapCursor != XCB_CURSOR_NONE) { - xcb_free_cursor(conn, m_currentBitmapCursor); - } - - if (isBitmapCursor) { - m_currentBitmapCursor = cursor; - } else { - m_currentBitmapCursor = XCB_CURSOR_NONE; - } -} - void QXcbWindow::windowEvent(QEvent *event) { switch (event->type()) { diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index a1f1540466..edfee1f574 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -103,8 +103,6 @@ public: bool setKeyboardGrabEnabled(bool grab) override; bool setMouseGrabEnabled(bool grab) override; - void setCursor(xcb_cursor_t cursor, bool isBitmapCursor); - QSurfaceFormat format() const override; void windowEvent(QEvent *event) override; @@ -285,7 +283,6 @@ protected: SyncState m_syncState = NoSyncNeeded; QXcbSyncWindowRequest *m_pendingSyncRequest = nullptr; - xcb_cursor_t m_currentBitmapCursor = XCB_CURSOR_NONE; }; class QXcbForeignWindow : public QXcbWindow |