OSDN Git Service

simplify QPixmapCache
authorIvailo Monev <xakepa10@laimg.moc>
Thu, 20 Jun 2019 13:59:03 +0000 (13:59 +0000)
committerIvailo Monev <xakepa10@laimg.moc>
Thu, 20 Jun 2019 14:05:58 +0000 (14:05 +0000)
Signed-off-by: Ivailo Monev <xakepa10@laimg.moc>
src/gui/image/image.cmake
src/gui/image/qpixmapcache.cpp
src/gui/image/qpixmapcache.h
src/gui/image/qpixmapcache_p.h [deleted file]
src/shared/qclass_lib_map.h

index 30384f4..3a75b85 100644 (file)
@@ -16,7 +16,6 @@ set(GUI_HEADERS
     ${CMAKE_CURRENT_SOURCE_DIR}/image/qpixmap_raster_p.h
     ${CMAKE_CURRENT_SOURCE_DIR}/image/qpixmap_x11_p.h
     ${CMAKE_CURRENT_SOURCE_DIR}/image/qpixmapcache.h
-    ${CMAKE_CURRENT_SOURCE_DIR}/image/qpixmapcache_p.h
     ${CMAKE_CURRENT_SOURCE_DIR}/image/qpixmapdata_p.h
     ${CMAKE_CURRENT_SOURCE_DIR}/image/qpixmapfilter_p.h
     ${CMAKE_CURRENT_SOURCE_DIR}/image/qbmphandler_p.h
index 22a6812..682677b 100644 (file)
 **
 ****************************************************************************/
 
-// #define Q_TEST_QPIXMAPCACHE
 #include "qpixmapcache.h"
-#include "qobject.h"
-#include "qdebug.h"
-#include "qpixmapcache_p.h"
+#include "qcache.h"
 
 QT_BEGIN_NAMESPACE
 
@@ -65,11 +62,7 @@ QT_BEGIN_NAMESPACE
     object for caching the pixmaps.
 
     The cache associates a pixmap with a user-provided string as a key,
-    or with a QPixmapCache::Key that the cache generates.
-    Using QPixmapCache::Key for keys is faster than using strings. The string API is
-    very convenient for complex keys but the QPixmapCache::Key API will be very
-    efficient and convenient for a one-to-one object-to-pixmap mapping \mdash in
-    this case, you can store the keys as members of an object.
+    or generates one if not provided.
 
     If two pixmaps are inserted into the cache using equal keys then the
     last pixmap will replace the first pixmap in the cache. This follows the
@@ -93,358 +86,8 @@ QT_BEGIN_NAMESPACE
 
 static int cache_limit = 10240; // 10 MB cache limit for desktop
 
-/*!
-    \class QPixmapCache::Key
-    \brief The QPixmapCache::Key class can be used for efficient access
-    to the QPixmapCache.
-    \since 4.6
-
-    Use QPixmapCache::insert() to receive an instance of Key generated
-    by the pixmap cache. You can store the key in your own objects for
-    a very efficient one-to-one object-to-pixmap mapping.
-*/
-
-/*!
-    Constructs an empty Key object.
-*/
-QPixmapCache::Key::Key() : d(0)
-{
-}
-
-/*!
-   \internal
-    Constructs a copy of \a other.
-*/
-QPixmapCache::Key::Key(const Key &other)
-{
-    if (other.d)
-        ++(other.d->ref);
-    d = other.d;
-}
-
-/*!
-    Destroys the key.
-*/
-QPixmapCache::Key::~Key()
-{
-    if (d && --(d->ref) == 0)
-        delete d;
-}
-
-/*!
-    \internal
-
-    Returns true if this key is the same as the given \a key; otherwise returns
-    false.
-*/
-bool QPixmapCache::Key::operator ==(const Key &key) const
-{
-    return (d == key.d);
-}
-
-/*!
-    \fn bool QPixmapCache::Key::operator !=(const Key &key) const
-    \internal
-*/
-
-/*!
-    \internal
-*/
-QPixmapCache::Key &QPixmapCache::Key::operator =(const Key &other)
-{
-    if (d != other.d) {
-        if (other.d)
-            ++(other.d->ref);
-        if (d && --(d->ref) == 0)
-            delete d;
-        d = other.d;
-    }
-    return *this;
-}
-
-class QPMCache : public QObject, public QCache<QPixmapCache::Key, QPixmapCacheEntry>
-{
-    Q_OBJECT
-public:
-    QPMCache();
-    ~QPMCache();
-
-    void timerEvent(QTimerEvent *);
-    bool insert(const QString& key, const QPixmap &pixmap, int cost);
-    QPixmapCache::Key insert(const QPixmap &pixmap, int cost);
-    bool replace(const QPixmapCache::Key &key, const QPixmap &pixmap, int cost);
-    bool remove(const QString &key);
-    bool remove(const QPixmapCache::Key &key);
-
-    void resizeKeyArray(int size);
-    QPixmapCache::Key createKey();
-    void releaseKey(const QPixmapCache::Key &key);
-    void clear();
-
-    QPixmap *object(const QString &key) const;
-    QPixmap *object(const QPixmapCache::Key &key) const;
-
-    static inline QPixmapCache::KeyData *get(const QPixmapCache::Key &key)
-    {return key.d;}
-
-    QList< QPair<QString,QPixmap> > allPixmaps() const;
-    bool flushDetachedPixmaps(bool nt);
-
-private:
-    enum { soon_time = 10000, flush_time = 30000 };
-    int *keyArray;
-    int theid;
-    int ps;
-    int keyArraySize;
-    int freeKey;
-    QHash<QString, QPixmapCache::Key> cacheKeys;
-    bool t;
-};
-
-uint qHash(const QPixmapCache::Key &k)
-{
-    return qHash(QPMCache::get(k)->key);
-}
-
-QPMCache::QPMCache()
-    : QObject(0),
-      QCache<QPixmapCache::Key, QPixmapCacheEntry>(cache_limit * 1024),
-      keyArray(0), theid(0), ps(0), keyArraySize(0), freeKey(0), t(false)
-{
-}
-QPMCache::~QPMCache()
-{
-    clear();
-    free(keyArray);
-}
-
-/*
-  This is supposed to cut the cache size down by about 25% in a
-  minute once the application becomes idle, to let any inserted pixmap
-  remain in the cache for some time before it becomes a candidate for
-  cleaning-up, and to not cut down the size of the cache while the
-  cache is in active use.
-
-  When the last detached pixmap has been deleted from the cache, kill the
-  timer so Qt won't keep the CPU from going into sleep mode. Currently
-  the timer is not restarted when the pixmap becomes unused, but it does
-  restart once something else is added (i.e. the cache space is actually needed).
-
-  Returns true if any were removed.
-*/
-bool QPMCache::flushDetachedPixmaps(bool nt)
-{
-    int mc = maxCost();
-    setMaxCost(nt ? totalCost() * 3 / 4 : totalCost() -1);
-    setMaxCost(mc);
-    ps = totalCost();
-
-    bool any = false;
-    QHash<QString, QPixmapCache::Key>::iterator it = cacheKeys.begin();
-    while (it != cacheKeys.end()) {
-        if (!contains(it.value())) {
-            releaseKey(it.value());
-            it = cacheKeys.erase(it);
-            any = true;
-        } else {
-            ++it;
-        }
-    }
-
-    return any;
-}
-
-void QPMCache::timerEvent(QTimerEvent *)
-{
-    bool nt = totalCost() == ps;
-    if (!flushDetachedPixmaps(nt)) {
-        killTimer(theid);
-        theid = 0;
-    } else if (nt != t) {
-        killTimer(theid);
-        theid = startTimer(nt ? soon_time : flush_time);
-        t = nt;
-    }
-}
-
-
-QPixmap *QPMCache::object(const QString &key) const
-{
-    QPixmapCache::Key cacheKey = cacheKeys.value(key);
-    if (!cacheKey.d || !cacheKey.d->isValid) {
-        const_cast<QPMCache *>(this)->cacheKeys.remove(key);
-        return 0;
-    }
-    QPixmap *ptr = QCache<QPixmapCache::Key, QPixmapCacheEntry>::object(cacheKey);
-     //We didn't find the pixmap in the cache, the key is not valid anymore
-    if (!ptr) {
-        const_cast<QPMCache *>(this)->cacheKeys.remove(key);
-    }
-    return ptr;
-}
-
-QPixmap *QPMCache::object(const QPixmapCache::Key &key) const
-{
-    Q_ASSERT(key.d->isValid);
-    QPixmap *ptr = QCache<QPixmapCache::Key, QPixmapCacheEntry>::object(key);
-    //We didn't find the pixmap in the cache, the key is not valid anymore
-    if (!ptr)
-        const_cast<QPMCache *>(this)->releaseKey(key);
-    return ptr;
-}
-
-bool QPMCache::insert(const QString& key, const QPixmap &pixmap, int cost)
-{
-    QPixmapCache::Key cacheKey;
-    QPixmapCache::Key oldCacheKey = cacheKeys.value(key);
-    //If for the same key we add already a pixmap we should delete it
-    if (oldCacheKey.d) {
-        QCache<QPixmapCache::Key, QPixmapCacheEntry>::remove(oldCacheKey);
-        cacheKeys.remove(key);
-    }
-
-    //we create a new key the old one has been removed
-    cacheKey = createKey();
-
-    bool success = QCache<QPixmapCache::Key, QPixmapCacheEntry>::insert(cacheKey, new QPixmapCacheEntry(cacheKey, pixmap), cost);
-    if (success) {
-        cacheKeys.insert(key, cacheKey);
-        if (!theid) {
-            theid = startTimer(flush_time);
-            t = false;
-        }
-    } else {
-        //Insertion failed we released the new allocated key
-        releaseKey(cacheKey);
-    }
-    return success;
-}
-
-QPixmapCache::Key QPMCache::insert(const QPixmap &pixmap, int cost)
-{
-    QPixmapCache::Key cacheKey = createKey();
-    bool success = QCache<QPixmapCache::Key, QPixmapCacheEntry>::insert(cacheKey, new QPixmapCacheEntry(cacheKey, pixmap), cost);
-    if (success) {
-        if (!theid) {
-            theid = startTimer(flush_time);
-            t = false;
-        }
-    } else {
-        //Insertion failed we released the key and return an invalid one
-        releaseKey(cacheKey);
-    }
-    return cacheKey;
-}
-
-bool QPMCache::replace(const QPixmapCache::Key &key, const QPixmap &pixmap, int cost)
-{
-    Q_ASSERT(key.d->isValid);
-    //If for the same key we had already an entry so we should delete the pixmap and use the new one
-    QCache<QPixmapCache::Key, QPixmapCacheEntry>::remove(key);
-
-    QPixmapCache::Key cacheKey = createKey();
-
-    bool success = QCache<QPixmapCache::Key, QPixmapCacheEntry>::insert(cacheKey, new QPixmapCacheEntry(cacheKey, pixmap), cost);
-    if (success) {
-        if(!theid) {
-            theid = startTimer(flush_time);
-            t = false;
-        }
-        const_cast<QPixmapCache::Key&>(key) = cacheKey;
-    } else {
-        //Insertion failed we released the key
-        releaseKey(cacheKey);
-    }
-    return success;
-}
-
-bool QPMCache::remove(const QString &key)
-{
-    QPixmapCache::Key cacheKey = cacheKeys.value(key);
-    //The key was not in the cache
-    if (!cacheKey.d)
-        return false;
-    cacheKeys.remove(key);
-    return QCache<QPixmapCache::Key, QPixmapCacheEntry>::remove(cacheKey);
-}
-
-bool QPMCache::remove(const QPixmapCache::Key &key)
-{
-    return QCache<QPixmapCache::Key, QPixmapCacheEntry>::remove(key);
-}
-
-void QPMCache::resizeKeyArray(int size)
-{
-    if (size <= keyArraySize || size == 0)
-        return;
-    keyArray = q_check_ptr(reinterpret_cast<int *>(realloc(keyArray,
-                    size * sizeof(int))));
-    for (int i = keyArraySize; i != size; ++i)
-        keyArray[i] = i + 1;
-    keyArraySize = size;
-}
-
-QPixmapCache::Key QPMCache::createKey()
-{
-    if (freeKey == keyArraySize)
-        resizeKeyArray(keyArraySize ? keyArraySize << 1 : 2);
-    int id = freeKey;
-    freeKey = keyArray[id];
-    QPixmapCache::Key key;
-    key.d = new QPixmapCache::KeyData;
-    key.d->key = ++id;
-    return key;
-}
-
-void QPMCache::releaseKey(const QPixmapCache::Key &key)
-{
-    if (key.d->key > keyArraySize || key.d->key <= 0)
-        return;
-    key.d->key--;
-    keyArray[key.d->key] = freeKey;
-    freeKey = key.d->key;
-    key.d->isValid = false;
-    key.d->key = 0;
-}
-
-void QPMCache::clear()
-{
-    free(keyArray);
-    keyArray = 0;
-    freeKey = 0;
-    keyArraySize = 0;
-    //Mark all keys as invalid
-    QList<QPixmapCache::Key> keys = QCache<QPixmapCache::Key, QPixmapCacheEntry>::keys();
-    for (int i = 0; i < keys.size(); ++i)
-        keys.at(i).d->isValid = false;
-    QCache<QPixmapCache::Key, QPixmapCacheEntry>::clear();
-}
-
-QList< QPair<QString,QPixmap> > QPMCache::allPixmaps() const
-{
-    QList< QPair<QString,QPixmap> > r;
-    QHash<QString, QPixmapCache::Key>::const_iterator it = cacheKeys.begin();
-    while (it != cacheKeys.end()) {
-        QPixmap *ptr = QCache<QPixmapCache::Key, QPixmapCacheEntry>::object(it.value());
-        if (ptr)
-            r.append(QPair<QString,QPixmap>(it.key(),*ptr));
-        ++it;
-    }
-    return r;
-}
-
-
-Q_GLOBAL_STATIC(QPMCache, pm_cache)
-
-int Q_AUTOTEST_EXPORT q_QPixmapCache_keyHashSize()
-{
-    return pm_cache()->size();
-}
-
-QPixmapCacheEntry::~QPixmapCacheEntry()
-{
-    pm_cache()->releaseKey(key);
-}
+typedef QCache<QString, QPixmap> PixmapCacheType;
+Q_GLOBAL_STATIC(PixmapCacheType, pm_cache)
 
 /*!
     \obsolete
@@ -491,27 +134,7 @@ bool QPixmapCache::find(const QString &key, QPixmap* pixmap)
     QPixmap *ptr = pm_cache()->object(key);
     if (ptr && pixmap)
         *pixmap = *ptr;
-    return ptr != 0;
-}
-
-/*!
-    Looks for a cached pixmap associated with the given \a key in the cache.
-    If the pixmap is found, the function sets \a pixmap to that pixmap and
-    returns true; otherwise it leaves \a pixmap alone and returns false. If
-    the pixmap is not found, it means that the \a key is no longer valid,
-    so it will be released for the next insertion.
-
-    \since 4.6
-*/
-bool QPixmapCache::find(const Key &key, QPixmap* pixmap)
-{
-    //The key is not valid anymore, a flush happened before probably
-    if (!key.d || !key.d->isValid)
-        return false;
-    QPixmap *ptr = pm_cache()->object(key);
-    if (ptr && pixmap)
-        *pixmap = *ptr;
-    return ptr != 0;
+    return ptr != Q_NULLPTR;
 }
 
 /*!
@@ -536,7 +159,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, new QPixmap(pixmap));
 }
 
 /*!
@@ -556,7 +179,10 @@ 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);
+    QPixmap *cpixmap = new QPixmap(pixmap);
+    QString key = QString::number(cpixmap->cacheKey());
+    pm_cache()->insert(key, cpixmap);
+    return key;
 }
 
 /*!
@@ -570,10 +196,8 @@ QPixmapCache::Key QPixmapCache::insert(const QPixmap &pixmap)
 */
 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);
+    QPixmap *cpixmap = new QPixmap(pixmap);
+    return pm_cache()->insert(key, cpixmap);
 }
 
 /*!
@@ -602,7 +226,7 @@ int QPixmapCache::cacheLimit()
 void QPixmapCache::setCacheLimit(int n)
 {
     cache_limit = n;
-    pm_cache()->setMaxCost(1024 * cache_limit);
+    pm_cache()->setMaxCost(cache_limit);
 }
 
 /*!
@@ -614,50 +238,12 @@ void QPixmapCache::remove(const QString &key)
 }
 
 /*!
-  Removes the pixmap associated with \a key from the cache and releases
-  the key for a future insertion.
-
-  \since 4.6
-*/
-void QPixmapCache::remove(const Key &key)
-{
-    //The key is not valid anymore, a flush happened before probably
-    if (!key.d || !key.d->isValid)
-        return;
-    pm_cache()->remove(key);
-}
-
-/*!
     Removes all pixmaps from the cache.
 */
 
 void QPixmapCache::clear()
 {
-    QT_TRY {
-        pm_cache()->clear();
-    } QT_CATCH(const std::bad_alloc &) {
-        // if we ran out of memory during pm_cache(), it's no leak,
-        // so just ignore it.
-    }
-}
-
-#ifdef Q_TEST_QPIXMAPCACHE
-void QPixmapCache::flushDetachedPixmaps()
-{
-    pm_cache()->flushDetachedPixmaps(true);
+    pm_cache()->clear();
 }
 
-int QPixmapCache::totalUsed()
-{
-    return (pm_cache()->totalCost()+1023) / 1024;
-}
-
-QList< QPair<QString,QPixmap> > QPixmapCache::allPixmaps()
-{
-    return pm_cache()->allPixmaps();
-}
-#endif // Q_TEST_QPIXMAPCACHE
-
 QT_END_NAMESPACE
-
-#include "moc_qpixmapcache.cpp"
index ed25f65..e613708 100644 (file)
 
 #include <QtGui/qpixmap.h>
 
-#ifdef Q_TEST_QPIXMAPCACHE
-#include <QtCore/qpair.h>
-#endif
-
 QT_BEGIN_HEADER
 
 QT_BEGIN_NAMESPACE
@@ -48,23 +44,7 @@ QT_BEGIN_NAMESPACE
 class Q_GUI_EXPORT QPixmapCache
 {
 public:
-    class KeyData;
-    class Q_GUI_EXPORT Key
-    {
-    public:
-        Key();
-        Key(const Key &other);
-        ~Key();
-        bool operator ==(const Key &key) const;
-        inline bool operator !=(const Key &key) const
-        { return !operator==(key); }
-        Key &operator =(const Key &other);
-
-    private:
-        KeyData *d;
-        friend class QPMCache;
-        friend class QPixmapCache;
-    };
+    typedef QString Key;
 
     static int cacheLimit();
     static void setCacheLimit(int);
@@ -73,19 +53,11 @@ public:
     // ### get rid of this function
     static inline bool find(const QString &key, QPixmap &pixmap)
         { return find(key, &pixmap); };
-    static bool find(const Key &key, QPixmap *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 void remove(const Key &key);
     static void clear();
-
-#ifdef Q_TEST_QPIXMAPCACHE
-    static void flushDetachedPixmaps();
-    static int totalUsed();
-    static QList< QPair<QString,QPixmap> > allPixmaps();
-#endif
 };
 
 QT_END_NAMESPACE
diff --git a/src/gui/image/qpixmapcache_p.h b/src/gui/image/qpixmapcache_p.h
deleted file mode 100644 (file)
index 5853411..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Copyright (C) 2016-2019 Ivailo Monev
-**
-** This file is part of the QtGui module of the Katie Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPIXMAPCACHE_P_H
-#define QPIXMAPCACHE_P_H
-
-//
-//  W A R N I N G
-//  -------------
-//
-// This file is not part of the Katie API. This header
-// file may change from version to version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qpixmapcache.h"
-#include "qpaintengine.h"
-#include <qimage_p.h>
-#include <qpixmap_raster_p.h>
-#include "qcache.h"
-
-QT_BEGIN_NAMESPACE
-
-uint qHash(const QPixmapCache::Key &k);
-
-class QPixmapCache::KeyData
-{
-public:
-    KeyData() : isValid(true), key(0), ref(1) {}
-    KeyData(const KeyData &other)
-     : isValid(other.isValid), key(other.key), ref(1) {}
-    ~KeyData() {}
-
-    bool isValid;
-    int key;
-    int ref;
-};
-
-// XXX: hw: is this a general concept we need to abstract?
-class QPixmapCacheEntry : public QPixmap
-{
-public:
-    QPixmapCacheEntry(const QPixmapCache::Key &key, const QPixmap &pix) : QPixmap(pix), key(key)
-    {
-        QPixmapData *pd = pixmapData();
-        if (pd && pd->classId() == QPixmapData::RasterClass) {
-            QRasterPixmapData *d = static_cast<QRasterPixmapData*>(pd);
-            if (!d->image.isNull() && d->image.d->paintEngine
-                && !d->image.d->paintEngine->isActive())
-            {
-                delete d->image.d->paintEngine;
-                d->image.d->paintEngine = 0;
-            }
-        }
-    }
-    ~QPixmapCacheEntry();
-    QPixmapCache::Key key;
-};
-
-QT_END_NAMESPACE
-
-#endif // QPIXMAPCACHE_P_H
index 58ed5c6..d73c351 100644 (file)
@@ -224,7 +224,6 @@ static const ClassInfoEntry qclass_lib_map[] = {
     { "QMovie", "QtGui/qmovie.h"},
     { "QPixmap", "QtGui/qpixmap.h"},
     { "QPixmapCache", "QtGui/qpixmapcache.h"},
-    { "Key", "QtGui/qpixmapcache.h"},
     { "QAccessible", "QtGui/qaccessible.h"},
     { "QAccessibleInterface", "QtGui/qaccessible.h"},
     { "QAccessibleEvent", "QtGui/qaccessible.h"},
@@ -693,6 +692,6 @@ static const ClassInfoEntry qclass_lib_map[] = {
     { "QFormBuilder", "QtUiTools/formbuilder.h"},
     { "QUiLoader", "QtUiTools/quiloader.h"},
 };
-static const int qclass_lib_count = 687;
+static const int qclass_lib_count = 686;
 
 #endif