Skip to content

Commit

Permalink
Address feedback, fix function declaration to be Pixar's code convent…
Browse files Browse the repository at this point in the history
…ion, rename variable for better readability
  • Loading branch information
Zhicheng Ye authored and Zhicheng Ye committed Aug 8, 2022
1 parent 6abfb45 commit b8a78ea
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 33 deletions.
75 changes: 47 additions & 28 deletions pxr/usdImaging/usdImaging/delegate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -907,25 +907,33 @@ UsdImagingDelegate::GetTimeWithOffset(float offset) const

void
UsdImagingDelegate::_GatherDependencies(SdfPath const& subtree,
SdfPathVector& affectedCachePaths)
SdfPathVector *affectedCachePaths)
{
HD_TRACE_FUNCTION();

const auto it = _dependenciesCacheMap.find(subtree);
if (it != _dependenciesCacheMap.end()) {
affectedCachePaths = it->second;
if (affectedCachePaths == nullptr) {
return;
}

_GatherDependenciesCache(subtree, affectedCachePaths);
const auto it = _flattenedDependenciesCache.find(subtree);
if (it != _flattenedDependenciesCache.end()) {
(*affectedCachePaths) = it->second;
return;
}

_CacheDependencies(subtree, affectedCachePaths);
}

void
UsdImagingDelegate::_GatherDependenciesCache(SdfPath const& subtree,
SdfPathVector& affectedCachePaths)
UsdImagingDelegate::_CacheDependencies(SdfPath const& subtree,
SdfPathVector *affectedCachePaths)
{
HD_TRACE_FUNCTION();

if (affectedCachePaths == nullptr) {
return;
}

// Binary search for the first path in the subtree.
_DependencyMap::const_iterator start =
_dependencyInfo.lower_bound(subtree);
Expand Down Expand Up @@ -959,7 +967,7 @@ UsdImagingDelegate::_GatherDependenciesCache(SdfPath const& subtree,
// usd dependencies within subtree.
std::sort(affectedPaths.begin(), affectedPaths.end());
std::unique_copy(affectedPaths.begin(), affectedPaths.end(),
std::back_inserter(affectedCachePaths));
std::back_inserter(*affectedCachePaths));
}

void
Expand All @@ -986,7 +994,7 @@ UsdImagingDelegate::ApplyPendingUpdates()
_coordSysBindingCache.Clear();
_inheritedPrimvarCache.Clear();
_pointInstancerIndicesCache.Clear();
_dependenciesCacheMap.clear();
_flattenedDependenciesCache.clear();

UsdImagingDelegate::_Worker worker(this);
UsdImagingIndexProxy indexProxy(this, &worker);
Expand All @@ -1006,25 +1014,18 @@ UsdImagingDelegate::ApplyPendingUpdates()
});
_usdPathsToResync.clear();

// Sort and find out all the key usd paths for `_GatherDependencies()`
SdfPathSet sortedUsdPathsToResync;
for (SdfPath const& usdPath: usdPathsToResync) {
if (usdPath.IsPropertyPath()) {
sortedUsdPathsToResync.emplace(usdPath.GetPrimPath());
} else if (usdPath.IsTargetPath()) {
sortedUsdPathsToResync.emplace(usdPath.GetParentPath());
} else if (usdPath.IsAbsoluteRootOrPrimPath()) {
sortedUsdPathsToResync.emplace(usdPath);
}
}

// Pre-cache dependencies in parallel
WorkDispatcher resyncPathsCacheDispatcher;
for (const auto& usdPath: sortedUsdPathsToResync) {
auto& affectedCachePaths = _dependenciesCacheMap[usdPath];
for (const auto& usdPath: usdPathsToResync) {
auto pair = _flattenedDependenciesCache.insert(std::make_pair(usdPath, SdfPathVector()));
if (!pair.second) {
// No insertion happened, path has been inserted
continue;
}
auto& affectedCachePaths = pair.first->second;
resyncPathsCacheDispatcher.Run(
[this, &usdPath, &affectedCachePaths]() {
_GatherDependenciesCache(usdPath, affectedCachePaths);
_CacheDependencies(usdPath, &affectedCachePaths);
});
}
resyncPathsCacheDispatcher.Wait();
Expand Down Expand Up @@ -1055,6 +1056,24 @@ UsdImagingDelegate::ApplyPendingUpdates()
if (!_usdPathsToUpdate.empty()) {
_PathsToUpdateMap usdPathsToUpdate;
std::swap(usdPathsToUpdate, _usdPathsToUpdate);

// Pre-cache dependencies in parallel
WorkDispatcher updatePathsCacheDispatcher;
for (auto pathIt: usdPathsToUpdate) {
const auto& usdPath = pathIt.first;
auto pair = _flattenedDependenciesCache.insert(std::make_pair(usdPath, SdfPathVector()));
if (!pair.second) {
// No insertion happened, path has been inserted
continue;
}
auto& affectedCachePaths = pair.first->second;
updatePathsCacheDispatcher.Run(
[this, &usdPath, &affectedCachePaths]() {
_CacheDependencies(usdPath, &affectedCachePaths);
});
}
updatePathsCacheDispatcher.Wait();

TF_FOR_ALL(pathIt, usdPathsToUpdate) {
const SdfPath& usdPath = pathIt->first;
const TfTokenVector& changedPrimInfoFields = pathIt->second;
Expand Down Expand Up @@ -1273,7 +1292,7 @@ UsdImagingDelegate::_ResyncUsdPrim(SdfPath const& usdPath,
// resync affected prims individually. If we do this, we also need to walk
// the subtree and check for new prims.
SdfPathVector affectedCachePaths;
_GatherDependencies(usdPath, affectedCachePaths);
_GatherDependencies(usdPath, &affectedCachePaths);
if (affectedCachePaths.size() > 0) {
for (SdfPath const& affectedCachePath : affectedCachePaths) {

Expand Down Expand Up @@ -1408,15 +1427,15 @@ UsdImagingDelegate::_RefreshUsdObject(SdfPath const& usdPath,
UsdGeomXformable::IsTransformationAffectedByAttrNamed(attrName)) {
// Because these are inherited attributes, we must update all
// children.
_GatherDependencies(usdPrimPath, affectedCachePaths);
_GatherDependencies(usdPrimPath, &affectedCachePaths);
} else if (UsdGeomPrimvarsAPI::CanContainPropertyName(attrName)) {
// Primvars can be inherited, so we need to invalidate everything
// downstream. Technically, only constant primvars on non-leaf
// prims are inherited, but we can't check the interpolation mode
// if (e.g.) the primvar has been blocked, and calling
// _GatherDependencies on a leaf prim won't invoke any extra work
// vs the equal_range below...
_GatherDependencies(usdPrimPath, affectedCachePaths);
_GatherDependencies(usdPrimPath, &affectedCachePaths);
} else if (UsdCollectionAPI::CanContainPropertyName(attrName)) {
// XXX Performance: Collections used for material bindings
// can refer to prims at arbitrary locations in the scene.
Expand Down Expand Up @@ -2333,7 +2352,7 @@ UsdImagingDelegate::PopulateSelection(
SdfPath rootPath = usdPrim.GetPath();

SdfPathVector affectedCachePaths;
_GatherDependencies(rootPath, affectedCachePaths);
_GatherDependencies(rootPath, &affectedCachePaths);

std::sort(affectedCachePaths.begin(), affectedCachePaths.end());
auto last = std::unique(affectedCachePaths.begin(),
Expand Down
10 changes: 5 additions & 5 deletions pxr/usdImaging/usdImaging/delegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -659,13 +659,13 @@ class UsdImagingDelegate : public HdSceneDelegate, public TfWeakBase {
_DependencyMap _dependencyInfo;

void _GatherDependencies(SdfPath const& subtree,
SdfPathVector& affectedCachePaths);
SdfPathVector *affectedCachePaths);

typedef TfHashMap<SdfPath, SdfPathVector, SdfPath::Hash> _DependenciesCacheMap;
_DependenciesCacheMap _dependenciesCacheMap;
typedef TfHashMap<SdfPath, SdfPathVector, SdfPath::Hash> _FlattenedDependenciesCacheMap;
_FlattenedDependenciesCacheMap _flattenedDependenciesCacheMap;

void _GatherDependenciesCache(SdfPath const &subtree,
SdfPathVector& affectedCachePaths);
void _CacheDependencies(SdfPath const &subtree,
SdfPathVector *affectedCachePaths);

// SdfPath::ReplacePrefix() is used frequently to convert between
// cache path and Hydra render index path and is a performance bottleneck.
Expand Down

0 comments on commit b8a78ea

Please sign in to comment.