void HiresTexture::Init() { size_sum.store(0); size_t sys_mem = MemPhysical(); size_t recommended_min_mem = 2 * size_t(1024 * 1024 * 1024); // keep 2GB memory for system stability if system RAM is 4GB+ - use half of memory in other cases max_mem = (sys_mem / 2 < recommended_min_mem) ? (sys_mem / 2) : (sys_mem - recommended_min_mem); Update(); }
void HiresTexture::Prefetch() { Common::SetCurrentThreadName("Prefetcher"); size_t size_sum = 0; size_t sys_mem = MemPhysical(); size_t recommended_min_mem = 2 * size_t(1024 * 1024 * 1024); // keep 2GB memory for system stability if system RAM is 4GB+ - use half of memory in other cases size_t max_mem = (sys_mem / 2 < recommended_min_mem) ? (sys_mem / 2) : (sys_mem - recommended_min_mem); u32 starttime = Common::Timer::GetTimeMs(); for (const auto& entry : s_textureMap) { const std::string& base_filename = entry.first; if (base_filename.find("_mip") == std::string::npos) { { // try to get this mutex first, so the video thread is allow to get the real mutex faster std::unique_lock<std::mutex> lk(s_textureCacheAquireMutex); } std::unique_lock<std::mutex> lk(s_textureCacheMutex); auto iter = s_textureCache.find(base_filename); if (iter == s_textureCache.end()) { // unlock while loading a texture. This may result in a race condition where we'll load a texture twice, // but it reduces the stuttering a lot. Notice: The loading library _must_ be thread safe now. // But bad luck, SOIL isn't, so TODO: remove SOIL usage here and use libpng directly // Also TODO: remove s_textureCacheAquireMutex afterwards. It won't be needed as the main mutex will be locked rarely //lk.unlock(); std::unique_ptr<HiresTexture> texture = Load(base_filename, 0, 0); //lk.lock(); if (texture) { std::shared_ptr<HiresTexture> ptr(std::move(texture)); iter = s_textureCache.insert(iter, std::make_pair(base_filename, ptr)); } } if (iter != s_textureCache.end()) { for (const Level& l : iter->second->m_levels) { size_sum += l.data_size; } } } if (s_textureCacheAbortLoading.IsSet()) { return; } if (size_sum > max_mem) { g_Config.bCacheHiresTextures = false; OSD::AddMessage(StringFromFormat("Custom Textures prefetching after %.1f MB aborted, not enough RAM available", size_sum / (1024.0 * 1024.0)), 10000); return; } } u32 stoptime = Common::Timer::GetTimeMs(); OSD::AddMessage(StringFromFormat("Custom Textures loaded, %.1f MB in %.1f s", size_sum / (1024.0 * 1024.0), (stoptime - starttime) / 1000.0), 10000); }