Fixed a performance regression caused by excessive mutex locks.

This commit is contained in:
Leon Styhre 2021-11-18 17:20:59 +01:00
parent e91e23a053
commit 0314b2d439
3 changed files with 23 additions and 24 deletions

View file

@ -33,9 +33,10 @@ TextureData::TextureData(bool tile)
, mSourceWidth{0.0f} , mSourceWidth{0.0f}
, mSourceHeight{0.0f} , mSourceHeight{0.0f}
, mScalable{false} , mScalable{false}
, mHasRGBAData{false}
, mPendingRasterization{false}
, mLinearMagnify{false} , mLinearMagnify{false}
, mForceRasterization{false} , mForceRasterization{false}
, mPendingRasterization{false}
{ {
} }
@ -55,9 +56,9 @@ void TextureData::initFromPath(const std::string& path)
bool TextureData::initSVGFromMemory(const std::string& fileData) bool TextureData::initSVGFromMemory(const std::string& fileData)
{ {
// If already initialized then don't process it again.
std::unique_lock<std::mutex> lock{mMutex}; std::unique_lock<std::mutex> lock{mMutex};
// If already initialized then don't process it again.
if (!mDataRGBA.empty()) if (!mDataRGBA.empty())
return true; return true;
@ -111,6 +112,7 @@ bool TextureData::initSVGFromMemory(const std::string& fileData)
ImageIO::flipPixelsVert(mDataRGBA.data(), mWidth, mHeight); ImageIO::flipPixelsVert(mDataRGBA.data(), mWidth, mHeight);
mPendingRasterization = false; mPendingRasterization = false;
mHasRGBAData = true;
} }
else { else {
// TODO: Fix this properly instead of using the single byte texture workaround. // TODO: Fix this properly instead of using the single byte texture workaround.
@ -125,9 +127,6 @@ bool TextureData::initSVGFromMemory(const std::string& fileData)
bool TextureData::initImageFromMemory(const unsigned char* fileData, size_t length) bool TextureData::initImageFromMemory(const unsigned char* fileData, size_t length)
{ {
size_t width;
size_t height;
// If already initialized then don't process it again. // If already initialized then don't process it again.
{ {
std::unique_lock<std::mutex> lock(mMutex); std::unique_lock<std::mutex> lock(mMutex);
@ -135,6 +134,9 @@ bool TextureData::initImageFromMemory(const unsigned char* fileData, size_t leng
return true; return true;
} }
size_t width;
size_t height;
std::vector<unsigned char> imageRGBA = ImageIO::loadFromMemoryRGBA32( std::vector<unsigned char> imageRGBA = ImageIO::loadFromMemoryRGBA32(
static_cast<const unsigned char*>(fileData), length, width, height); static_cast<const unsigned char*>(fileData), length, width, height);
@ -166,6 +168,8 @@ bool TextureData::initFromRGBA(const unsigned char* dataRGBA, size_t width, size
mWidth = static_cast<int>(width); mWidth = static_cast<int>(width);
mHeight = static_cast<int>(height); mHeight = static_cast<int>(height);
mHasRGBAData = true;
return true; return true;
} }
@ -196,7 +200,8 @@ bool TextureData::isLoaded()
{ {
std::unique_lock<std::mutex> lock(mMutex); std::unique_lock<std::mutex> lock(mMutex);
if (!mDataRGBA.empty() || mTextureID != 0) if (!mDataRGBA.empty() || mTextureID != 0)
return true; if (mHasRGBAData || mPendingRasterization || mTextureID != 0)
return true;
return false; return false;
} }
@ -238,14 +243,13 @@ void TextureData::releaseRAM()
if (!mDataRGBA.empty()) { if (!mDataRGBA.empty()) {
mDataRGBA.clear(); mDataRGBA.clear();
mDataRGBA.swap(swapVector); mDataRGBA.swap(swapVector);
mHasRGBAData = false;
} }
} }
size_t TextureData::width() size_t TextureData::width()
{ {
std::unique_lock<std::mutex> lock(mMutex);
if (mWidth == 0) { if (mWidth == 0) {
lock.unlock();
load(); load();
} }
return static_cast<size_t>(mWidth); return static_cast<size_t>(mWidth);
@ -253,9 +257,7 @@ size_t TextureData::width()
size_t TextureData::height() size_t TextureData::height()
{ {
std::unique_lock<std::mutex> lock(mMutex);
if (mHeight == 0) { if (mHeight == 0) {
lock.unlock();
load(); load();
} }
return static_cast<size_t>(mHeight); return static_cast<size_t>(mHeight);
@ -263,9 +265,7 @@ size_t TextureData::height()
float TextureData::sourceWidth() float TextureData::sourceWidth()
{ {
std::unique_lock<std::mutex> lock(mMutex);
if (mSourceWidth == 0) { if (mSourceWidth == 0) {
lock.unlock();
load(); load();
} }
return mSourceWidth; return mSourceWidth;
@ -273,9 +273,7 @@ float TextureData::sourceWidth()
float TextureData::sourceHeight() float TextureData::sourceHeight()
{ {
std::unique_lock<std::mutex> lock(mMutex);
if (mSourceHeight == 0) { if (mSourceHeight == 0) {
lock.unlock();
load(); load();
} }
return mSourceHeight; return mSourceHeight;
@ -295,8 +293,7 @@ void TextureData::setSourceSize(float width, float height)
size_t TextureData::getVRAMUsage() size_t TextureData::getVRAMUsage()
{ {
std::unique_lock<std::mutex> lock(mMutex); if (mHasRGBAData || mTextureID != 0)
if (mTextureID != 0 || !mDataRGBA.empty())
return mWidth * mHeight * 4; return mWidth * mHeight * 4;
else else
return 0; return 0;

View file

@ -56,7 +56,7 @@ public:
float sourceWidth(); float sourceWidth();
float sourceHeight(); float sourceHeight();
void setSourceSize(float width, float height); void setSourceSize(float width, float height);
glm::vec2 getSize() { return glm::vec2{mWidth, mHeight}; } glm::vec2 getSize() { return glm::vec2{static_cast<int>(mWidth), static_cast<int>(mHeight)}; }
// Whether to use linear filtering when magnifying the texture. // Whether to use linear filtering when magnifying the texture.
void setLinearMagnify(bool setting) { mLinearMagnify = setting; } void setLinearMagnify(bool setting) { mLinearMagnify = setting; }
@ -72,19 +72,21 @@ public:
private: private:
std::mutex mMutex; std::mutex mMutex;
bool mTile; bool mTile;
std::string mPath; std::string mPath;
unsigned int mTextureID; std::atomic<unsigned int> mTextureID;
std::vector<unsigned char> mDataRGBA; std::vector<unsigned char> mDataRGBA;
int mWidth; std::atomic<int> mWidth;
int mHeight; std::atomic<int> mHeight;
float mSourceWidth; std::atomic<float> mSourceWidth;
float mSourceHeight; std::atomic<float> mSourceHeight;
std::atomic<bool> mScalable; std::atomic<bool> mScalable;
std::atomic<bool> mHasRGBAData;
std::atomic<bool> mPendingRasterization;
bool mLinearMagnify; bool mLinearMagnify;
bool mReloadable; bool mReloadable;
bool mForceRasterization; bool mForceRasterization;
bool mPendingRasterization;
}; };
#endif // ES_CORE_RESOURCES_TEXTURE_DATA_H #endif // ES_CORE_RESOURCES_TEXTURE_DATA_H

View file

@ -40,7 +40,7 @@ public:
std::vector<unsigned char> getRawRGBAData(); std::vector<unsigned char> getRawRGBAData();
// Has the image been loaded but not yet been rasterized as the size was not known? // Has the image been loaded but not yet been rasterized as the size was not known?
bool getPendingRasterization() bool getPendingRasterization() const
{ {
return (mTextureData != nullptr ? mTextureData->getPendingRasterization() : false); return (mTextureData != nullptr ? mTextureData->getPendingRasterization() : false);
} }