diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index f15918070..92119bf1a 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -2309,19 +2309,6 @@ bool QFontInfo::exactMatch() const // ********************************************************************** // QFontCache -// ********************************************************************** - -#ifdef QFONTCACHE_DEBUG -// fast timeouts for debugging -static const int fast_timeout = 1000; // 1s -static const int slow_timeout = 5000; // 5s -#else -static const int fast_timeout = 10000; // 10s -static const int slow_timeout = 300000; // 5m -#endif // QFONTCACHE_DEBUG - -const uint QFontCache::min_cost = 4*1024; // 4mb - thread_local QFontCache* theFontCache = nullptr; QFontCache *QFontCache::instance() @@ -2340,8 +2327,6 @@ void QFontCache::cleanup() } QFontCache::QFontCache() - : QObject(), total_cost(0), max_cost(min_cost), - current_timestamp(0), fast(false), timer_id(-1) { } @@ -2380,9 +2365,9 @@ void QFontCache::clear() for (EngineCache::Iterator it = engineCache.begin(), end = engineCache.end(); it != end; ++it) { - if (!it->data->ref.deref()) { - delete it->data; - it->data = 0; + QFontEngine *engine = it.value(); + if (!engine->ref.deref()) { + delete engine; } } @@ -2394,7 +2379,9 @@ QFontEngineData *QFontCache::findEngineData(const Key &key) const { EngineDataCache::ConstIterator it = engineDataCache.find(key), end = engineDataCache.end(); - if (it == end) return 0; + if (it == end) { + return nullptr; + } // found return it.value(); @@ -2407,263 +2394,35 @@ void QFontCache::insertEngineData(const Key &key, QFontEngineData *engineData) Q_ASSERT(!engineDataCache.contains(key)); engineData->ref.ref(); // the cache has a reference engineDataCache.insert(key, engineData); - increaseCost(sizeof(QFontEngineData)); } QFontEngine *QFontCache::findEngine(const Key &key) { EngineCache::Iterator it = engineCache.find(key), end = engineCache.end(); - if (it == end) return 0; - - // found... update the hitcount and timestamp - it.value().hits++; - it.value().timestamp = ++current_timestamp; + if (it == end) { + return nullptr; + } FC_DEBUG("QFontCache: found font engine\n" - " %p: timestamp %4u hits %3u ref %2d/%2d, type '%s'", - it.value().data, it.value().timestamp, it.value().hits, - int(it.value().data->ref), it.value().data->cache_count, - it.value().data->name()); + " %p: ref %2d, type '%s'", + it.value(), int(it.value()->ref), it.value()->name()); - return it.value().data; + return it.value(); } void QFontCache::insertEngine(const Key &key, QFontEngine *engine) { FC_DEBUG("QFontCache: inserting new engine %p", engine); - Engine data(engine); - data.timestamp = ++current_timestamp; - - QFontEngine *oldEngine = engineCache.value(key).data; + QFontEngine *oldEngine = engineCache.value(key); engine->ref.ref(); // the cache has a reference if (oldEngine && !oldEngine->ref.deref()) delete oldEngine; - engineCache.insert(key, data); - - // only increase the cost if this is the first time we insert the engine - if (engine->cache_count == 0) - increaseCost(engine->cache_cost); - - ++engine->cache_count; + engineCache.insert(key, engine); } -void QFontCache::increaseCost(uint cost) -{ - cost = (cost + 512) / 1024; // store cost in kb - cost = cost > 0 ? cost : 1; - total_cost += cost; - - FC_DEBUG(" COST: increased %u kb, total_cost %u kb, max_cost %u kb", - cost, total_cost, max_cost); - - if (total_cost > max_cost) { - max_cost = total_cost; - - if (timer_id == -1 || ! fast) { - FC_DEBUG(" TIMER: starting fast timer (%d ms)", fast_timeout); - - if (timer_id != -1) killTimer(timer_id); - timer_id = startTimer(fast_timeout); - fast = true; - } - } -} - -void QFontCache::decreaseCost(uint cost) -{ - cost = (cost + 512) / 1024; // cost is stored in kb - cost = cost > 0 ? cost : 1; - Q_ASSERT(cost <= total_cost); - total_cost -= cost; - - FC_DEBUG(" COST: decreased %u kb, total_cost %u kb, max_cost %u kb", - cost, total_cost, max_cost); -} - -void QFontCache::timerEvent(QTimerEvent *) -{ - FC_DEBUG("QFontCache::timerEvent: performing cache maintenance (timestamp %u)", - current_timestamp); - - if (total_cost <= max_cost && max_cost <= min_cost) { - FC_DEBUG(" cache redused sufficiently, stopping timer"); - - killTimer(timer_id); - timer_id = -1; - fast = false; - - return; - } - - // go through the cache and count up everything in use - uint in_use_cost = 0; - - { - FC_DEBUG(" SWEEP engine data:"); - - // make sure the cost of each engine data is at least 1kb - const uint engine_data_cost = - sizeof(QFontEngineData) > 1024 ? sizeof(QFontEngineData) : 1024; - - EngineDataCache::ConstIterator it = engineDataCache.constBegin(), - end = engineDataCache.constEnd(); - for (; it != end; ++it) { -#ifdef QFONTCACHE_DEBUG - FC_DEBUG(" %p: ref %2d", it.value(), int(it.value()->ref)); - -# if defined(Q_WS_X11) - // print out all engines - for (int i = 0; i < QUnicodeTables::ScriptCount; ++i) { - if (! it.value()->engines[i]) - continue; - FC_DEBUG(" contains %p", it.value()->engines[i]); - } -# endif // Q_WS_X11 -#endif // QFONTCACHE_DEBUG - - if (it.value()->ref > 1) - in_use_cost += engine_data_cost; - } - } - - { - FC_DEBUG(" SWEEP engine:"); - - EngineCache::ConstIterator it = engineCache.constBegin(), - end = engineCache.constEnd(); - for (; it != end; ++it) { - FC_DEBUG(" %p: timestamp %4u hits %2u ref %2d/%2d, cost %u bytes", - it.value().data, it.value().timestamp, it.value().hits, - int(it.value().data->ref), it.value().data->cache_count, - it.value().data->cache_cost); - - if (it.value().data->ref > 1) - in_use_cost += it.value().data->cache_cost / it.value().data->cache_count; - } - - // attempt to make up for rounding errors - in_use_cost += engineCache.size(); - } - - in_use_cost = (in_use_cost + 512) / 1024; // cost is stored in kb - - /* - calculate the new maximum cost for the cache - - NOTE: in_use_cost is *not* correct due to rounding errors in the - above algorithm. instead of worrying about getting the - calculation correct, we are more interested in speed, and use - in_use_cost as a floor for new_max_cost - */ - uint new_max_cost = qMax(qMax(max_cost / 2, in_use_cost), min_cost); - - FC_DEBUG(" after sweep, in use %u kb, total %u kb, max %u kb, new max %u kb", - in_use_cost, total_cost, max_cost, new_max_cost); - - if (new_max_cost == max_cost) { - if (fast) { - FC_DEBUG(" cannot shrink cache, slowing timer"); - - killTimer(timer_id); - timer_id = startTimer(slow_timeout); - fast = false; - } - - return; - } else if (! fast) { - FC_DEBUG(" dropping into passing gear"); - - killTimer(timer_id); - timer_id = startTimer(fast_timeout); - fast = true; - } - - max_cost = new_max_cost; - - { - FC_DEBUG(" CLEAN engine data:"); - - // clean out all unused engine data - EngineDataCache::Iterator it = engineDataCache.begin(), - end = engineDataCache.end(); - while (it != end) { - if (it.value()->ref > 1) { - ++it; - continue; - } - - EngineDataCache::Iterator rem = it++; - - decreaseCost(sizeof(QFontEngineData)); - - FC_DEBUG(" %p", rem.value()); - - delete rem.value(); - engineDataCache.erase(rem); - } - } - - // clean out the engine cache just enough to get below our new max cost - uint current_cost; - do { - current_cost = total_cost; - - EngineCache::Iterator it = engineCache.begin(), - end = engineCache.end(); - // determine the oldest and least popular of the unused engines - uint oldest = ~0u; - uint least_popular = ~0u; - - for (; it != end; ++it) { - if (it.value().data->ref > 1) - continue; - - if (it.value().timestamp < oldest && - it.value().hits <= least_popular) { - oldest = it.value().timestamp; - least_popular = it.value().hits; - } - } - - FC_DEBUG(" oldest %u least popular %u", oldest, least_popular); - - for (it = engineCache.begin(); it != end; ++it) { - if (it.value().data->ref == 1 && - it.value().timestamp == oldest && - it.value().hits == least_popular) - break; - } - - if (it != end) { - FC_DEBUG(" %p: timestamp %4u hits %2u ref %2d/%2d, type '%s'", - it.value().data, it.value().timestamp, it.value().hits, - int(it.value().data->ref), it.value().data->cache_count, - it.value().data->name()); - - if (--it.value().data->cache_count == 0) { - FC_DEBUG(" DELETE: last occurrence in cache"); - - decreaseCost(it.value().data->cache_cost); - if (!it.value().data->ref.deref()) - delete it.value().data; - } else { - /* - this particular font engine is in the cache multiple - times... set current_cost to zero, so that we can - keep looping to get rid of all occurrences - */ - current_cost = 0; - } - - engineCache.erase(it); - } - } while (current_cost != total_cost && total_cost > max_cost); -} - - #ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug stream, const QFont &font) { @@ -2674,4 +2433,3 @@ QDebug operator<<(QDebug stream, const QFont &font) QT_END_NAMESPACE #include "moc_qfont.h" -#include "moc_qfont_p.h" diff --git a/src/gui/text/qfont_p.h b/src/gui/text/qfont_p.h index 34267dbcc..76b8592ff 100644 --- a/src/gui/text/qfont_p.h +++ b/src/gui/text/qfont_p.h @@ -163,9 +163,8 @@ private: }; -class QFontCache : public QObject +class QFontCache { - Q_OBJECT public: // note: these static functions work on a per-thread basis static QFontCache *instance(); @@ -204,31 +203,11 @@ public: void insertEngineData(const Key &key, QFontEngineData *engineData); // QFontEngine cache - struct Engine { - Engine() : data(0), timestamp(0), hits(0) { } - Engine(QFontEngine *d) : data(d), timestamp(0), hits(0) { } - - QFontEngine *data; - uint timestamp; - uint hits; - }; - - typedef QMap EngineCache; + typedef QMap EngineCache; EngineCache engineCache; QFontEngine *findEngine(const Key &key); void insertEngine(const Key &key, QFontEngine *engine); - - private: - void increaseCost(uint cost); - void decreaseCost(uint cost); - void timerEvent(QTimerEvent *event); - - static const uint min_cost; - uint total_cost, max_cost; - uint current_timestamp; - bool fast; - int timer_id; }; QT_END_NAMESPACE diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index 16ce88a5c..aafda3ec9 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -141,7 +141,6 @@ QFontEngine::QFontEngine() : QObject(), ref(0) { - cache_count = 0; fsType = 0; symbol = false; memset(&hbFont, 0, sizeof(hbFont)); @@ -709,7 +708,6 @@ QByteArray QFontEngine::convertToPostscriptFontFamilyName(const QByteArray &fami QFontEngineBox::QFontEngineBox(int size) : _size(size) { - cache_cost = sizeof(QFontEngineBox); } QFontEngineBox::~QFontEngineBox() @@ -845,7 +843,6 @@ static inline glyph_t stripped(glyph_t glyph) QFontEngineMulti::QFontEngineMulti(int engineCount) { engines.fill(0, engineCount); - cache_cost = 0; } QFontEngineMulti::~QFontEngineMulti() diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index cb5c03580..e54502696 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -19,9 +19,6 @@ ** ****************************************************************************/ -#include "qdir.h" -#include "qmetatype.h" -#include "qtextstream.h" #include "qvariant.h" #include "qfile.h" #include "qabstractfileengine.h" @@ -375,7 +372,6 @@ QFontEngineFT::QFontEngineFT(const QFontDef &fd) matrix.yy = 0x10000; matrix.xy = 0; matrix.yx = 0; - cache_cost = 100; kerning_pairs_loaded = false; embolden = false; freetype = 0; diff --git a/src/gui/text/qfontengine_ft_p.h b/src/gui/text/qfontengine_ft_p.h index 5c3d2b9bb..31bb868d1 100644 --- a/src/gui/text/qfontengine_ft_p.h +++ b/src/gui/text/qfontengine_ft_p.h @@ -190,20 +190,16 @@ private: }; protected: - QFreetypeFace *freetype; int default_load_flags; - HintStyle default_hint_style; - bool embolden; - private: int loadFlags(QGlyphSet *set, int flags) const; + QFreetypeFace *freetype; + bool embolden; FT_Matrix matrix; - mutable QGlyphSet defaultGlyphSet; - QFontEngine::FaceId face_id; int xsize; diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h index db1698b18..c1e567e61 100644 --- a/src/gui/text/qfontengine_p.h +++ b/src/gui/text/qfontengine_p.h @@ -163,8 +163,6 @@ public: QAtomicInt ref; QFontDef fontDef; - int cache_cost; // amount of mem used in kb by the font - int cache_count; int fsType; bool symbol; mutable HB_FontRec hbFont; diff --git a/src/gui/text/qfontengine_x11.cpp b/src/gui/text/qfontengine_x11.cpp index 606334c59..e2f4b9dc3 100644 --- a/src/gui/text/qfontengine_x11.cpp +++ b/src/gui/text/qfontengine_x11.cpp @@ -104,7 +104,6 @@ QFontEngineMultiFT::QFontEngineMultiFT(QFontEngine *fe, FcPattern *matchedPatter engines[0] = fe; engines.at(0)->ref.ref(); fontDef = engines[0]->fontDef; - cache_cost = 100; firstFontIndex = 1; } diff --git a/src/gui/text/qfontsubset_p.h b/src/gui/text/qfontsubset_p.h index a764fe449..909ba0fc7 100644 --- a/src/gui/text/qfontsubset_p.h +++ b/src/gui/text/qfontsubset_p.h @@ -46,7 +46,7 @@ public: : object_id(obj_id), noEmbed(false), fontEngine(fe), downloaded_glyphs(0), standard_font(false) { fontEngine->ref.ref(); addGlyph(0); } ~QFontSubset() { - if (!fontEngine->ref.deref() && fontEngine->cache_count == 0) + if (!fontEngine->ref.deref()) delete fontEngine; }