예제 #1
0
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();
}
예제 #2
0
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);
}