This document is for a version of USD that is under development. See this page for the current release.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
dependencyForwardingSceneIndex.h
1//
2// Copyright 2022 Pixar
3//
4// Licensed under the terms set forth in the LICENSE.txt file available at
5// https://openusd.org/license.
6//
7#ifndef PXR_IMAGING_HD_DEPENDENCY_FORWARDING_SCENE_INDEX_H
8#define PXR_IMAGING_HD_DEPENDENCY_FORWARDING_SCENE_INDEX_H
9
11
12#include "pxr/imaging/hd/api.h"
13#include "pxr/imaging/hd/filteringSceneIndex.h"
14
15#include <tbb/concurrent_unordered_map.h>
16#include <tbb/concurrent_unordered_set.h>
17
18PXR_NAMESPACE_OPEN_SCOPE
19
20class HdDependencyForwardingSceneIndex;
21TF_DECLARE_REF_PTRS(HdDependencyForwardingSceneIndex);
22
23
24class HdDependencyForwardingSceneIndex
26{
27public:
28
29 static HdDependencyForwardingSceneIndexRefPtr New(
30 HdSceneIndexBaseRefPtr inputScene) {
31 return TfCreateRefPtr(
32 new HdDependencyForwardingSceneIndex(inputScene));
33 }
34
35 // satisfying HdSceneIndexBase
36 HdSceneIndexPrim GetPrim(const SdfPath &primPath) const override;
37 SdfPathVector GetChildPrimPaths(const SdfPath &primPath) const override;
38
39
40protected:
41 HD_API
42 HdDependencyForwardingSceneIndex(HdSceneIndexBaseRefPtr inputScene);
43
44 // satisfying HdSingleInputFilteringSceneIndexBase
45 void _PrimsAdded(
46 const HdSceneIndexBase &sender,
47 const HdSceneIndexObserver::AddedPrimEntries &entries) override;
48
49 void _PrimsRemoved(
50 const HdSceneIndexBase &sender,
51 const HdSceneIndexObserver::RemovedPrimEntries &entries) override;
52
53 void _PrimsDirtied(
54 const HdSceneIndexBase &sender,
55 const HdSceneIndexObserver::DirtiedPrimEntries &entries) override;
56private:
57
58 // -----------------------------------------------------------------------
59
60 struct _LocatorsEntry
61 {
62 HdDataSourceLocator dependedOnDataSourceLocator;
63 HdDataSourceLocator affectedDataSourceLocator;
64 };
65
66 // The token used as a key here corresponds to the first member of an
67 // HdDependenciesSchema::EntryPair and provides an identifier for a
68 // dependency declaration. An affected prim may depend on more than one
69 // data source of another prim. That identifier is used here for updating
70 // or removing a dependency.
71 using _LocatorsEntryMap = tbb::concurrent_unordered_map<
72 TfToken,
73 _LocatorsEntry,
75
76
77 struct _AffectedPrimDependencyEntry
78 {
79 _LocatorsEntryMap locatorsEntryMap;
80 bool flaggedForDeletion = false;
81 };
82
83 // Reverse mapping from a depended on prim to its discovered-thus-far
84 // affected prims and data source locators..
85 using _AffectedPrimsDependencyMap = tbb::concurrent_unordered_map<
86 SdfPath,
87 _AffectedPrimDependencyEntry,
88 SdfPath::Hash>;
89
90
91 // Top-level map keyed by paths of depended-on paths
92 using _DependedOnPrimsAffectedPrimsMap = tbb::concurrent_unordered_map<
93 SdfPath,
94 _AffectedPrimsDependencyMap,
95 SdfPath::Hash>;
96
97
98 // Lazily-populated mapping of depended on paths to the affected paths
99 // and data source locators used for forwarding of dirtying.
100 // NOTE: This is mutable because it can be updated during calls to
101 // GetPrim -- which is defined as const within HdSceneIndexBase.
102 // This is in service of lazy population goals.
103 mutable _DependedOnPrimsAffectedPrimsMap _dependedOnPrimToDependentsMap;
104
105
106 // -----------------------------------------------------------------------
107
108 using _PathSet = tbb::concurrent_unordered_set<SdfPath, SdfPath::Hash>;
109
110 //using _DensePathSet = TfDenseHashSet<SdfPath, SdfPath::Hash>;
111
112 struct _AffectedPrimToDependsOnPathsEntry
113 {
114 _PathSet dependsOnPaths;
115 bool flaggedForDeletion = false;
116 };
117
118
119 using _AffectedPrimToDependsOnPathsEntryMap = tbb::concurrent_unordered_map<
120 SdfPath,
121 _AffectedPrimToDependsOnPathsEntry,
122 SdfPath::Hash>;
123
124 // lazily-populated set of depended on paths for affected prims. This
125 // is used to update _dependedOnPrimToDependentsMap when a prim's
126 // __dependencies data source is dirtied (or the prim is removed)
127 // NOTE: This is mutable because it can be updated during calls to
128 // GetPrim -- which is defined as const within HdSceneIndexBase.
129 // This is in service of lazy population goals.
130 mutable _AffectedPrimToDependsOnPathsEntryMap
131 _affectedPrimToDependsOnPathsMap;
132
133 // -----------------------------------------------------------------------
134
135 void _ClearDependencies(const SdfPath &primPath);
136 void _UpdateDependencies(const SdfPath &primPath) const;
137
138 // -----------------------------------------------------------------------
139
140 // Dependencies may reasonably describe cycles given that:
141 // 1) Dependancies can exist at different levels of data source nesting
142 // 2) Dependancy declarations can be present from multiple upstream
143 // scene indices -- each of which draws its value from its input.
144 // In that case, it's not a cycle which affects a computed value but
145 // rather indicates to observers of this scene index that a value
146 // should be repulled.
147 //
148 // When following affected paths to propogate dirtiness, we need to detect
149 // cycles to avoiding hanging. This is done is by sending a "visited" set
150 // containing these node keys:
151 struct _VisitedNode
152 {
153 SdfPath primPath;
154 HdDataSourceLocator locator;
155
156 inline bool operator==(_VisitedNode const &rhs) const noexcept
157 {
158 return primPath == rhs.primPath && locator == rhs.locator;
159 }
160
161 template <class HashState>
162 friend void TfHashAppend(HashState &h, _VisitedNode const &myObj) {
163 h.Append(myObj.primPath);
164 h.Append(myObj.locator);
165 }
166
167 inline size_t Hash() const;
168 struct HashFunctor {
169 size_t operator()(_VisitedNode const &node) const {
170 return node.Hash();
171 }
172 };
173 };
174
175 using _VisitedNodeSet = TfDenseHashSet<
176 _VisitedNode,
177 _VisitedNode::HashFunctor>;
178
179 // impl for PrimDirtied which handles propogation of PrimDirtied notices
180 // for affected prims/dataSources.
181 void _PrimDirtied(
182 const SdfPath &primPath,
183 const HdDataSourceLocator &sourceLocator,
184 _VisitedNodeSet *visited,
185 HdSceneIndexObserver::DirtiedPrimEntries *moreDirtiedEntries);
186
187 // -----------------------------------------------------------------------
188
189 // accumulated depended-on prim paths whose affected prims may have been
190 // removed.
191 mutable _PathSet _potentiallyDeletedDependedOnPaths;
192
193 // Accumulated affected prim paths who may have been deleted. Normally this
194 // is needed to track affected prims which have an entry in
195 // _dependedOnPrimToDependentsMap but which is empty -- and therefore
196 // won't be handled by their dependencies inclusion in
197 // _potentiallyDeletedDependedOnPaths
198 mutable _PathSet _potentiallyDeletedAffectedPaths;
199
200 // -----------------------------------------------------------------------
201
202public:
203 // XXX does thread-unsafe deletion.
204 // NOTE FOR REVIEWERS: temporarily hiding this explosive public method
205 // down here while we discuss it. It's public because
206 // only the application knows when it's safe to call?
207 //
208 // NOTE: optional arguments are in service of unit testing to provide
209 // insight in to what was removed.
210 HD_API
211 void RemoveDeletedEntries(
212 SdfPathVector *removedAffectedPrimPaths = nullptr,
213 SdfPathVector *removedDependedOnPrimPaths = nullptr);
214
215};
216
217
218inline size_t
219HdDependencyForwardingSceneIndex::_VisitedNode::Hash() const
220{
221 return TfHash()(*this);
222}
223
224PXR_NAMESPACE_CLOSE_SCOPE
225
226#endif
Represents an object that can identify the location of a data source.
Abstract interface to scene data.
Definition: sceneIndex.h:48
virtual SdfPathVector GetChildPrimPaths(const SdfPath &primPath) const =0
Returns the paths of all scene index prims located immediately below primPath.
virtual HdSceneIndexPrim GetPrim(const SdfPath &primPath) const =0
Returns a pair of (prim type, datasource) for the object at primPath.
An abstract base class for a filtering scene index that observes a single input scene index.
A path value used to locate objects in layers or scenegraphs.
Definition: path.h:274
This is a space efficient container that mimics the TfHashSet API that uses a vector for storage when...
Definition: denseHashSet.h:39
A user-extensible hashing mechanism for use with runtime hash tables.
Definition: hash.h:460
Token for efficient comparison, assignment, and hashing of known strings.
Definition: token.h:71
#define TF_DECLARE_REF_PTRS(type)
Define standard ref pointer types.
Definition: declarePtrs.h:58
Small struct representing a 'prim' in the Hydra scene index.
Definition: sceneIndex.h:35
Functor to use for hash maps from tokens to other things.
Definition: token.h:149