QPixmapCache: make sure to not overflow cache limit
The cost for the pixmap cache was calculated in bytes but setCacheLimit() takes the size in kilobytes. This lead to the situation that all values above 2097152 overflowed and disabled the caching completely. Fix it by calculating the cost in kilobytes as it is done in QGLContext. Task-number: QTBUG-45293 Change-Id: Ib8dc2360c8f3201ce0b615a04c38b5ccaa8fc6cf Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io> Reviewed-by: Andy Shaw <andy.shaw@qt.io>
This commit is contained in:
parent
4840ec7c68
commit
c7cbf21699
@ -86,7 +86,17 @@ QT_BEGIN_NAMESPACE
|
||||
\sa QCache, QPixmap
|
||||
*/
|
||||
|
||||
static int cache_limit = 10240; // 10 MB cache limit
|
||||
static const int cache_limit_default = 10240; // 10 MB cache limit
|
||||
|
||||
static inline int cost(const QPixmap &pixmap)
|
||||
{
|
||||
// make sure to do a 64bit calculation
|
||||
const qint64 costKb = static_cast<qint64>(pixmap.width()) *
|
||||
pixmap.height() * pixmap.depth() / (8 * 1024);
|
||||
const qint64 costMax = std::numeric_limits<int>::max();
|
||||
// a small pixmap should have at least a cost of 1(kb)
|
||||
return static_cast<int>(qBound(1LL, costKb, costMax));
|
||||
}
|
||||
|
||||
/*!
|
||||
\class QPixmapCache::Key
|
||||
@ -237,7 +247,7 @@ uint qHash(const QPixmapCache::Key &k)
|
||||
|
||||
QPMCache::QPMCache()
|
||||
: QObject(0),
|
||||
QCache<QPixmapCache::Key, QPixmapCacheEntry>(cache_limit * 1024),
|
||||
QCache<QPixmapCache::Key, QPixmapCacheEntry>(cache_limit_default),
|
||||
keyArray(0), theid(0), ps(0), keyArraySize(0), freeKey(0), t(false)
|
||||
{
|
||||
}
|
||||
@ -553,7 +563,7 @@ bool QPixmapCache::find(const Key &key, QPixmap* pixmap)
|
||||
|
||||
bool QPixmapCache::insert(const QString &key, const QPixmap &pixmap)
|
||||
{
|
||||
return pm_cache()->insert(key, pixmap, pixmap.width() * pixmap.height() * pixmap.depth() / 8);
|
||||
return pm_cache()->insert(key, pixmap, cost(pixmap));
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -573,7 +583,7 @@ bool QPixmapCache::insert(const QString &key, const QPixmap &pixmap)
|
||||
*/
|
||||
QPixmapCache::Key QPixmapCache::insert(const QPixmap &pixmap)
|
||||
{
|
||||
return pm_cache()->insert(pixmap, pixmap.width() * pixmap.height() * pixmap.depth() / 8);
|
||||
return pm_cache()->insert(pixmap, cost(pixmap));
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -590,7 +600,7 @@ bool QPixmapCache::replace(const Key &key, const QPixmap &pixmap)
|
||||
//The key is not valid anymore, a flush happened before probably
|
||||
if (!key.d || !key.d->isValid)
|
||||
return false;
|
||||
return pm_cache()->replace(key, pixmap, pixmap.width() * pixmap.height() * pixmap.depth() / 8);
|
||||
return pm_cache()->replace(key, pixmap, cost(pixmap));
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -603,7 +613,7 @@ bool QPixmapCache::replace(const Key &key, const QPixmap &pixmap)
|
||||
|
||||
int QPixmapCache::cacheLimit()
|
||||
{
|
||||
return cache_limit;
|
||||
return pm_cache()->maxCost();
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -616,8 +626,7 @@ int QPixmapCache::cacheLimit()
|
||||
|
||||
void QPixmapCache::setCacheLimit(int n)
|
||||
{
|
||||
cache_limit = n;
|
||||
pm_cache()->setMaxCost(1024 * cache_limit);
|
||||
pm_cache()->setMaxCost(n);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -92,6 +92,9 @@ void tst_QPixmapCache::cacheLimit()
|
||||
// it was between 2048 and 10240 last time I looked at it
|
||||
QVERIFY(originalCacheLimit >= 1024 && originalCacheLimit <= 20480);
|
||||
|
||||
QPixmapCache::setCacheLimit(std::numeric_limits<int>::max());
|
||||
QCOMPARE(QPixmapCache::cacheLimit(), std::numeric_limits<int>::max());
|
||||
|
||||
QPixmapCache::setCacheLimit(100);
|
||||
QCOMPARE(QPixmapCache::cacheLimit(), 100);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user