diff options
| author | Shawn Rutledge <shawn.rutledge@qt.io> | 2023-08-29 23:39:08 +0200 |
|---|---|---|
| committer | Shawn Rutledge <shawn.rutledge@qt.io> | 2023-09-09 11:03:42 +0200 |
| commit | 96e68221798e7781022aecedb6917f389a31b35c (patch) | |
| tree | 1117483b37f38fb1260fdfc6dca777617eae1c33 /src/quick/util/qquickpixmapcache.cpp | |
| parent | e903cf1b3eb6bf3773dbc4a9792d8b3496b1d180 (diff) | |
Test QQuickPixmap::loadImageFromDevice()
SlowProvider is slow like QPdfIOHandler is; it's a QQuickImageProvider
rather than a QImageIOHandler for ease of testing, and we invoke it via
a QQuickImage subclass that calls QQuickPixmap::loadImageFromDevice(),
like QQuickPdfPageImage does.
Also get the old dataLeak() test running, as a drive-by. It still isn't
useful in CI though, because it has no built-in way of detecting leaks.
Task-number: QTBUG-114953
Change-Id: I9e2950fbaf4ea69969b3bd10a0d8e624f0e4e8c1
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
Diffstat (limited to 'src/quick/util/qquickpixmapcache.cpp')
| -rw-r--r-- | src/quick/util/qquickpixmapcache.cpp | 39 |
1 files changed, 30 insertions, 9 deletions
diff --git a/src/quick/util/qquickpixmapcache.cpp b/src/quick/util/qquickpixmapcache.cpp index a17a9aebc3..46ecdf1928 100644 --- a/src/quick/util/qquickpixmapcache.cpp +++ b/src/quick/util/qquickpixmapcache.cpp @@ -1224,26 +1224,38 @@ QQuickPixmapCache *QQuickPixmapCache::instance() QQuickPixmapCache::~QQuickPixmapCache() { + destroyCache(); +} + +/*! \internal + Empty the cache completely, to prevent leaks. Returns the number of + leaked pixmaps (should always be \c 0). + + This is work the destructor needs to do, but we put it into a function + only to make it testable in autotests, because the static instance() + cannot be destroyed before shutdown. +*/ +int QQuickPixmapCache::destroyCache() +{ + if (m_destroying) + return -1; + m_destroying = true; -#ifndef QT_NO_DEBUG - int leakedPixmaps = 0; -#endif // Prevent unreferencePixmap() from assuming it needs to kick // off the cache expiry timer, as we're shrinking the cache // manually below after releasing all the pixmaps. m_timerId = -2; // unreference all (leaked) pixmaps + int leakedPixmaps = 0; const auto cache = m_cache; // NOTE: intentional copy (QTBUG-65077); releasing items from the cache modifies m_cache. for (auto *pixmap : cache) { auto currRefCount = pixmap->refCount; if (currRefCount) { -#ifndef QT_NO_DEBUG leakedPixmaps++; qCDebug(lcQsgLeak) << "leaked pixmap: refCount" << pixmap->refCount << pixmap->url << "frame" << pixmap->frame << "size" << pixmap->requestSize << "region" << pixmap->requestRegion; -#endif while (currRefCount > 0) { pixmap->release(this); currRefCount--; @@ -1252,13 +1264,22 @@ QQuickPixmapCache::~QQuickPixmapCache() } // free all unreferenced pixmaps - while (m_lastUnreferencedPixmap) { + while (m_lastUnreferencedPixmap) shrinkCache(20); - } -#ifndef QT_NO_DEBUG qCDebug(lcQsgLeak, "Number of leaked pixmaps: %i", leakedPixmaps); -#endif + return leakedPixmaps; +} + +qsizetype QQuickPixmapCache::referencedCost() const +{ + qsizetype ret = 0; + QMutexLocker locker(&m_cacheMutex); + for (const auto *pixmap : std::as_const(m_cache)) { + if (pixmap->refCount) + ret += pixmap->cost(); + } + return ret; } /*! \internal |
