Changeset View
Changeset View
Standalone View
Standalone View
source/graphics/TextureConverter.cpp
Show First 20 Lines • Show All 278 Lines • ▼ Show 20 Lines | CTextureConverter::CTextureConverter(PIVFS vfs, bool highQuality) : | ||||
m_VFS(vfs), m_HighQuality(highQuality), m_Shutdown(false) | m_VFS(vfs), m_HighQuality(highQuality), m_Shutdown(false) | ||||
{ | { | ||||
// Verify that we are running with at least the version we were compiled with, | // Verify that we are running with at least the version we were compiled with, | ||||
// to avoid bugs caused by ABI changes | // to avoid bugs caused by ABI changes | ||||
#if CONFIG2_NVTT | #if CONFIG2_NVTT | ||||
ENSURE(nvtt::version() >= NVTT_VERSION); | ENSURE(nvtt::version() >= NVTT_VERSION); | ||||
#endif | #endif | ||||
// Set up the worker thread: | |||||
int ret; | |||||
// Use SDL semaphores since OS X doesn't implement sem_init | |||||
m_WorkerSem = SDL_CreateSemaphore(0); | |||||
ENSURE(m_WorkerSem); | |||||
m_WorkerThread = std::thread(RunThread, this); | m_WorkerThread = std::thread(RunThread, this); | ||||
// Maybe we should share some centralised pool of worker threads? | // Maybe we should share some centralised pool of worker threads? | ||||
// For now we'll just stick with a single thread for this specific use. | // For now we'll just stick with a single thread for this specific use. | ||||
} | } | ||||
CTextureConverter::~CTextureConverter() | CTextureConverter::~CTextureConverter() | ||||
{ | { | ||||
// Tell the thread to shut down | // Tell the thread to shut down | ||||
{ | { | ||||
std::lock_guard<std::mutex> lock(m_WorkerMutex); | std::lock_guard<std::mutex> lock(m_WorkerMutex); | ||||
m_Shutdown = true; | m_Shutdown = true; | ||||
} | } | ||||
// Wake it up so it sees the notification | // Wake it up so it sees the notification | ||||
SDL_SemPost(m_WorkerSem); | m_WorkerCV.notify_all(); | ||||
// Wait for it to shut down cleanly | // Wait for it to shut down cleanly | ||||
m_WorkerThread.join(); | m_WorkerThread.join(); | ||||
// Clean up resources | |||||
SDL_DestroySemaphore(m_WorkerSem); | |||||
} | } | ||||
bool CTextureConverter::ConvertTexture(const CTexturePtr& texture, const VfsPath& src, const VfsPath& dest, const Settings& settings) | bool CTextureConverter::ConvertTexture(const CTexturePtr& texture, const VfsPath& src, const VfsPath& dest, const Settings& settings) | ||||
{ | { | ||||
shared_ptr<u8> file; | shared_ptr<u8> file; | ||||
size_t fileSize; | size_t fileSize; | ||||
if (m_VFS->LoadFile(src, file, fileSize) < 0) | if (m_VFS->LoadFile(src, file, fileSize) < 0) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 135 Lines • ▼ Show 20 Lines | #if CONFIG2_NVTT | ||||
} | } | ||||
{ | { | ||||
std::lock_guard<std::mutex> lock(m_WorkerMutex); | std::lock_guard<std::mutex> lock(m_WorkerMutex); | ||||
m_RequestQueue.push_back(request); | m_RequestQueue.push_back(request); | ||||
} | } | ||||
// Wake up the worker thread | // Wake up the worker thread | ||||
SDL_SemPost(m_WorkerSem); | m_WorkerCV.notify_all(); | ||||
return true; | return true; | ||||
#else | #else | ||||
LOGERROR("Failed to convert texture \"%s\" (NVTT not available)", src.string8()); | LOGERROR("Failed to convert texture \"%s\" (NVTT not available)", src.string8()); | ||||
return false; | return false; | ||||
#endif | #endif | ||||
} | } | ||||
▲ Show 20 Lines • Show All 50 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
bool CTextureConverter::IsBusy() | bool CTextureConverter::IsBusy() | ||||
{ | { | ||||
std::lock_guard<std::mutex> lock(m_WorkerMutex); | std::lock_guard<std::mutex> lock(m_WorkerMutex); | ||||
bool busy = !m_RequestQueue.empty(); | bool busy = !m_RequestQueue.empty(); | ||||
return busy; | return busy; | ||||
} | } | ||||
Stan: Why the need for the scope and busy variable here ? | |||||
Done Inline Actionsprobably un-necessary, I ran into an issue but it wasn't related here. wraitii: probably un-necessary, I ran into an issue but it wasn't related here. | |||||
void CTextureConverter::RunThread(CTextureConverter* textureConverter) | void CTextureConverter::RunThread(CTextureConverter* textureConverter) | ||||
{ | { | ||||
debug_SetThreadName("TextureConverter"); | debug_SetThreadName("TextureConverter"); | ||||
g_Profiler2.RegisterCurrentThread("texconv"); | g_Profiler2.RegisterCurrentThread("texconv"); | ||||
#if CONFIG2_NVTT | #if CONFIG2_NVTT | ||||
// Wait until the main thread wakes us up | // Wait until the main thread wakes us up | ||||
while (SDL_SemWait(textureConverter->m_WorkerSem) == 0) | while (true) | ||||
{ | { | ||||
std::unique_lock<std::mutex> wait_lock(textureConverter->m_WorkerMutex); | |||||
textureConverter->m_WorkerCV.wait(wait_lock, [&textureConverter] { return textureConverter->m_Shutdown; }); | |||||
g_Profiler2.RecordSyncMarker(); | g_Profiler2.RecordSyncMarker(); | ||||
PROFILE2_EVENT("wakeup"); | PROFILE2_EVENT("wakeup"); | ||||
shared_ptr<ConversionRequest> request; | shared_ptr<ConversionRequest> request; | ||||
{ | { | ||||
std::lock_guard<std::mutex> lock(textureConverter->m_WorkerMutex); | std::lock_guard<std::mutex> lock(textureConverter->m_WorkerMutex); | ||||
if (textureConverter->m_Shutdown) | if (textureConverter->m_Shutdown) | ||||
▲ Show 20 Lines • Show All 44 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator
Why the need for the scope and busy variable here ?