summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@digia.com>2013-10-01 15:00:55 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-10-02 10:43:55 +0200
commit5ad1e2578bb3eaa7da6aefa1f96d79947216d509 (patch)
tree6d4289e3058703662767b2a21908689d0513fdc7
parent8388b40108eb3f78531dac2af07eef0e89a44c03 (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>
-rw-r--r--src/plugins/platforms/windows/qwindowscursor.cpp41
-rw-r--r--src/plugins/platforms/windows/qwindowscursor.h27
-rw-r--r--src/plugins/platforms/xcb/qxcbcursor.cpp40
-rw-r--r--src/plugins/platforms/xcb/qxcbcursor.h30
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,