Improved thread safety in TextureData and TextureDataManager.

This commit is contained in:
Leon Styhre 2021-11-15 23:33:16 +01:00
parent 7b06e9fb8b
commit 999b9a6c04
2 changed files with 32 additions and 8 deletions

View file

@ -179,7 +179,9 @@ bool TextureData::load()
const ResourceData& data = rm->getFileData(mPath);
// Is it an SVG?
if (Utils::String::toLower(mPath.substr(mPath.size() - 4, std::string::npos)) == ".svg") {
std::unique_lock<std::mutex> lock(mMutex);
mScalable = true;
lock.unlock();
std::string dataString;
dataString.assign(std::string(reinterpret_cast<char*>(data.ptr.get()), data.length));
retval = initSVGFromMemory(dataString);
@ -243,35 +245,51 @@ void TextureData::releaseRAM()
size_t TextureData::width()
{
if (mWidth == 0)
std::unique_lock<std::mutex> lock(mMutex);
if (mWidth == 0) {
lock.unlock();
load();
}
return static_cast<size_t>(mWidth);
}
size_t TextureData::height()
{
if (mHeight == 0)
std::unique_lock<std::mutex> lock(mMutex);
if (mHeight == 0) {
lock.unlock();
load();
}
return static_cast<size_t>(mHeight);
}
float TextureData::sourceWidth()
{
if (mSourceWidth == 0)
std::unique_lock<std::mutex> lock(mMutex);
if (mSourceWidth == 0) {
lock.unlock();
load();
}
return mSourceWidth;
}
float TextureData::sourceHeight()
{
if (mSourceHeight == 0)
std::unique_lock<std::mutex> lock(mMutex);
if (mSourceHeight == 0) {
lock.unlock();
load();
}
return mSourceHeight;
}
void TextureData::setSourceSize(float width, float height)
{
if (mScalable) {
std::unique_lock<std::mutex> lock(mMutex);
bool scalable = mScalable;
lock.unlock();
if (scalable) {
if ((mSourceWidth != width) || (mSourceHeight != height)) {
mSourceWidth = width;
mSourceHeight = height;
@ -283,6 +301,7 @@ void TextureData::setSourceSize(float width, float height)
size_t TextureData::getVRAMUsage()
{
std::unique_lock<std::mutex> lock(mMutex);
if (mTextureID != 0 || !mDataRGBA.empty())
return mWidth * mHeight * 4;
else

View file

@ -16,7 +16,7 @@
TextureDataManager::TextureDataManager()
{
unsigned char data[5 * 5 * 4];
mBlank = std::shared_ptr<TextureData>(new TextureData(false));
mBlank = std::make_shared<TextureData>(false);
for (int i = 0; i < (5 * 5); i++) {
data[i * 4] = (i % 2) * 255;
data[i * 4 + 1] = (i % 2) * 255;
@ -36,7 +36,7 @@ TextureDataManager::~TextureDataManager()
std::shared_ptr<TextureData> TextureDataManager::add(const TextureResource* key, bool tiled)
{
remove(key);
std::shared_ptr<TextureData> data(new TextureData(tiled));
std::shared_ptr<TextureData> data = std::make_shared<TextureData>(tiled);
mTextures.push_front(data);
mTextureLookup[key] = mTextures.cbegin();
return data;
@ -158,11 +158,13 @@ TextureLoader::TextureLoader()
TextureLoader::~TextureLoader()
{
// Just abort any waiting texture.
std::unique_lock<std::mutex> lock(mMutex);
mTextureDataQ.clear();
mTextureDataLookup.clear();
// Exit the thread.
mExit = true;
lock.unlock();
mEvent.notify_one();
mThread->join();
mThread.reset();
@ -170,7 +172,9 @@ TextureLoader::~TextureLoader()
void TextureLoader::threadProc()
{
while (!mExit) {
bool exit = false;
while (!exit) {
std::shared_ptr<TextureData> textureData;
{
// Wait for an event to say there is something in the queue.
@ -195,6 +199,7 @@ void TextureLoader::threadProc()
mTextureDataLookup.erase(mTextureDataLookup.find(textureData.get()));
}
}
exit = mExit;
}
}