Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HYDRA-160 : support multithreading in MayaHydraSceneIndex::RecreateAd… #3

Merged
merged 2 commits into from
Nov 13, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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