From 5edb0313ed6e8c74afda277c0964819330f54a9f Mon Sep 17 00:00:00 2001 From: Cyril Pichard Date: Thu, 25 Jan 2024 10:45:48 +0000 Subject: [PATCH 1/2] make the UsdArnoldReaderRegistry non static --- CHANGELOG.md | 1 + libs/translator/reader/reader.cpp | 50 ++++++++++++++----------------- libs/translator/reader/reader.h | 24 ++++----------- 3 files changed, 28 insertions(+), 47 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c75c886a3d..03ff5778c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ - [usd#1808](https://github.com/Autodesk/arnold-usd/issues/1808) - Fix the error "Cannot load _htoa_pygeo library required for volume rendering in Solaris" in Houdini 19.5+. - [usd#1812](https://github.com/Autodesk/arnold-usd/issues/1812) - Improve Material network creation by caching the node entries and the osl code. +- [usd#1781](https://github.com/Autodesk/arnold-usd/issues/1781) - Fix a crash happening in a aiStandin usd when scrolling the timeline in maya. ## [7.2.5.1] - 2024-01-18 diff --git a/libs/translator/reader/reader.cpp b/libs/translator/reader/reader.cpp index 7be72bf457..6a080355e9 100644 --- a/libs/translator/reader/reader.cpp +++ b/libs/translator/reader/reader.cpp @@ -82,22 +82,29 @@ namespace { WorkDispatcher *dispatcher; }; }; -// global reader registry, will be used in the default case -static UsdArnoldReaderRegistry *s_readerRegistry = nullptr; -static int s_mustDeleteRegistry = 0; + static AtMutex s_globalReaderMutex; static std::unordered_map s_cacheRefCount; - +UsdArnoldReader::UsdArnoldReader() + : _procParent(nullptr), + _universe(nullptr), + _convert(true), + _debug(false), + _threadCount(1), + _mask(AI_NODE_ALL), + _defaultShader(nullptr), + _hasRootPrim(false), + _readStep(READ_NOT_STARTED), + _purpose(UsdGeomTokens->render), + _dispatcher(nullptr), + _readerRegistry(new UsdArnoldReaderRegistry()) + { + _readerRegistry->RegisterPrimitiveReaders(); + } UsdArnoldReader::~UsdArnoldReader() { - if (s_mustDeleteRegistry && _registry) { - delete _registry; - s_mustDeleteRegistry = false; - _registry = s_readerRegistry; - } - // What do we want to do at destruction here ? - // Should we delete the created nodes in case there was no procParent ? + delete _readerRegistry; } void UsdArnoldReader::TraverseStage(UsdPrim *rootPrim, UsdArnoldReaderContext &context, @@ -284,20 +291,6 @@ void UsdArnoldReader::ReadStage(UsdStageRefPtr stage, const std::string &path) // and the eventual procedural mask set above _mask = _mask & procMask; - // eventually use a dedicated registry - if (_registry == nullptr) { - // No registry was set (default), let's use the global one - { - std::lock_guard guard(s_globalReaderMutex); - if (s_readerRegistry == nullptr) { - s_readerRegistry = new UsdArnoldReaderRegistry(); // initialize the global registry - s_readerRegistry->RegisterPrimitiveReaders(); - } - } - _registry = s_readerRegistry; - } else - _registry->RegisterPrimitiveReaders(); - UsdPrim *rootPrimPtr = nullptr; if (!path.empty()) { @@ -602,7 +595,7 @@ void UsdArnoldReader::ReadPrimitive(const UsdPrim &prim, UsdArnoldReaderContext _renderSettings = objName; } - UsdArnoldPrimReader *primReader = _registry->GetPrimReader(objType); + UsdArnoldPrimReader *primReader = _readerRegistry->GetPrimReader(objType); if (primReader && (_mask & primReader->GetType())) { if (_debug) { std::string txt; @@ -699,8 +692,9 @@ void UsdArnoldReader::SetProceduralParent(AtNode *node) } void UsdArnoldReader::CreateViewportRegistry(AtProcViewportMode mode, const AtParamValueMap* params) { - s_mustDeleteRegistry = true; - _registry = new UsdArnoldViewportReaderRegistry(mode, params); + delete _readerRegistry; + _readerRegistry = new UsdArnoldViewportReaderRegistry(mode, params); + _readerRegistry->RegisterPrimitiveReaders(); } void UsdArnoldReader::SetUniverse(AtUniverse *universe) diff --git a/libs/translator/reader/reader.h b/libs/translator/reader/reader.h index 11254cd9a6..ee7abe6f77 100644 --- a/libs/translator/reader/reader.h +++ b/libs/translator/reader/reader.h @@ -47,21 +47,7 @@ class UsdArnoldReaderRegistry; class UsdArnoldReader : public ProceduralReader { public: - UsdArnoldReader() - : _procParent(nullptr), - _universe(nullptr), - _registry(nullptr), - _convert(true), - _debug(false), - _threadCount(1), - _mask(AI_NODE_ALL), - _defaultShader(nullptr), - _hasRootPrim(false), - _readStep(READ_NOT_STARTED), - _purpose(UsdGeomTokens->render), - _dispatcher(nullptr) - { - } + UsdArnoldReader(); ~UsdArnoldReader(); void ReadStage(UsdStageRefPtr stage, @@ -74,7 +60,7 @@ class UsdArnoldReader : public ProceduralReader { void SetProceduralParent(AtNode *node) override; void SetUniverse(AtUniverse *universe) override; - // void SetRegistry(UsdArnoldReaderRegistry *registry); + void CreateViewportRegistry(AtProcViewportMode mode, const AtParamValueMap* params) override; void SetFrame(float frame) override; void SetMotionBlur(bool motionBlur, float motionStart = 0.f, float motionEnd = 0.f) override; @@ -89,7 +75,7 @@ class UsdArnoldReader : public ProceduralReader { const UsdStageRefPtr &GetStage() const { return _stage; } const std::vector &GetNodes() const override { return _nodes; } float GetFrame() const { return _time.frame; } - UsdArnoldReaderRegistry *GetRegistry() { return _registry; } + UsdArnoldReaderRegistry *GetRegistry() { return _readerRegistry; } AtUniverse *GetUniverse() { return _universe; } const AtNode *GetProceduralParent() const { return _procParent; } bool GetDebug() const { return _debug; } @@ -206,8 +192,6 @@ class UsdArnoldReader : public ProceduralReader { private: const AtNode *_procParent; // the created nodes are children of a procedural parent AtUniverse *_universe; // only set if a specific universe is being used - UsdArnoldReaderRegistry *_registry; // custom registry used for this reader. If null, a global - // registry will be used. TimeSettings _time; bool _convert; // do we want to convert the primitives attributes bool _debug; @@ -235,6 +219,8 @@ class UsdArnoldReader : public ProceduralReader { AtString _pxrMtlxPath; // environment variable PXR_MTLX_STDLIB_SEARCH_PATHS unsigned int _id = 0; ///< Arnold shape ID for the procedural. + // Reader registry, will be used in the default case + UsdArnoldReaderRegistry *_readerRegistry = nullptr; }; class UsdArnoldReaderThreadContext : public ArnoldAPIAdapter { From c57fabf89ef412bacead503adb3b36d541e5f5d3 Mon Sep 17 00:00:00 2001 From: Cyril Pichard Date: Thu, 25 Jan 2024 12:26:44 +0000 Subject: [PATCH 2/2] register readers before reading --- libs/translator/reader/reader.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/libs/translator/reader/reader.cpp b/libs/translator/reader/reader.cpp index 6a080355e9..e0c89caeaa 100644 --- a/libs/translator/reader/reader.cpp +++ b/libs/translator/reader/reader.cpp @@ -99,9 +99,7 @@ UsdArnoldReader::UsdArnoldReader() _purpose(UsdGeomTokens->render), _dispatcher(nullptr), _readerRegistry(new UsdArnoldReaderRegistry()) - { - _readerRegistry->RegisterPrimitiveReaders(); - } + {} UsdArnoldReader::~UsdArnoldReader() { delete _readerRegistry; @@ -291,6 +289,8 @@ void UsdArnoldReader::ReadStage(UsdStageRefPtr stage, const std::string &path) // and the eventual procedural mask set above _mask = _mask & procMask; + _readerRegistry->RegisterPrimitiveReaders(); + UsdPrim *rootPrimPtr = nullptr; if (!path.empty()) { @@ -694,7 +694,6 @@ void UsdArnoldReader::SetProceduralParent(AtNode *node) void UsdArnoldReader::CreateViewportRegistry(AtProcViewportMode mode, const AtParamValueMap* params) { delete _readerRegistry; _readerRegistry = new UsdArnoldViewportReaderRegistry(mode, params); - _readerRegistry->RegisterPrimitiveReaders(); } void UsdArnoldReader::SetUniverse(AtUniverse *universe)