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>bb10
parent
8388b40108
commit
5ad1e2578b
|
|
@ -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>
|
||||
|
|
@ -60,6 +60,30 @@ QT_BEGIN_NAMESPACE
|
|||
Q_GUI_EXPORT HBITMAP qt_pixmapToWinHBITMAP(const QPixmap &p, int hbitmapFormat = 0);
|
||||
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();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Reference in New Issue