diff --git a/src/gui/platform/darwin/qappleiconengine.mm b/src/gui/platform/darwin/qappleiconengine.mm index 4dd8e42124..d99da6da84 100644 --- a/src/gui/platform/darwin/qappleiconengine.mm +++ b/src/gui/platform/darwin/qappleiconengine.mm @@ -397,26 +397,26 @@ auto *configuredImage(const UIImage *image, const QColor &color) QPixmap QAppleIconEngine::scaledPixmap(const QSize &size, QIcon::Mode mode, QIcon::State state, qreal scale) { - const quint64 cacheKey = calculateCacheKey(mode, state); - if (cacheKey != m_cacheKey || m_pixmap.size() != size || m_pixmap.devicePixelRatio() != scale) { + const CacheKey key(mode, state, size, scale); + QPixmap pixmap = m_cache.value(key); + if (pixmap.isNull()) { const QSize paintSize = actualSize(size, mode, state); const QSize paintOffset = paintSize != size ? (QSizeF(size - paintSize) * 0.5).toSize() : QSize(); - m_pixmap = QPixmap(size * scale); - m_pixmap.setDevicePixelRatio(scale); - m_pixmap.fill(Qt::transparent); + pixmap = QPixmap(size * scale); + pixmap.setDevicePixelRatio(scale); + pixmap.fill(Qt::transparent); - if (!m_pixmap.isNull()) { - QPainter painter(&m_pixmap); + if (!pixmap.isNull()) { + QPainter painter(&pixmap); paint(&painter, QRect(paintOffset.width(), paintOffset.height(), - paintSize.width(), paintSize.height()), mode, state); + paintSize.width(), paintSize.height()), mode, state); + m_cache.insert(key, pixmap); } - - m_cacheKey = cacheKey; } - return m_pixmap; + return pixmap; } void QAppleIconEngine::paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state) diff --git a/src/gui/platform/darwin/qappleiconengine_p.h b/src/gui/platform/darwin/qappleiconengine_p.h index 2a4ff7fc64..d99c60ffc5 100644 --- a/src/gui/platform/darwin/qappleiconengine_p.h +++ b/src/gui/platform/darwin/qappleiconengine_p.h @@ -17,6 +17,8 @@ #include +#include + #include Q_FORWARD_DECLARE_OBJC_CLASS(UIImage); @@ -43,19 +45,31 @@ public: static QList availableIconSizes(double aspectRatio = 1.0); private: - static constexpr quint64 calculateCacheKey(QIcon::Mode mode, QIcon::State state) - { - return (quint64(mode) << 32) | state; - } - const QString m_iconName; #if defined(Q_OS_MACOS) const NSImage *m_image; #elif defined(QT_PLATFORM_UIKIT) const UIImage *m_image; #endif - mutable QPixmap m_pixmap; - mutable quint64 m_cacheKey = {}; + struct CacheKey { + constexpr CacheKey(QIcon::Mode mode, QIcon::State state, QSize size, qreal scale) noexcept + : modeAndState((quint64(mode) << 32) | state), size(size), scale(scale) + {} + + quint64 modeAndState; + QSize size; + qreal scale; + + friend constexpr bool operator==(const CacheKey &lhs, const CacheKey &rhs) noexcept + { + return lhs.modeAndState == rhs.modeAndState + && lhs.size == rhs.size + && lhs.scale == rhs.scale; + } + friend constexpr size_t qHash(const CacheKey &key, size_t seed) noexcept + { return qHashMulti(seed, key.modeAndState, key.size, key.scale); } + }; + mutable QHash m_cache; };