Changeset View
Changeset View
Standalone View
Standalone View
source/graphics/TextureConverter.cpp
Show First 20 Lines • Show All 91 Lines • ▼ Show 20 Lines | |||||
/** | /** | ||||
* Response from the asynchronous task. | * Response from the asynchronous task. | ||||
*/ | */ | ||||
struct CTextureConverter::ConversionResult | struct CTextureConverter::ConversionResult | ||||
{ | { | ||||
VfsPath dest; | VfsPath dest; | ||||
CTexturePtr texture; | CTexturePtr texture; | ||||
BufferOutputHandler output; | BufferOutputHandler output; | ||||
bool ret; // true if the conversion succeeded | }; | ||||
struct WriteFileError : ConversionError | |||||
{ | |||||
using ConversionError::ConversionError; | |||||
}; | }; | ||||
#endif // CONFIG2_NVTT | #endif // CONFIG2_NVTT | ||||
void CTextureConverter::Settings::Hash(MD5& hash) | void CTextureConverter::Settings::Hash(MD5& hash) | ||||
{ | { | ||||
hash.Update((const u8*)&format, sizeof(format)); | hash.Update((const u8*)&format, sizeof(format)); | ||||
hash.Update((const u8*)&mipmap, sizeof(mipmap)); | hash.Update((const u8*)&mipmap, sizeof(mipmap)); | ||||
▲ Show 20 Lines • Show All 361 Lines • ▼ Show 20 Lines | m_ResultQueue.push(Threading::TaskManager::Instance().PushTask([request = std::move(request)] | ||||
std::unique_ptr<ConversionResult> result = std::make_unique<ConversionResult>(); | std::unique_ptr<ConversionResult> result = std::make_unique<ConversionResult>(); | ||||
result->dest = request->dest; | result->dest = request->dest; | ||||
result->texture = request->texture; | result->texture = request->texture; | ||||
request->outputOptions.setOutputHandler(&result->output); | request->outputOptions.setOutputHandler(&result->output); | ||||
// Perform the compression | // Perform the compression | ||||
nvtt::Compressor compressor; | nvtt::Compressor compressor; | ||||
result->ret = compressor.process(request->inputOptions, request->compressionOptions, | const auto ret = compressor.process(request->inputOptions, request->compressionOptions, | ||||
request->outputOptions); | request->outputOptions); | ||||
if (!ret) | |||||
throw ConversionError{request->texture}; | |||||
return result; | return result; | ||||
}, Threading::TaskPriority::LOW)); | }, Threading::TaskPriority::LOW)); | ||||
return true; | return true; | ||||
#else // CONFIG2_NVTT | #else // CONFIG2_NVTT | ||||
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 // !CONFIG2_NVTT | #endif // !CONFIG2_NVTT | ||||
} | } | ||||
bool CTextureConverter::Poll(CTexturePtr& texture, VfsPath& dest, bool& ok) | bool CTextureConverter::Poll(CTexturePtr& texture, VfsPath& dest) | ||||
{ | { | ||||
#if CONFIG2_NVTT | #if CONFIG2_NVTT | ||||
if (m_ResultQueue.empty() || !m_ResultQueue.front().IsReady()) | if (m_ResultQueue.empty() || !m_ResultQueue.front().IsReady()) | ||||
{ | { | ||||
// no work to do | // no work to do | ||||
return false; | return false; | ||||
} | } | ||||
std::unique_ptr<ConversionResult> result = m_ResultQueue.front().Get(); | std::unique_ptr<ConversionResult> result = m_ResultQueue.front().Get(); | ||||
m_ResultQueue.pop(); | m_ResultQueue.pop(); | ||||
phosit: The element should be poped before `.Get` is called. | |||||
if (!result->ret) | |||||
{ | |||||
// conversion had failed | |||||
ok = false; | |||||
return true; | |||||
} | |||||
// Move output into a correctly-aligned buffer | // Move output into a correctly-aligned buffer | ||||
size_t size = result->output.buffer.size(); | size_t size = result->output.buffer.size(); | ||||
std::shared_ptr<u8> file; | std::shared_ptr<u8> file; | ||||
AllocateAligned(file, size, maxSectorSize); | AllocateAligned(file, size, maxSectorSize); | ||||
memcpy(file.get(), &result->output.buffer[0], size); | memcpy(file.get(), &result->output.buffer[0], size); | ||||
if (m_VFS->CreateFile(result->dest, file, size) < 0) | if (m_VFS->CreateFile(result->dest, file, size) < 0) | ||||
{ | throw WriteFileError{result->texture}; | ||||
// error writing file | |||||
ok = false; | |||||
return true; | |||||
} | |||||
// Succeeded in converting texture | // Succeeded in converting texture | ||||
texture = result->texture; | texture = result->texture; | ||||
dest = result->dest; | dest = result->dest; | ||||
ok = true; | |||||
return true; | return true; | ||||
#else // CONFIG2_NVTT | #else // CONFIG2_NVTT | ||||
return false; | return false; | ||||
#endif // !CONFIG2_NVTT | #endif // !CONFIG2_NVTT | ||||
} | } | ||||
bool CTextureConverter::IsBusy() const | bool CTextureConverter::IsBusy() const | ||||
{ | { | ||||
#if CONFIG2_NVTT | #if CONFIG2_NVTT | ||||
return m_ResultQueue.size() >= OPTIMAL_UTILIZATION; | return m_ResultQueue.size() >= OPTIMAL_UTILIZATION; | ||||
#else // CONFIG2_NVTT | #else // CONFIG2_NVTT | ||||
return false; | return false; | ||||
#endif // !CONFIG2_NVTT | #endif // !CONFIG2_NVTT | ||||
} | } |
Wildfire Games · Phabricator
The element should be poped before .Get is called.