HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
dependencyForwardingSceneIndex.h
Go to the documentation of this file.
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"
14 
15 #include <tbb/concurrent_unordered_map.h>
16 #include <tbb/concurrent_unordered_set.h>
17 
19 
22 
23 
26 {
27 public:
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 
40 protected:
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;
56 private:
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,
89 
90 
91  // Top-level map keyed by paths of depended-on paths
92  using _DependedOnPrimsAffectedPrimsMap = tbb::concurrent_unordered_map<
93  SdfPath,
94  _AffectedPrimsDependencyMap,
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 
202 public:
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
212  SdfPathVector *removedAffectedPrimPaths = nullptr,
213  SdfPathVector *removedDependedOnPrimPaths = nullptr);
214 
215 };
216 
217 
218 inline size_t
220 {
221  return TfHash()(*this);
222 }
223 
225 
226 #endif
TfRefPtr< T > TfCreateRefPtr(T *ptr)
Definition: refPtr.h:1190
void _PrimsDirtied(const HdSceneIndexBase &sender, const HdSceneIndexObserver::DirtiedPrimEntries &entries) override
void TfHashAppend(HashState &h, const T &ptr)
Definition: anyWeakPtr.h:220
STATIC_INLINE size_t Hash(const char *s, size_t len)
Definition: farmhash.h:2099
HD_API HdDependencyForwardingSceneIndex(HdSceneIndexBaseRefPtr inputScene)
SdfPathVector GetChildPrimPaths(const SdfPath &primPath) const override
#define HD_API
Definition: api.h:23
Functor to use for hash maps from tokens to other things.
Definition: token.h:149
void _PrimsAdded(const HdSceneIndexBase &sender, const HdSceneIndexObserver::AddedPrimEntries &entries) override
Definition: hash.h:472
bool operator==(const BaseDimensions< T > &a, const BaseDimensions< Y > &b)
Definition: Dimensions.h:137
Definition: token.h:70
std::vector< class SdfPath > SdfPathVector
Definition: path.h:273
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:2002
TF_DECLARE_REF_PTRS(HdDependencyForwardingSceneIndex)
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1425
HdSceneIndexPrim GetPrim(const SdfPath &primPath) const override
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
HD_API void RemoveDeletedEntries(SdfPathVector *removedAffectedPrimPaths=nullptr, SdfPathVector *removedDependedOnPrimPaths=nullptr)
static HdDependencyForwardingSceneIndexRefPtr New(HdSceneIndexBaseRefPtr inputScene)
void _PrimsRemoved(const HdSceneIndexBase &sender, const HdSceneIndexObserver::RemovedPrimEntries &entries) override