Skip to content

Commit

Permalink
HYDRA-160 : support multithreading in MayaHydraSceneIndex::RecreateAd…
Browse files Browse the repository at this point in the history
…apterOnIdle (#3)
  • Loading branch information
lanierd-adsk authored Nov 13, 2023
1 parent 31c3f5d commit a3a6679
Showing 1 changed file with 48 additions and 26 deletions.
74 changes: 48 additions & 26 deletions lib/mayaHydra/hydraExtensions/sceneIndex/mayaHydraSceneIndex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@
#include <pxr/imaging/hd/rprim.h>
#include <pxr/usdImaging/usdImaging/tokens.h>

namespace
{
static std::mutex _adaptersToRecreateMutex;
static std::mutex _adaptersToRebuildMutex;
}

PXR_NAMESPACE_OPEN_SCOPE
// Bring the MayaHydra namespace into scope.
// The following code currently lives inside the pxr namespace, but it would make more sense to
Expand Down Expand Up @@ -766,37 +772,49 @@ void MayaHydraSceneIndex::PreFrame(const MHWRender::MDrawContext& context)
// We don't need to rebuild something that's already being recreated.
// Since we have a few elements, linear search over vectors is going to
// be okay.
if (!_adaptersToRecreate.empty()) {
for (const auto& it : _adaptersToRecreate) {
RecreateAdapter(std::get<0>(it), std::get<1>(it));
for (auto itr = _adaptersToRebuild.begin(); itr != _adaptersToRebuild.end(); ++itr) {
if (std::get<0>(it) == std::get<0>(*itr)) {
_adaptersToRebuild.erase(itr);
break;
//Block for the lifetime of _adaptersToRecreateMutex and _adaptersToRebuildMutex
{
std::lock_guard<std::mutex> lockRecreate(_adaptersToRecreateMutex);
std::lock_guard<std::mutex> lockRebuild(_adaptersToRebuildMutex);

if (!_adaptersToRecreate.empty()) {
for (const auto& it : _adaptersToRecreate) {
RecreateAdapter(std::get<0>(it), std::get<1>(it));

for (auto itr = _adaptersToRebuild.begin(); itr != _adaptersToRebuild.end(); ++itr) {
if (std::get<0>(it) == std::get<0>(*itr)) {
_adaptersToRebuild.erase(itr);
break;
}
}
}
_adaptersToRecreate.clear();
}
_adaptersToRecreate.clear();
}
if (!_adaptersToRebuild.empty()) {
for (const auto& it : _adaptersToRebuild) {
_FindAdapter<MayaHydraAdapter>(
std::get<0>(it),
[&](MayaHydraAdapter* a) {
if (std::get<1>(it) & MayaHydraSceneIndex::RebuildFlagCallbacks) {
a->RemoveCallbacks();
a->CreateCallbacks();
}
if (std::get<1>(it) & MayaHydraSceneIndex::RebuildFlagPrim) {
a->RemovePrim();
a->Populate();
}

//Block for the lifetime of _adaptersToRebuildMutex
{
std::lock_guard<std::mutex> lock(_adaptersToRebuildMutex);
if (!_adaptersToRebuild.empty()) {
for (const auto& it : _adaptersToRebuild) {
_FindAdapter<MayaHydraAdapter>(
std::get<0>(it),
[&](MayaHydraAdapter* a) {
if (std::get<1>(it) & MayaHydraSceneIndex::RebuildFlagCallbacks) {
a->RemoveCallbacks();
a->CreateCallbacks();
}
if (std::get<1>(it) & MayaHydraSceneIndex::RebuildFlagPrim) {
a->RemovePrim();
a->Populate();
}
},
_shapeAdapters,
_lightAdapters,
_materialAdapters);
}
},
_shapeAdapters,
_lightAdapters,
_materialAdapters);
_adaptersToRebuild.clear();
}
_adaptersToRebuild.clear();
}
if (!IsHdSt()) {
return;
Expand Down Expand Up @@ -1073,6 +1091,8 @@ void MayaHydraSceneIndex::RemoveAdapter(const SdfPath& id)

void MayaHydraSceneIndex::RecreateAdapterOnIdle(const SdfPath& id, const MObject& obj)
{
std::lock_guard<std::mutex> lock(_adaptersToRecreateMutex);

// We expect this to be a small number of objects, so using a simple linear
// search and a vector is generally a good choice.
for (auto& it : _adaptersToRecreate) {
Expand Down Expand Up @@ -1167,6 +1187,8 @@ SdfPath MayaHydraSceneIndex::GetLightedPrimsRootPath() const

void MayaHydraSceneIndex::RebuildAdapterOnIdle(const SdfPath& id, uint32_t flags)
{
std::lock_guard<std::mutex> lock(_adaptersToRebuildMutex);

// We expect this to be a small number of objects, so using a simple linear
// search and a vector is generally a good choice.
for (auto& it : _adaptersToRebuild) {
Expand Down

0 comments on commit a3a6679

Please sign in to comment.