diff options
author | Alexander Hulander <alexander.hulander@evoma.se> | 2023-11-21 10:41:58 +0100 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2024-02-28 17:28:11 +0000 |
commit | 9c6ab32a9c30e8dbf2d0639e04542305e88e46b7 (patch) | |
tree | 4aab4ade16b985685d7b92105ea9443d17bef0ca | |
parent | 164f8eb9d76b986ede6882d1faedd64dc547aec7 (diff) |
ShaderData: Atomically generate property values
Ensure same lock is used when generating property values for ShaderData.
Not doing so could cause a race condition if two different threads
checked if ShaderData contained property value for a given block at the
same time.
Also removes unused method to avoid similary issues in the future.
Fixes: QTBUG-111427
Change-Id: Iadf88aeb7a440bcfd46f2a8e164403fa7d6e1713
Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
(cherry picked from commit c6fafcb66814c1de1fd67c1e049d94c94ce0d2f0)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 96f5d91b05fd91de9ae09ce194bf0d95c6a5bd0e)
-rw-r--r-- | src/render/jobs/uniformblockbuilder.cpp | 3 | ||||
-rw-r--r-- | src/render/materialsystem/shaderdata.cpp | 17 | ||||
-rw-r--r-- | src/render/materialsystem/shaderdata_p.h | 3 |
3 files changed, 11 insertions, 12 deletions
diff --git a/src/render/jobs/uniformblockbuilder.cpp b/src/render/jobs/uniformblockbuilder.cpp index 132c31d9e..e917d3572 100644 --- a/src/render/jobs/uniformblockbuilder.cpp +++ b/src/render/jobs/uniformblockbuilder.cpp @@ -97,8 +97,7 @@ void UniformBlockValueBuilder::buildActiveUniformNameValueMapStructHelper(Shader // Retrieve set of {NameId -> PropertyValue} for Block const int fullBlockNameId = StringToInt::lookupId(fullBlockName); - if (!rShaderData->hasPropertyValuesForBlock(fullBlockNameId)) - rShaderData->generatePropertyValuesForBlock(fullBlockName); + rShaderData->generatePropertyValuesForBlockIfNeeded(fullBlockName); const ShaderData::PropertyValuesForBlock &propertiesForBlock = rShaderData->propertyValuesForBlock(fullBlockNameId); for (const auto &nameIdPropertyPair : propertiesForBlock) { diff --git a/src/render/materialsystem/shaderdata.cpp b/src/render/materialsystem/shaderdata.cpp index 365c1929d..a2306421b 100644 --- a/src/render/materialsystem/shaderdata.cpp +++ b/src/render/materialsystem/shaderdata.cpp @@ -122,20 +122,22 @@ void ShaderData::syncFromFrontEnd(const QNode *frontEnd, bool firstTime) } } -bool ShaderData::hasPropertyValuesForBlock(int blockName) const -{ - std::shared_lock readLocker(m_lock); - return m_blockNameToPropertyValues.find(blockName) != m_blockNameToPropertyValues.cend(); -} - const ShaderData::PropertyValuesForBlock &ShaderData::propertyValuesForBlock(int blockName) const { std::shared_lock readLocker(m_lock); return m_blockNameToPropertyValues.at(blockName); } -void ShaderData::generatePropertyValuesForBlock(const QString &fullBlockName) +void ShaderData::generatePropertyValuesForBlockIfNeeded(const QString &fullBlockName) { + const int fullBlockNameId = StringToInt::lookupId(fullBlockName); + + std::unique_lock readWriteLocker(m_lock); + const bool hasPropertyValuesForBlock = m_blockNameToPropertyValues.find(fullBlockNameId) != m_blockNameToPropertyValues.cend(); + if (hasPropertyValuesForBlock) { + return; + } + const QHash<QString, ShaderData::PropertyValue> &props = properties(); ShaderData::PropertyValuesForBlock valueBlock; @@ -162,7 +164,6 @@ void ShaderData::generatePropertyValuesForBlock(const QString &fullBlockName) ++it; } - std::unique_lock writeLocker(m_lock); m_blockNameToPropertyValues[StringToInt::lookupId(fullBlockName)] = std::move(valueBlock); } diff --git a/src/render/materialsystem/shaderdata_p.h b/src/render/materialsystem/shaderdata_p.h index 440819e38..cf29742b6 100644 --- a/src/render/materialsystem/shaderdata_p.h +++ b/src/render/materialsystem/shaderdata_p.h @@ -74,9 +74,8 @@ public: // Block.Property nameId, property nameId, PropertyValue * using PropertyValuesForBlock = std::vector<std::tuple<int, int, const PropertyValue *>>; - bool hasPropertyValuesForBlock(int blockNameId) const; const PropertyValuesForBlock &propertyValuesForBlock(int blockNameId) const; - void generatePropertyValuesForBlock(const QString &blockName); + void generatePropertyValuesForBlockIfNeeded(const QString &blockName); protected: PropertyReaderInterfacePtr m_propertyReader; |