From ed9bb53ed1e9058cf97192382b2afd5266574a67 Mon Sep 17 00:00:00 2001 From: Pierre Baillargeon Date: Fri, 26 Jan 2024 11:19:16 -0500 Subject: [PATCH 1/2] MAYA-132438 fix slow scene load performance Maya scene load without any USD data is slower when the MayaUSD plugin is loaded. The reason behind the bad performance is that the UsdStageMap class constantly rebuilds itself because it thinks it is out of date. The reason is that its UsdStageMap::proxyShape() function assumes that it is always called to retrieve an existing proxy shape. So when it fails to find the requested proxy shape, it assumes its mapping between UFE paths and DAG paths must be stale. Those assumptions are false. The culprit is the following sequence: - Adding Maya nodes cause a UFE AddObject notification to be sent. - The Maya outliner UI wants to know if this object might be a UFE gateway node. - It asks UFE if is a gateway node. - This ends-up being routed to MayaUSD. - ProxyShapeSceneSegmentHandler::isGateway_() calls getStage(path) with the UFE path. - This ends-up calling UsdStageMap::proxyShape(). - Which triggers the cache rebuilds, as explained above. While we need to revisit how the UsdStageMap works, this would be a somewhat big and risky endeavour at this point in time. The simple fix is to not rebuild the cache when we know there are no proxy shape in existence. This fixes the performance problem for all Maya scene without USD data. --- lib/mayaUsd/nodes/proxyShapeBase.cpp | 9 +++++++++ lib/mayaUsd/nodes/proxyShapeBase.h | 3 +++ lib/mayaUsd/ufe/UsdStageMap.cpp | 6 ++++++ 3 files changed, 18 insertions(+) diff --git a/lib/mayaUsd/nodes/proxyShapeBase.cpp b/lib/mayaUsd/nodes/proxyShapeBase.cpp index a3b45ffb7e..9b71bb1500 100644 --- a/lib/mayaUsd/nodes/proxyShapeBase.cpp +++ b/lib/mayaUsd/nodes/proxyShapeBase.cpp @@ -136,6 +136,8 @@ const MString MayaUsdProxyShapeBase::displayFilterName( TfStringPrintf("%sDisplayFilter", MayaUsdProxyShapeBaseTokens->MayaTypeName.GetText()).c_str()); const MString MayaUsdProxyShapeBase::displayFilterLabel("USD Proxies"); +std::atomic g_proxyShapeInstancesCount = 0; + // Attributes MObject MayaUsdProxyShapeBase::filePathAttr; MObject MayaUsdProxyShapeBase::filePathRelativeAttr; @@ -535,6 +537,9 @@ MayaUsdProxyShapeBase* MayaUsdProxyShapeBase::GetShapeAtDagPath(const MDagPath& return pShape; } +/* static */ +int MayaUsdProxyShapeBase::countProxyShapeInstances() { return g_proxyShapeInstancesCount; } + /* static */ void MayaUsdProxyShapeBase::SetClosestPointDelegate(ClosestPointDelegate delegate) { @@ -1971,6 +1976,8 @@ MayaUsdProxyShapeBase::MayaUsdProxyShapeBase( , _unsharedStageRootSublayers() , _incomingLayers() { + g_proxyShapeInstancesCount += 1; + TfRegistryManager::GetInstance().SubscribeTo(); if (useLoadRulesHandling) { @@ -1998,6 +2005,8 @@ MayaUsdProxyShapeBase::~MayaUsdProxyShapeBase() // Deregister from the load-rules handling used to transfer load rules // between the USD stage and a dynamic attribute on the proxy shape. MayaUsdProxyShapeStageExtraData::removeProxyShape(*this); + + g_proxyShapeInstancesCount -= 1; } MSelectionMask MayaUsdProxyShapeBase::getShapeSelectionMask() const diff --git a/lib/mayaUsd/nodes/proxyShapeBase.h b/lib/mayaUsd/nodes/proxyShapeBase.h index b0570d8bf7..19ff35336a 100644 --- a/lib/mayaUsd/nodes/proxyShapeBase.h +++ b/lib/mayaUsd/nodes/proxyShapeBase.h @@ -151,6 +151,9 @@ class MayaUsdProxyShapeBase MAYAUSD_CORE_PUBLIC static MayaUsdProxyShapeBase* GetShapeAtDagPath(const MDagPath& dagPath); + MAYAUSD_CORE_PUBLIC + static int countProxyShapeInstances(); + MAYAUSD_CORE_PUBLIC static void SetClosestPointDelegate(ClosestPointDelegate delegate); diff --git a/lib/mayaUsd/ufe/UsdStageMap.cpp b/lib/mayaUsd/ufe/UsdStageMap.cpp index 179583140a..9637c1cc0c 100644 --- a/lib/mayaUsd/ufe/UsdStageMap.cpp +++ b/lib/mayaUsd/ufe/UsdStageMap.cpp @@ -134,6 +134,12 @@ UsdStageWeakPtr UsdStageMap::stage(const Ufe::Path& path) MObject UsdStageMap::proxyShape(const Ufe::Path& path) { + // Optimization: if there are not proxy shape instances, + // there is nothing that can be mapped. Avoid trying to + // build the proxy shape map. + if (MayaUsdProxyShapeBase::countProxyShapeInstances() == 0) + return MObject(); + rebuildIfDirty(); // In additional to the explicit dirty system it is possible that From 658f26365595f22295a54c00037e78b7e6b85764 Mon Sep 17 00:00:00 2001 From: Pierre Baillargeon Date: Fri, 26 Jan 2024 13:20:39 -0500 Subject: [PATCH 2/2] MAYA-132438 fix compilation on MacOS and Linux. --- lib/mayaUsd/nodes/proxyShapeBase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/mayaUsd/nodes/proxyShapeBase.cpp b/lib/mayaUsd/nodes/proxyShapeBase.cpp index 9b71bb1500..69f1d6b2f0 100644 --- a/lib/mayaUsd/nodes/proxyShapeBase.cpp +++ b/lib/mayaUsd/nodes/proxyShapeBase.cpp @@ -136,7 +136,7 @@ const MString MayaUsdProxyShapeBase::displayFilterName( TfStringPrintf("%sDisplayFilter", MayaUsdProxyShapeBaseTokens->MayaTypeName.GetText()).c_str()); const MString MayaUsdProxyShapeBase::displayFilterLabel("USD Proxies"); -std::atomic g_proxyShapeInstancesCount = 0; +std::atomic g_proxyShapeInstancesCount; // Attributes MObject MayaUsdProxyShapeBase::filePathAttr;