Merge pull request #17709 from hrydgard/icon-cache

Save/Load the icon cache to disk if RetroAchievements are enabled.
This commit is contained in:
Henrik Rydgård authored and GitHub committed 2023-07-13 14:56:35 +02:00
commit e0fd83687d
3 files changed
+75 -1

No files matched your search

+55 -1
View File
@@ -1,3 +1,5 @@
#include <algorithm>
#include "Common/UI/IconCache.h"
#include "Common/UI/Context.h"
#include "Common/TimeUtil.h"
@@ -5,9 +7,11 @@
#include "Common/Log.h"
#define ICON_CACHE_VERSION 1
#define MK_FOURCC(str) (str[0] | ((uint8_t)str[1] << 8) | ((uint8_t)str[2] << 16) | ((uint8_t)str[3] << 24))
#define MAX_RUNTIME_CACHE_SIZE (1024 * 1024 * 4)
#define MAX_SAVED_CACHE_SIZE (1024 * 1024 * 1)
const uint32_t ICON_CACHE_MAGIC = MK_FOURCC("pICN");
IconCache g_iconCache;
@@ -28,6 +32,9 @@ struct DiskCacheEntry {
void IconCache::SaveToFile(FILE *file) {
std::unique_lock<std::mutex> lock(lock_);
// First, compute the total size. If above a threshold, remove until under.
Decimate(MAX_SAVED_CACHE_SIZE);
DiskCacheHeader header;
header.magic = ICON_CACHE_MAGIC;
header.version = ICON_CACHE_VERSION;
@@ -131,6 +138,53 @@ void IconCache::FrameUpdate() {
}
lastUpdate_ = now;
}
if (now > lastDecimate_ + 60.0) {
Decimate(MAX_RUNTIME_CACHE_SIZE);
lastDecimate_ = now;
}
}
void IconCache::Decimate(int64_t maxSize) {
// Call this under the lock.
int64_t totalSize = 0;
for (auto &iter : cache_) {
totalSize += iter.second.data.size();
}
if (totalSize <= maxSize) {
return;
}
// Create a list of all the entries, sort by date. Then delete until we reach the desired size.
struct SortEntry {
std::string key;
double usedTimestamp;
size_t size;
};
std::vector<SortEntry> sortEntries;
for (auto iter : cache_) {
sortEntries.push_back({ iter.first, iter.second.usedTimeStamp, iter.second.data.size() });
}
std::sort(sortEntries.begin(), sortEntries.end(), [](const SortEntry &a, const SortEntry &b) {
// Oldest should be last in the lsit.
return a.usedTimestamp > b.usedTimestamp;
});
while (totalSize > maxSize && !sortEntries.empty()) {
totalSize -= sortEntries.back().size;
auto iter = cache_.find(sortEntries.back().key);
if (iter != cache_.end()) {
if (iter->second.texture) {
iter->second.texture->Release();
}
cache_.erase(iter);
}
sortEntries.pop_back();
}
}
bool IconCache::GetDimensions(const std::string &key, int *width, int *height) {
+3
View File
@@ -62,6 +62,8 @@ public:
}
private:
void Decimate(int64_t maxSize);
struct Entry {
std::string data;
IconFormat format;
@@ -77,6 +79,7 @@ private:
std::mutex lock_;
double lastUpdate_ = 0.0;
double lastDecimate_ = 0.0;
};
extern IconCache g_iconCache;
+17
View File
@@ -55,6 +55,7 @@
#include "Common/UI/Screen.h"
#include "Common/UI/Context.h"
#include "Common/UI/View.h"
#include "Common/UI/IconCache.h"
#include "android/jni/app-android.h"
@@ -774,6 +775,14 @@ void NativeInit(int argc, const char *argv[], const char *savegame_dir, const ch
});
}
if (g_Config.bAchievementsEnable) {
FILE *iconCacheFile = File::OpenCFile(GetSysDirectory(DIRECTORY_CACHE) / "icon.cache", "rb");
if (iconCacheFile) {
g_iconCache.LoadFromFile(iconCacheFile);
fclose(iconCacheFile);
}
}
DEBUG_LOG(SYSTEM, "ScreenManager!");
g_screenManager = new ScreenManager();
if (g_Config.memStickDirectory.empty()) {
@@ -1367,6 +1376,14 @@ bool NativeIsRestarting() {
void NativeShutdown() {
Achievements::Shutdown();
if (g_Config.bAchievementsEnable) {
FILE *iconCacheFile = File::OpenCFile(GetSysDirectory(DIRECTORY_CACHE) / "icon.cache", "wb");
if (iconCacheFile) {
g_iconCache.SaveToFile(iconCacheFile);
fclose(iconCacheFile);
}
}
if (g_screenManager) {
g_screenManager->shutdown();
delete g_screenManager;