diff options
author | Friedemann Kleint <Friedemann.Kleint@digia.com> | 2013-10-01 15:00:55 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-10-02 10:43:55 +0200 |
commit | 5ad1e2578bb3eaa7da6aefa1f96d79947216d509 (patch) | |
tree | 6d4289e3058703662767b2a21908689d0513fdc7 /src | |
parent | 8388b40108eb3f78531dac2af07eef0e89a44c03 (diff) |
Windows/Linux: Cache cursors by mask/pixmap keys and shape.
Task-number: QTBUG-33383
Change-Id: I65a5a0870f50f42c26a4d297331224b3597a36e0
Reviewed-by: Andy Shaw <andy.shaw@digia.com>
Reviewed-by: Shawn Rutledge <shawn.rutledge@digia.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/platforms/windows/qwindowscursor.cpp | 41 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowscursor.h | 27 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbcursor.cpp | 40 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbcursor.h | 30 |
4 files changed, 111 insertions, 27 deletions
diff --git a/src/plugins/platforms/windows/qwindowscursor.cpp b/src/plugins/platforms/windows/qwindowscursor.cpp index 5b2a3acbae..5e7944a4cf 100644 --- a/src/plugins/platforms/windows/qwindowscursor.cpp +++ b/src/plugins/platforms/windows/qwindowscursor.cpp @@ -45,7 +45,7 @@ #include "qwindowswindow.h" #include "qwindowsscreen.h" -#include <QtGui/QPixmap> +#include <QtGui/QBitmap> #include <QtGui/QImage> #include <QtGui/QBitmap> #include <QtGui/QGuiApplication> @@ -61,6 +61,30 @@ Q_GUI_EXPORT HBITMAP qt_pixmapToWinHBITMAP(const QPixmap &p, int hbitmapFormat = Q_GUI_EXPORT HBITMAP qt_createIconMask(const QBitmap &bitmap); /*! + \class QWindowsCursorCacheKey + \brief Cache key for storing values in a QHash with a QCursor as key. + + \internal + \ingroup qt-lighthouse-win +*/ + +QWindowsCursorCacheKey::QWindowsCursorCacheKey(const QCursor &c) + : shape(c.shape()), bitmapCacheKey(0), maskCacheKey(0) +{ + if (shape == Qt::BitmapCursor) { + const qint64 pixmapCacheKey = c.pixmap().cacheKey(); + if (pixmapCacheKey) { + bitmapCacheKey = pixmapCacheKey; + } else { + Q_ASSERT(c.bitmap()); + Q_ASSERT(c.mask()); + bitmapCacheKey = c.bitmap()->cacheKey(); + maskCacheKey = c.mask()->cacheKey(); + } + } +} + +/*! \class QWindowsCursor \brief Platform cursor implementation @@ -388,9 +412,10 @@ HCURSOR QWindowsCursor::createSystemCursor(const QCursor &c) QWindowsWindowCursor QWindowsCursor::standardWindowCursor(Qt::CursorShape shape) { - StandardCursorCache::iterator it = m_standardCursorCache.find(shape); - if (it == m_standardCursorCache.end()) - it = m_standardCursorCache.insert(shape, QWindowsWindowCursor(QCursor(shape))); + const QWindowsCursorCacheKey key(shape); + CursorCache::iterator it = m_cursorCache.find(key); + if (it == m_cursorCache.end()) + it = m_cursorCache.insert(key, QWindowsWindowCursor(QCursor(shape))); return it.value(); } @@ -400,10 +425,10 @@ QWindowsWindowCursor QWindowsCursor::standardWindowCursor(Qt::CursorShape shape) QWindowsWindowCursor QWindowsCursor::pixmapWindowCursor(const QCursor &c) { - const qint64 cacheKey = c.pixmap().cacheKey(); - PixmapCursorCache::iterator it = m_pixmapCursorCache.find(cacheKey); - if (it == m_pixmapCursorCache.end()) - it = m_pixmapCursorCache.insert(cacheKey, QWindowsWindowCursor(c)); + const QWindowsCursorCacheKey cacheKey(c); + CursorCache::iterator it = m_cursorCache.find(cacheKey); + if (it == m_cursorCache.end()) + it = m_cursorCache.insert(cacheKey, QWindowsWindowCursor(c)); return it.value(); } diff --git a/src/plugins/platforms/windows/qwindowscursor.h b/src/plugins/platforms/windows/qwindowscursor.h index 1e818bc9b8..b366d9a06a 100644 --- a/src/plugins/platforms/windows/qwindowscursor.h +++ b/src/plugins/platforms/windows/qwindowscursor.h @@ -52,6 +52,27 @@ QT_BEGIN_NAMESPACE class QWindowsWindowCursorData; +struct QWindowsCursorCacheKey +{ + explicit QWindowsCursorCacheKey(const QCursor &c); + explicit QWindowsCursorCacheKey(Qt::CursorShape s) : shape(s), bitmapCacheKey(0), maskCacheKey(0) {} + QWindowsCursorCacheKey() : shape(Qt::CustomCursor), bitmapCacheKey(0), maskCacheKey(0) {} + + Qt::CursorShape shape; + qint64 bitmapCacheKey; + qint64 maskCacheKey; +}; + +inline bool operator==(const QWindowsCursorCacheKey &k1, const QWindowsCursorCacheKey &k2) +{ + return k1.shape == k2.shape && k1.bitmapCacheKey == k2.bitmapCacheKey && k1.maskCacheKey == k2.maskCacheKey; +} + +inline uint qHash(const QWindowsCursorCacheKey &k, uint seed) Q_DECL_NOTHROW +{ + return (uint(k.shape) + uint(k.bitmapCacheKey) + uint(k.maskCacheKey)) ^ seed; +} + class QWindowsWindowCursor { public: @@ -86,11 +107,9 @@ public: QWindowsWindowCursor pixmapWindowCursor(const QCursor &c); private: - typedef QHash<Qt::CursorShape, QWindowsWindowCursor> StandardCursorCache; - typedef QHash<qint64, QWindowsWindowCursor> PixmapCursorCache; + typedef QHash<QWindowsCursorCacheKey, QWindowsWindowCursor> CursorCache; - StandardCursorCache m_standardCursorCache; - PixmapCursorCache m_pixmapCursorCache; + CursorCache m_cursorCache; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/qxcbcursor.cpp b/src/plugins/platforms/xcb/qxcbcursor.cpp index 756c3c22dd..11848d503b 100644 --- a/src/plugins/platforms/xcb/qxcbcursor.cpp +++ b/src/plugins/platforms/xcb/qxcbcursor.cpp @@ -272,6 +272,26 @@ static const char * const cursorNames[] = { "link" }; +#ifndef QT_NO_CURSOR + +QXcbCursorCacheKey::QXcbCursorCacheKey(const QCursor &c) + : shape(c.shape()), bitmapCacheKey(0), maskCacheKey(0) +{ + if (shape == Qt::BitmapCursor) { + const qint64 pixmapCacheKey = c.pixmap().cacheKey(); + if (pixmapCacheKey) { + bitmapCacheKey = pixmapCacheKey; + } else { + Q_ASSERT(c.bitmap()); + Q_ASSERT(c.mask()); + bitmapCacheKey = c.bitmap()->cacheKey(); + maskCacheKey = c.mask()->cacheKey(); + } + } +} + +#endif // !QT_NO_CURSOR + QXcbCursor::QXcbCursor(QXcbConnection *conn, QXcbScreen *screen) : QXcbObject(conn), m_screen(screen), m_gtkCursorThemeInitialized(false) { @@ -318,9 +338,7 @@ QXcbCursor::~QXcbCursor() if (!--cursorCount) xcb_close_font(conn, cursorFont); - foreach (xcb_cursor_t cursor, m_bitmapCursorMap) - xcb_free_cursor(conn, cursor); - foreach (xcb_cursor_t cursor, m_shapeCursorMap) + foreach (xcb_cursor_t cursor, m_cursorHash) xcb_free_cursor(conn, cursor); } @@ -336,17 +354,13 @@ void QXcbCursor::changeCursor(QCursor *cursor, QWindow *widget) xcb_cursor_t c = XCB_CURSOR_NONE; if (cursor) { - if (cursor->shape() == Qt::BitmapCursor) { - qint64 id = cursor->pixmap().cacheKey(); - if (!m_bitmapCursorMap.contains(id)) - m_bitmapCursorMap.insert(id, createBitmapCursor(cursor)); - c = m_bitmapCursorMap.value(id); - } else { - int id = cursor->shape(); - if (!m_shapeCursorMap.contains(id)) - m_shapeCursorMap.insert(id, createFontCursor(cursor->shape())); - c = m_shapeCursorMap.value(id); + const QXcbCursorCacheKey key(*cursor); + CursorHash::iterator it = m_cursorHash.find(key); + if (it == m_cursorHash.end()) { + const Qt::CursorShape shape = cursor->shape(); + it = m_cursorHash.insert(key, shape == Qt::BitmapCursor ? createBitmapCursor(cursor) : createFontCursor(shape)); } + c = it.value(); } w->setCursor(c); diff --git a/src/plugins/platforms/xcb/qxcbcursor.h b/src/plugins/platforms/xcb/qxcbcursor.h index 081300868c..f224aae4e0 100644 --- a/src/plugins/platforms/xcb/qxcbcursor.h +++ b/src/plugins/platforms/xcb/qxcbcursor.h @@ -47,6 +47,31 @@ QT_BEGIN_NAMESPACE +#ifndef QT_NO_CURSOR + +struct QXcbCursorCacheKey +{ + explicit QXcbCursorCacheKey(const QCursor &c); + explicit QXcbCursorCacheKey(Qt::CursorShape s) : shape(s), bitmapCacheKey(0), maskCacheKey(0) {} + QXcbCursorCacheKey() : shape(Qt::CustomCursor), bitmapCacheKey(0), maskCacheKey(0) {} + + Qt::CursorShape shape; + qint64 bitmapCacheKey; + qint64 maskCacheKey; +}; + +inline bool operator==(const QXcbCursorCacheKey &k1, const QXcbCursorCacheKey &k2) +{ + return k1.shape == k2.shape && k1.bitmapCacheKey == k2.bitmapCacheKey && k1.maskCacheKey == k2.maskCacheKey; +} + +inline uint qHash(const QXcbCursorCacheKey &k, uint seed) Q_DECL_NOTHROW +{ + return (uint(k.shape) + uint(k.bitmapCacheKey) + uint(k.maskCacheKey)) ^ seed; +} + +#endif // !QT_NO_CURSOR + class QXcbCursor : public QXcbObject, public QPlatformCursor { public: @@ -62,6 +87,8 @@ public: private: #ifndef QT_NO_CURSOR + typedef QHash<QXcbCursorCacheKey, xcb_cursor_t> CursorHash; + xcb_cursor_t createFontCursor(int cshape); xcb_cursor_t createBitmapCursor(QCursor *cursor); xcb_cursor_t createNonStandardCursor(int cshape); @@ -69,8 +96,7 @@ private: QXcbScreen *m_screen; #ifndef QT_NO_CURSOR - QMap<int, xcb_cursor_t> m_shapeCursorMap; - QMap<qint64, xcb_cursor_t> m_bitmapCursorMap; + CursorHash m_cursorHash; #endif #ifdef XCB_USE_XLIB static void cursorThemePropertyChanged(QXcbScreen *screen, |