Emoticon Pixmap Caching System¶
Overview¶
This document describes the centralized emoticon pixmap caching system in GuiThumbMgr that eliminates the ~10 second delay when opening emoticon-using features.
Problem¶
Loading 50 emoticon SVGs synchronously takes ~10 seconds. This delay occurred when opening: - InputFaceWidget (face picker in chat) - AppletGalleryEmoticon - Random Person Connect - Any feature needing emoticon pixmaps
Previously, each consumer loaded SVGs independently and synchronously.
Solution¶
Centralize emoticon pixmap storage in GuiThumbMgr with:
1. 48×48 base pixmaps cached in memory
2. Background loading after login via QTimer
3. Fast path: Load from existing .nlt files (created by gallery system)
4. Slow path: Load from SVG resources (first time only)
5. On-demand scaling: Return scaled copies from the 48×48 cache
Architecture¶
Cache Storage (GuiThumbMgr)¶
// 48x48 pixmap cache
static constexpr int kEmoticonCacheSize = 48;
static constexpr int kEmoticonCount = 50;
std::vector<QPixmap> m_EmoticonPixmapCache; // 50 cached pixmaps
std::vector<bool> m_EmoticonLoaded; // tracking flags
bool m_EmoticonCacheReady; // all loaded flag
Loading Flow¶
- Login completion →
onSystemReady(true)→startEmoticonCacheLoad() - Background loading via QTimer: 5 emoticons per 50ms tick
- For each emoticon:
- Try loading from .nlt file (fast - these are PNG files)
- Fallback: Load from SVG resource (slow)
- Scale to 48×48 and store in cache
- When complete:
m_EmoticonCacheReady = true, emitsignalEmoticonCacheReady()
.nlt File Strategy¶
- Cache does NOT write .nlt files - only reads them if they exist
- Gallery system (
generateEmoticon()) creates full-size 240×240 .nlt files - If user opens gallery first → .nlt files are created → cache benefits from fast path
- If user opens face picker first → cache loads from SVG (slower, but only once per session)
Public API¶
// Get single emoticon scaled to requested size
bool getEmoticonPixmap(int emoticonNum, QSize imageSize, QPixmap& retPixmap);
// Get all 50 emoticons scaled to requested size
bool getAllEmoticonPixmaps(QSize imageSize, QVector<QPixmap>& retPixmaps);
// Check if background loading is complete
bool isEmoticonCacheReady() const;
// Manually trigger background loading (called automatically on login)
void startEmoticonCacheLoad();
// Signal emitted when cache is ready
void signalEmoticonCacheReady();
Consumer Changes¶
InputFaceWidget¶
- Removed SVG loading from constructor
- Uses
getEmoticonPixmap()inrefreshScaledPixmaps() - Loads pixmaps on-demand from cache (near-instant if cache ready)
Legacy API¶
getEmoticonImage() now redirects to getEmoticonPixmap() for backward compatibility.
AppletGalleryEmoticon¶
- Uses existing
generateEmoticonsIfNeeded()flow (creates full-size .nlt files) - Gallery thumbnails are 240×240 loaded directly from SVG for quality
- Once .nlt files exist, other features (like InputFaceWidget) benefit from fast loading
Performance Characteristics¶
| Scenario | Time |
|---|---|
| First session, open face picker early | ~10s (loads SVGs in background) |
| Subsequent face picker opens (same session) | Instant (cached) |
| After gallery has been opened once (creates .nlt files) | Fast (~1s to load PNGs) |
Design Decisions¶
- 48×48 cache size: Good balance of quality vs memory (~200KB total)
- FastTransformation: Prioritizes speed over quality for scaling
- QTimer chunked loading: Avoids UI freeze during background load
- No cache invalidation: Emoticons are only added, never changed
- Separate gallery path: Gallery uses SVG directly for 240×240 quality
Files Modified¶
- GuiThumbMgr.h - Cache members, public API
- GuiThumbMgr.cpp - Implementation
- InputFaceWidget.h - Removed unused members
- InputFaceWidget.cpp - Use cache API