change the QPixmapCache key type to QByteArray from QString

QString is 2x the size of QByteArray (in terms of memory allocated)

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2024-03-28 10:44:16 +02:00
parent 32d252d3cf
commit cf1b19860d
17 changed files with 71 additions and 77 deletions

View file

@ -1295,7 +1295,7 @@ void QGraphicsItemPrivate::initStyleOption(QStyleOptionGraphicsItem *option, con
void QGraphicsItemCache::purge()
{
QPixmapCache::remove(key);
key = QPixmapCache::Key();
key = QByteArray();
foreach (const DeviceData &data, deviceData) {
QPixmapCache::remove(data.key);
}

View file

@ -51,14 +51,14 @@ public:
// ItemCoordinateCache only
QRect boundingRect;
QSize fixedSize;
QPixmapCache::Key key;
QByteArray key;
// DeviceCoordinateCache only
struct DeviceData {
DeviceData() {}
QTransform lastTransform;
QPoint cacheIndent;
QPixmapCache::Key key;
QByteArray key;
};
QMap<QPaintDevice *, DeviceData> deviceData;

View file

@ -4229,7 +4229,7 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte
return;
// Fetch the off-screen transparent buffer and exposed area info.
QPixmapCache::Key pixmapKey;
QByteArray pixmapKey;
QPixmap pix;
bool pixmapFound;
QGraphicsItemCache *itemCache = itemd->extraItemCache();

View file

@ -223,7 +223,7 @@ QPixmap QPixmapIconEngine::pixmap(const QSize &size, QIcon::Mode mode, QIcon::St
if (!actualSize.isNull() && (actualSize.width() > size.width() || actualSize.height() > size.height()))
actualSize.scale(size, Qt::KeepAspectRatio);
const QString key = qHexString(
const QByteArray key = qHexString(
"qt_icon_%lld_%d_%lld_%d_%d",
pm.cacheKey(),
static_cast<int>(pe ? pe->mode : QIcon::Normal),
@ -231,12 +231,12 @@ QPixmap QPixmapIconEngine::pixmap(const QSize &size, QIcon::Mode mode, QIcon::St
actualSize.width(),
actualSize.height()
);
const QString key2 = key + QLatin1Char('_') + QChar(static_cast<uint>(mode));
const QByteArray key2 = key + '_' + static_cast<char>(mode);
if (mode == QIcon::Active) {
if (QPixmapCache::find(key2, pm))
return pm; // horray
const QString key3 = key + QLatin1Char('_') + QChar(static_cast<uint>(QIcon::Normal));
const QByteArray key3 = key + '_' + static_cast<char>(QIcon::Normal);
if (QPixmapCache::find(key + key3, pm)) {
QStyleOption opt(0);
opt.palette = QApplication::palette();

View file

@ -429,7 +429,7 @@ QPixmap QIconLoaderEngineEntry::pixmap(const QSize &size, QIcon::Mode mode, QIco
}
int actualSize = qMin(size.width(), size.height());
const QString key = qHexString(
const QByteArray key = qHexString(
"qt_theme_%lld_%d_%lld_%d",
m_basePixmap.cacheKey(),
static_cast<int>(mode),

View file

@ -561,12 +561,12 @@ bool QPixmap::load(const QString &fileName, const char *format, Qt::ImageConvers
return false;
QFileInfo info(fileName);
const QString key = qHexString(
const QByteArray key = qHexString(
"qt_pixmap_%lld_%lld_%d_",
info.lastModified().toTime_t(),
info.size(),
static_cast<int>(data ? data->pixelType() : QPixmapData::PixmapType)
) + info.absoluteFilePath();
) + QFile::encodeName(info.absoluteFilePath());
// Note: If no extension is provided, we try to match the
// file against known plugin extensions

View file

@ -66,7 +66,7 @@ QT_BEGIN_NAMESPACE
static int cache_limit = 10240; // 10 MB cache limit for desktop
typedef QCache<QString, QPixmap> PixmapCacheType;
typedef QCache<QByteArray, QPixmap> PixmapCacheType;
Q_GLOBAL_STATIC(PixmapCacheType, pm_cache)
/*!
@ -79,13 +79,13 @@ Q_GLOBAL_STATIC(PixmapCacheType, pm_cache)
\warning If valid, you should copy the pixmap immediately (this is
fast). Subsequent insertions into the cache could cause the
pointer to become invalid. For this reason, we recommend you use
bool find(const QString&, QPixmap*) instead.
bool find(const QByteArray&, QPixmap*) instead.
Example:
\snippet doc/src/snippets/code/src_gui_image_qpixmapcache.cpp 0
*/
QPixmap *QPixmapCache::find(const QString &key)
QPixmap *QPixmapCache::find(const QByteArray &key)
{
return pm_cache()->object(key);
}
@ -93,9 +93,9 @@ QPixmap *QPixmapCache::find(const QString &key)
/*!
\obsolete
\fn QPixmapCache::find(const QString &key, QPixmap& pixmap)
\fn QPixmapCache::find(const QByteArray &key, QPixmap& pixmap)
Use bool find(const QString&, QPixmap*) instead.
Use bool find(const QByteArray&, QPixmap*) instead.
*/
/*!
@ -109,7 +109,7 @@ QPixmap *QPixmapCache::find(const QString &key)
\snippet doc/src/snippets/code/src_gui_image_qpixmapcache.cpp 1
*/
bool QPixmapCache::find(const QString &key, QPixmap* pixmap)
bool QPixmapCache::find(const QByteArray &key, QPixmap* pixmap)
{
QPixmap *ptr = pm_cache()->object(key);
if (ptr && pixmap)
@ -137,7 +137,7 @@ bool QPixmapCache::find(const QString &key, QPixmap* pixmap)
\sa setCacheLimit()
*/
bool QPixmapCache::insert(const QString &key, const QPixmap &pixmap)
bool QPixmapCache::insert(const QByteArray &key, const QPixmap &pixmap)
{
return pm_cache()->insert(key, new QPixmap(pixmap));
}
@ -157,10 +157,10 @@ bool QPixmapCache::insert(const QString &key, const QPixmap &pixmap)
\since 4.6
*/
QPixmapCache::Key QPixmapCache::insert(const QPixmap &pixmap)
QByteArray QPixmapCache::insert(const QPixmap &pixmap)
{
QPixmap *cpixmap = new QPixmap(pixmap);
QString key = QString::number(cpixmap->cacheKey());
const QByteArray key = QByteArray::number(cpixmap->cacheKey());
pm_cache()->insert(key, cpixmap);
return key;
}
@ -174,7 +174,7 @@ QPixmapCache::Key QPixmapCache::insert(const QPixmap &pixmap)
\since 4.6
*/
bool QPixmapCache::replace(const Key &key, const QPixmap &pixmap)
bool QPixmapCache::replace(const QByteArray &key, const QPixmap &pixmap)
{
return pm_cache()->insert(key, new QPixmap(pixmap));
}
@ -211,7 +211,7 @@ void QPixmapCache::setCacheLimit(int n)
/*!
Removes the pixmap associated with \a key from the cache.
*/
void QPixmapCache::remove(const QString &key)
void QPixmapCache::remove(const QByteArray &key)
{
pm_cache()->remove(key);
}

View file

@ -31,19 +31,17 @@ QT_BEGIN_NAMESPACE
class Q_GUI_EXPORT QPixmapCache
{
public:
typedef QString Key;
static int cacheLimit();
static void setCacheLimit(int);
static QPixmap *find(const QString &key);
static bool find(const QString &key, QPixmap *pixmap);
static QPixmap *find(const QByteArray &key);
static bool find(const QByteArray &key, QPixmap *pixmap);
// ### get rid of this function
static inline bool find(const QString &key, QPixmap &pixmap)
static inline bool find(const QByteArray &key, QPixmap &pixmap)
{ return find(key, &pixmap); };
static bool insert(const QString &key, const QPixmap &pixmap);
static Key insert(const QPixmap &pixmap);
static bool replace(const Key &key, const QPixmap &pixmap);
static void remove(const QString &key);
static bool insert(const QByteArray &key, const QPixmap &pixmap);
static QByteArray insert(const QPixmap &pixmap);
static bool replace(const QByteArray &key, const QPixmap &pixmap);
static void remove(const QByteArray &key);
static void clear();
};

View file

@ -968,7 +968,7 @@ QPixmap QItemDelegate::decoration(const QStyleOptionViewItem &option, const QVar
*/
QPixmap *QItemDelegate::selected(const QPixmap &pixmap, const QPalette &palette, bool enabled) const
{
const QString key = qHexString(
const QByteArray key = qHexString(
"qt_itemdelegate_%lld_%d",
pixmap.cacheKey(),
static_cast<int>(enabled)

View file

@ -4956,10 +4956,10 @@ static QPixmap generateWavyPixmap(qreal maxRadius, const QPen &pen)
{
const qreal radiusBase = qMax(qreal(1), maxRadius);
const QString key = qHexString(
const QByteArray key = qHexString(
"qt_waveunderline_%f_",
static_cast<float>(radiusBase)
) + pen.color().name();
) + pen.color().name().toLatin1();
QPixmap pixmap;
if (QPixmapCache::find(key, pixmap))

View file

@ -136,14 +136,14 @@ inline static QTabBar::Shape tabBarShapeFrom(QTabWidget::TabShape shape, QTabWid
#endif // QT_NO_TABWIDGET
// converts an integer values to an unique string token
inline static QString qHexString(const char *format, ...)
inline static QByteArray qHexString(const char *format, ...)
{
va_list ap;
va_start(ap, format);
QSTACKARRAY(char, hexbuf, 1024);
::vsnprintf(hexbuf, sizeof(hexbuf), format, ap);
va_end(ap);
return QString::fromLatin1(hexbuf);
return QByteArray(hexbuf);
}
QT_END_NAMESPACE

View file

@ -682,7 +682,7 @@ void QCleanlooksStyle::drawPrimitive(PrimitiveElement elem,
return;
}
BEGIN_STYLE_PIXMAPCACHE(QString::fromLatin1("pushbutton-%1").arg(isDefault))
BEGIN_STYLE_PIXMAPCACHE(QByteArray("pushbutton-") + static_cast<char>(isDefault))
r = rect.adjusted(0, 1, 0, -1);
bool isEnabled = (option->state & State_Enabled);
@ -1223,9 +1223,9 @@ void QCleanlooksStyle::drawControl(ControlElement element, const QStyleOption *o
// Draws the header in tables.
if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
QPixmap cache;
QString pixmapName = QStyleHelper::uniqueName(QLatin1String("qt_headersection"), option, option->rect.size());
pixmapName += QString::number(- int(header->position));
pixmapName += QString::number(- int(header->orientation));
QByteArray pixmapName = QStyleHelper::uniqueName("qt_headersection", option, option->rect.size());
pixmapName += QByteArray::number(- int(header->position));
pixmapName += QByteArray::number(- int(header->orientation));
QRect r = option->rect;
QColor gradientStopColor;
QColor gradientStartColor = option->palette.button().color();
@ -2010,7 +2010,7 @@ void QCleanlooksStyle::drawComplexControl(ComplexControl control, const QStyleOp
case CC_SpinBox:
if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
QPixmap cache;
QString pixmapName = QStyleHelper::uniqueName(QLatin1String("qt_spinbox"), spinBox, spinBox->rect.size());
QByteArray pixmapName = QStyleHelper::uniqueName("qt_spinbox", spinBox, spinBox->rect.size());
if (!QPixmapCache::find(pixmapName, cache)) {
cache = QPixmap(spinBox->rect.size());
cache.fill(Qt::transparent);
@ -2759,7 +2759,7 @@ void QCleanlooksStyle::drawComplexControl(ComplexControl control, const QStyleOp
// The AddLine (down/right) button
if (scrollBar->subControls & SC_ScrollBarAddLine) {
QString addLinePixmapName = QStyleHelper::uniqueName(QLatin1String("qt_scrollbar_addline"), option, QSize(16, 16));
QString addLinePixmapName = QStyleHelper::uniqueName("qt_scrollbar_addline", option, QSize(16, 16));
QRect pixmapRect = scrollBarAddLine;
if (isEnabled) {
QRect fillRect = pixmapRect.adjusted(1, 1, -1, -1);
@ -2837,13 +2837,13 @@ void QCleanlooksStyle::drawComplexControl(ComplexControl control, const QStyleOp
bool isEnabled = (comboBox->state & State_Enabled);
bool focus = isEnabled && (comboBox->state & State_HasFocus);
QPixmap cache;
QString pixmapName = QStyleHelper::uniqueName(QLatin1String("qt_combobox"), option, comboBox->rect.size());
QByteArray pixmapName = QStyleHelper::uniqueName("qt_combobox", option, comboBox->rect.size());
if (sunken)
pixmapName += QLatin1String("-sunken");
pixmapName += "-sunken";
if (comboBox->editable)
pixmapName += QLatin1String("-editable");
pixmapName += "-editable";
if (isEnabled)
pixmapName += QLatin1String("-enabled");
pixmapName += "-enabled";
if (!QPixmapCache::find(pixmapName, cache)) {
cache = QPixmap(comboBox->rect.size());
@ -3077,7 +3077,7 @@ void QCleanlooksStyle::drawComplexControl(ComplexControl control, const QStyleOp
highlightAlpha.setAlpha(80);
if ((option->subControls & SC_SliderGroove) && groove.isValid()) {
QString groovePixmapName = QStyleHelper::uniqueName(QLatin1String("qt_slider_groove"), option, groove.size());
QByteArray groovePixmapName = QStyleHelper::uniqueName("qt_slider_groove", option, groove.size());
QRect pixmapRect(0, 0, groove.width(), groove.height());
// draw background groove
@ -3155,7 +3155,7 @@ void QCleanlooksStyle::drawComplexControl(ComplexControl control, const QStyleOp
// draw handle
if ((option->subControls & SC_SliderHandle) ) {
QString handlePixmapName = QStyleHelper::uniqueName(QLatin1String("qt_slider_handle"), option, handle.size());
QByteArray handlePixmapName = QStyleHelper::uniqueName("qt_slider_handle", option, handle.size());
if (!QPixmapCache::find(handlePixmapName, cache)) {
cache = QPixmap(handle.size());
cache.fill(Qt::transparent);

View file

@ -56,9 +56,9 @@ public:
QPixmap internalPixmapCache; \
QImage imageCache; \
QPainter *p = painter; \
QString unique = QStyleHelper::uniqueName((a), option, option->rect.size()); \
QTransform::TransformationType devTxType = painter->deviceTransform().type(); \
QTransform::TransformationType worldTxType = painter->worldTransform().type(); \
const QByteArray unique = QStyleHelper::uniqueName((a), option, option->rect.size()); \
const QTransform::TransformationType devTxType = painter->deviceTransform().type(); \
const QTransform::TransformationType worldTxType = painter->worldTransform().type(); \
bool doPixmapCache = (devTxType <= QTransform::TxTranslate && worldTxType <= QTransform::TxTranslate); \
if (doPixmapCache && QPixmapCache::find(unique, internalPixmapCache)) { \
painter->drawPixmap(option->rect.topLeft(), internalPixmapCache); \

View file

@ -32,10 +32,10 @@ QT_BEGIN_NAMESPACE
namespace QStyleHelper {
QString uniqueName(const QString &key, const QStyleOption *option, const QSize &size)
QByteArray uniqueName(const QByteArray &key, const QStyleOption *option, const QSize &size)
{
const QStyleOptionComplex *complexOption = qstyleoption_cast<const QStyleOptionComplex *>(option);
QString tmp = key + qHexString(
QByteArray tmp = key + qHexString(
"_%d_%d_%d_%lld_%d_%d",
static_cast<int>(option->state),
static_cast<int>(option->direction),
@ -47,9 +47,9 @@ QString uniqueName(const QString &key, const QStyleOption *option, const QSize &
#ifndef QT_NO_SPINBOX
if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
tmp += QLatin1Char('_') + QChar(static_cast<uint>(spinBox->buttonSymbols));
tmp += QLatin1Char('_') + QChar(static_cast<uint>(spinBox->stepEnabled));
tmp += QLatin1Char('_') + QChar(static_cast<uint>(spinBox->frame ? '1' : '0'));
tmp += '_' + static_cast<char>(spinBox->buttonSymbols);
tmp += '_' + static_cast<char>(spinBox->stepEnabled);
tmp += '_' + static_cast<char>(spinBox->frame ? '1' : '0');
}
#endif // QT_NO_SPINBOX
return tmp;
@ -184,7 +184,7 @@ void drawDial(const QStyleOptionSlider *option, QPainter *painter)
}
// Cache dial background
BEGIN_STYLE_PIXMAPCACHE(QString::fromLatin1("qdial"));
BEGIN_STYLE_PIXMAPCACHE(QByteArray("qdial"));
const qreal d_ = r / 6;
const qreal dx = option->rect.x() + d_ + (width - 2 * r) / 2 + 1;

View file

@ -46,7 +46,7 @@ class QStyleOption;
namespace QStyleHelper
{
QString uniqueName(const QString &key, const QStyleOption *option, const QSize &size);
QByteArray uniqueName(const QByteArray &key, const QStyleOption *option, const QSize &size);
#ifndef QT_NO_DIAL
qreal angle(const QPointF &p1, const QPointF &p2);
QPolygonF calcLines(const QStyleOptionSlider *dial);

View file

@ -694,9 +694,8 @@ void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt,
QRect r = opt->rect;
int size = qMin(r.height(), r.width());
QPixmap pixmap;
QString pixmapName = QStyleHelper::uniqueName(QLatin1String("qt_arrow")
+ QString::fromLatin1(metaObject()->className()), opt, QSize(size, size))
+ QLatin1Char('_') + QChar(static_cast<uint>(pe));
QByteArray pixmapName = QStyleHelper::uniqueName(QByteArray("qt_arrow") + metaObject()->className(), opt, QSize(size, size))
+ '_' + static_cast<char>(pe);
if (!QPixmapCache::find(pixmapName, pixmap)) {
int border = size/5;
int sqsize = 2*(size/2);

View file

@ -21,6 +21,7 @@
#include <qtest.h>
#include <QPixmapCache>
#include <qguicommon_p.h>
//TESTED_FILES=
class tst_QPixmapCache : public QObject
@ -67,7 +68,7 @@ void tst_QPixmapCache::insert_data()
QTest::newRow("QPixmapCache (int API)") << false;
}
QList<QPixmapCache::Key> keys;
QList<QByteArray> keys;
void tst_QPixmapCache::insert()
{
@ -77,8 +78,8 @@ void tst_QPixmapCache::insert()
QBENCHMARK {
for (int i = 0 ; i <= 10000 ; i++)
{
QString tmp;
tmp.sprintf("my-key-%d", i);
QByteArray tmp("my-key-");
tmp += QByteArray::number(i);
QPixmapCache::insert(tmp, p);
}
}
@ -103,10 +104,10 @@ void tst_QPixmapCache::find()
QPixmap p;
if (cacheType) {
QBENCHMARK {
QString tmp;
for (int i = 0 ; i <= 10000 ; i++)
{
tmp.sprintf("my-key-%d", i);
QByteArray tmp("my-key-");
tmp += QByteArray::number(i);
QPixmapCache::find(tmp, p);
}
}
@ -127,7 +128,7 @@ void tst_QPixmapCache::styleUseCaseComplexKey_data()
}
struct styleStruct {
QString key;
QByteArray key;
uint state;
uint direction;
uint complex;
@ -155,45 +156,41 @@ void tst_QPixmapCache::styleUseCaseComplexKey()
QBENCHMARK {
for (int i = 0 ; i <= 10000 ; i++)
{
QString tmp;
tmp.sprintf("%s-%d-%d-%d-%d-%d-%d", QString("my-progressbar-%1").arg(i).toLatin1().constData(), 5, 3, 0, 358, 100, 200);
QByteArray tmp = qHexString("my-progressbar-%d-%d-%d-%d-%d-%d-%d", i, 5, 3, 0, 358, 100, 200);
QPixmapCache::insert(tmp, p);
}
for (int i = 0 ; i <= 10000 ; i++)
{
QString tmp;
tmp.sprintf("%s-%d-%d-%d-%d-%d-%d", QString("my-progressbar-%1").arg(i).toLatin1().constData(), 5, 3, 0, 358, 100, 200);
QByteArray tmp = qHexString("my-progressbar-%d-%d-%d-%d-%d-%d-%d", i, 5, 3, 0, 358, 100, 200);
QPixmapCache::find(tmp, p);
}
}
} else {
QHash<styleStruct, QPixmapCache::Key> hash;
QHash<styleStruct, QByteArray> hash;
QBENCHMARK {
for (int i = 0 ; i <= 10000 ; i++)
{
styleStruct myStruct;
myStruct.key = QString("my-progressbar-%1").arg(i);
myStruct.key = QByteArray("my-progressbar-") + QByteArray::number(i);
myStruct.state = 5;
myStruct.direction = 4;
myStruct.complex = 3;
myStruct.palette = 358;
myStruct.width = 100;
myStruct.key = QString::number(200);
QPixmapCache::Key key = QPixmapCache::insert(p);
QByteArray key = QPixmapCache::insert(p);
hash.insert(myStruct, key);
}
for (int i = 0 ; i <= 10000 ; i++)
{
styleStruct myStruct;
myStruct.key = QString("my-progressbar-%1").arg(i);
myStruct.key = QByteArray("my-progressbar-") + QByteArray::number(i);
myStruct.state = 5;
myStruct.direction = 4;
myStruct.complex = 3;
myStruct.palette = 358;
myStruct.width = 100;
myStruct.key = QString::number(200);
QPixmapCache::Key key = hash.value(myStruct);
QByteArray key = hash.value(myStruct);
QPixmapCache::find(key, &p);
}
}