All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
changeTracker.h
1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 // names, trademarks, service marks, or product names of the Licensor
11 // and its affiliates, except as required to comply with Section 4(c) of
12 // the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 // http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 #ifndef PXR_IMAGING_HD_CHANGE_TRACKER_H
25 #define PXR_IMAGING_HD_CHANGE_TRACKER_H
26 
27 #include "pxr/pxr.h"
28 #include "pxr/imaging/hd/api.h"
29 #include "pxr/imaging/hd/version.h"
30 #include "pxr/imaging/hd/rprimCollection.h"
31 #include "pxr/imaging/hd/types.h"
32 #include "pxr/usd/sdf/path.h"
33 #include "pxr/base/tf/hashmap.h"
34 
35 #include <tbb/concurrent_hash_map.h>
36 #include <atomic>
37 
38 PXR_NAMESPACE_OPEN_SCOPE
39 
40 
51 {
52 public:
53 
54  // Common dirty bits for Rprims
55  // XXX: Move this to HdRprim
56  enum RprimDirtyBits : HdDirtyBits {
57  Clean = 0,
58  InitRepr = 1 << 0,
59  Varying = 1 << 1,
60  AllDirty = ~Varying,
61  DirtyPrimID = 1 << 2,
62  DirtyExtent = 1 << 3,
63  DirtyDisplayStyle = 1 << 4,
64  DirtyPoints = 1 << 5,
65  DirtyPrimvar = 1 << 6,
66  DirtyMaterialId = 1 << 7,
67  DirtyTopology = 1 << 8,
68  DirtyTransform = 1 << 9,
69  DirtyVisibility = 1 << 10,
70  DirtyNormals = 1 << 11,
71  DirtyDoubleSided = 1 << 12,
72  DirtyCullStyle = 1 << 13,
73  DirtySubdivTags = 1 << 14,
74  DirtyWidths = 1 << 15,
75  DirtyInstancer = 1 << 16,
76  DirtyInstanceIndex = 1 << 17,
77  DirtyRepr = 1 << 18,
78  DirtyRenderTag = 1 << 19,
79  DirtyComputationPrimvarDesc = 1 << 20,
80  DirtyCategories = 1 << 21,
81  DirtyVolumeField = 1 << 22,
82  AllSceneDirtyBits = ((1<<23) - 1),
83 
84  NewRepr = 1 << 23,
85 
86  CustomBitsBegin = 1 << 24,
87  CustomBitsEnd = 1 << 30,
88  };
89 
90  // InstancerDirtybits are a subset of rprim dirty bits right now:
91  // DirtyPrimvar, DirtyTransform, DirtyInstanceIndex, DirtyInstancer.
92 
93  // Dirty bits for Tasks
94  // XXX: Move this to HdTask
95  enum TaskDirtyBits : HdDirtyBits {
96  //Varying = 1 << 0,
97  DirtyType = 1 << 1,
98  DirtyParams = 1 << 2,
99  DirtyCollection = 1 << 3,
100  DirtyRenderTags = 1 << 4,
101  };
102 
103  HD_API
104  HdChangeTracker();
105  HD_API
106  virtual ~HdChangeTracker();
107 
108  // ---------------------------------------------------------------------- //
111  // ---------------------------------------------------------------------- //
112 
114  HD_API
115  void RprimInserted(SdfPath const& id, HdDirtyBits initialDirtyState);
116 
118  HD_API
119  void RprimRemoved(SdfPath const& id);
120 
121  // ---------------------------------------------------------------------- //
125  // ---------------------------------------------------------------------- //
126 
128  HD_API
129  HdDirtyBits GetRprimDirtyBits(SdfPath const& id) const;
130 
133  HD_API
134  void MarkRprimDirty(SdfPath const& id, HdDirtyBits bits=AllDirty);
135 
139  HD_API
140  void MarkRprimClean(SdfPath const& id, HdDirtyBits newBits=Clean);
141 
143  HD_API
144  void MarkPrimvarDirty(SdfPath const& id, TfToken const& name);
145 
149  HD_API
150  void MarkAllRprimsDirty(HdDirtyBits bits);
151 
159  HD_API
160  void ResetVaryingState();
161 
165  HD_API
166  void ResetRprimVaryingState(SdfPath const& id);
167 
168 
169  // ---------------------------------------------------------------------- //
170 
172  HD_API
173  bool IsRprimDirty(SdfPath const& id);
174 
176  HD_API
177  bool IsExtentDirty(SdfPath const& id);
178 
180  HD_API
181  bool IsDisplayStyleDirty(SdfPath const& id);
182 
185  HD_API
186  bool IsPrimvarDirty(SdfPath const& id, TfToken const& name);
187 
189  HD_API
190  bool IsAnyPrimvarDirty(SdfPath const& id);
191 
193  HD_API
194  bool IsTopologyDirty(SdfPath const& id);
195 
197  HD_API
198  bool IsDoubleSidedDirty(SdfPath const& id);
199 
201  HD_API
202  bool IsCullStyleDirty(SdfPath const& id);
203 
205  HD_API
206  bool IsSubdivTagsDirty(SdfPath const& id);
207 
209  HD_API
210  bool IsTransformDirty(SdfPath const& id);
211 
213  HD_API
214  bool IsVisibilityDirty(SdfPath const& id);
215 
217  HD_API
218  bool IsPrimIdDirty(SdfPath const& id);
219 
221  static bool IsDirty(HdDirtyBits dirtyBits) {
222  return (dirtyBits & AllDirty) != 0;
223  }
224 
226  static bool IsClean(HdDirtyBits dirtyBits) {
227  return (dirtyBits & AllDirty) == 0;
228  }
229 
231  static bool IsVarying(HdDirtyBits dirtyBits) {
232  return (dirtyBits & Varying) != 0;
233  }
234 
236  HD_API
237  static bool IsExtentDirty(HdDirtyBits dirtyBits, SdfPath const& id);
238 
240  HD_API
241  static bool IsDisplayStyleDirty(HdDirtyBits dirtyBits, SdfPath const& id);
242 
244  HD_API
245  static bool IsSubdivTagsDirty(HdDirtyBits dirtyBits, SdfPath const& id);
246 
249  HD_API
250  static bool IsPrimvarDirty(HdDirtyBits dirtyBits, SdfPath const& id,
251  TfToken const& name);
252 
255  HD_API
256  static bool IsAnyPrimvarDirty(HdDirtyBits dirtyBits, SdfPath const& id);
257 
259  HD_API
260  static bool IsTopologyDirty(HdDirtyBits dirtyBits, SdfPath const& id);
261 
263  HD_API
264  static bool IsDoubleSidedDirty(HdDirtyBits dirtyBits, SdfPath const& id);
265 
267  HD_API
268  static bool IsCullStyleDirty(HdDirtyBits dirtyBits, SdfPath const& id);
269 
271  HD_API
272  static bool IsTransformDirty(HdDirtyBits dirtyBits, SdfPath const& id);
273 
275  HD_API
276  static bool IsVisibilityDirty(HdDirtyBits dirtyBits, SdfPath const& id);
277 
279  HD_API
280  static bool IsPrimIdDirty(HdDirtyBits dirtyBits, SdfPath const& id);
281 
283  HD_API
284  static bool IsInstancerDirty(HdDirtyBits dirtyBits, SdfPath const& id);
285 
287  HD_API
288  static bool IsInstanceIndexDirty(HdDirtyBits dirtyBits, SdfPath const& id);
289 
290  HD_API
291  static bool IsReprDirty(HdDirtyBits dirtyBits, SdfPath const &id);
292 
293  // ---------------------------------------------------------------------- //
294 
296  HD_API
297  static void MarkPrimvarDirty(HdDirtyBits *dirtyBits, TfToken const &name);
298 
299  // ---------------------------------------------------------------------- //
303  // ---------------------------------------------------------------------- //
304 
306  HD_API
307  void TaskInserted(SdfPath const& id, HdDirtyBits initialDirtyState);
308 
310  HD_API
311  void TaskRemoved(SdfPath const& id);
312 
314  HD_API
315  void MarkTaskDirty(SdfPath const& id, HdDirtyBits bits=AllDirty);
316 
318  HD_API
319  HdDirtyBits GetTaskDirtyBits(SdfPath const& id);
320 
322  HD_API
323  void MarkTaskClean(SdfPath const& id, HdDirtyBits newBits=Clean);
324 
331  HD_API
332  void MarkRenderTagsDirty();
333 
335  HD_API
336  unsigned GetRenderTagVersion() const;
337 
338  // ---------------------------------------------------------------------- //
342  // ---------------------------------------------------------------------- //
343 
345  HD_API
346  void InstancerInserted(SdfPath const& id, HdDirtyBits initialDirtyState);
347 
349  HD_API
350  void InstancerRemoved(SdfPath const& id);
351 
353  HD_API
354  HdDirtyBits GetInstancerDirtyBits(SdfPath const& id);
355 
358  HD_API
359  void MarkInstancerDirty(SdfPath const& id, HdDirtyBits bits=AllDirty);
360 
362  HD_API
363  void MarkInstancerClean(SdfPath const& id, HdDirtyBits newBits=Clean);
364 
368  HD_API
369  void AddInstancerRprimDependency(SdfPath const& instancerId,
370  SdfPath const& rprimId);
371 
374  HD_API
375  void RemoveInstancerRprimDependency(SdfPath const& instancerId,
376  SdfPath const& rprimId);
377 
381  HD_API
382  void AddInstancerInstancerDependency(SdfPath const& parentInstancerId,
383  SdfPath const& instancerId);
384 
387  HD_API
388  void RemoveInstancerInstancerDependency(SdfPath const& parentInstancerId,
389  SdfPath const& instancerId);
390 
391  // ---------------------------------------------------------------------- //
395  // ---------------------------------------------------------------------- //
396 
398  HD_API
399  void SprimInserted(SdfPath const& id, HdDirtyBits initialDirtyState);
400 
402  HD_API
403  void SprimRemoved(SdfPath const& id);
404 
406  HD_API
407  HdDirtyBits GetSprimDirtyBits(SdfPath const& id);
408 
410  HD_API
411  void MarkSprimDirty(SdfPath const& id, HdDirtyBits bits);
412 
414  HD_API
415  void MarkSprimClean(SdfPath const& id, HdDirtyBits newBits=Clean);
416 
417  // ---------------------------------------------------------------------- //
421  // ---------------------------------------------------------------------- //
422 
424  HD_API
425  void BprimInserted(SdfPath const& id, HdDirtyBits initialDirtyState);
426 
428  HD_API
429  void BprimRemoved(SdfPath const& id);
430 
432  HD_API
433  HdDirtyBits GetBprimDirtyBits(SdfPath const& id);
434 
436  HD_API
437  void MarkBprimDirty(SdfPath const& id, HdDirtyBits bits);
438 
440  HD_API
441  void MarkBprimClean(SdfPath const& id, HdDirtyBits newBits=Clean);
442 
443  // ---------------------------------------------------------------------- //
447  // ---------------------------------------------------------------------- //
448 
450  HD_API
451  void AddCollection(TfToken const& collectionName);
452 
455  HD_API
456  void MarkCollectionDirty(TfToken const& collectionName);
457 
459  HD_API
460  unsigned GetCollectionVersion(TfToken const& collectionName) const;
461 
464  HD_API
465  unsigned GetVisibilityChangeCount() const;
466 
469  unsigned GetVaryingStateVersion() const {
470  return _varyingStateVersion;
471  }
472 
473  // ---------------------------------------------------------------------- //
477  // ---------------------------------------------------------------------- //
478 
482  unsigned GetRprimIndexVersion() const {
483  return _rprimIndexVersion;
484  }
485 
489  unsigned GetSprimIndexVersion() const {
490  return _sprimIndexVersion;
491  }
492 
496  unsigned GetBprimIndexVersion() const {
497  return _bprimIndexVersion;
498  }
499 
503  unsigned GetInstancerIndexVersion() const {
504  return _instancerIndexVersion;
505  }
506 
507 
513  unsigned GetSceneStateVersion() const {
514  return _sceneStateVersion;
515  }
516 
517  // ---------------------------------------------------------------------- //
521  // ---------------------------------------------------------------------- //
522 
524  HD_API
525  void AddState(TfToken const& name);
526 
529  HD_API
530  void MarkStateDirty(TfToken const& name);
531 
533  HD_API
534  unsigned GetStateVersion(TfToken const &name) const;
535 
536  // ---------------------------------------------------------------------- //
540  // ---------------------------------------------------------------------- //
541  HD_API
542  static std::string StringifyDirtyBits(HdDirtyBits dirtyBits);
543 
544  HD_API
545  static void DumpDirtyBits(HdDirtyBits dirtyBits);
546 
548 
549 private:
550 
551  // Don't allow copies
552  HdChangeTracker(const HdChangeTracker &) = delete;
553  HdChangeTracker &operator=(const HdChangeTracker &) = delete;
554 
555 
556  static void _LogCacheAccess(TfToken const& cacheName,
557  SdfPath const& id, bool hit);
558 
559  typedef TfHashMap<SdfPath, HdDirtyBits, SdfPath::Hash> _IDStateMap;
560  typedef TfHashMap<TfToken, int, TfToken::HashFunctor> _CollectionStateMap;
561  typedef TfHashMap<TfToken, unsigned, TfToken::HashFunctor> _GeneralStateMap;
562 
563  struct _PathHashCompare {
564  static bool equal(const SdfPath& a, const SdfPath& b)
565  { return a == b; }
566 
567  static size_t hash(const SdfPath& path)
568  { return hash_value(path); }
569  };
570  typedef tbb::concurrent_hash_map<SdfPath, SdfPathSet, _PathHashCompare>
571  _DependencyMap;
572 
573  // Core dirty state.
574  _IDStateMap _rprimState;
575  _IDStateMap _instancerState;
576  _IDStateMap _taskState;
577  _IDStateMap _sprimState;
578  _IDStateMap _bprimState;
579  _GeneralStateMap _generalState;
580 
581  // Collection versions / state.
582  _CollectionStateMap _collectionState;
583 
584  // Provides reverse-association between instancers and the child
585  // instancers/rprims that use them.
586  _DependencyMap _instancerRprimDependencies;
587  _DependencyMap _instancerInstancerDependencies;
588 
589  // Dependency map helpers
590  void _AddDependency(_DependencyMap &depMap,
591  SdfPath const& parent, SdfPath const& child);
592  void _RemoveDependency(_DependencyMap &depMap,
593  SdfPath const& parent, SdfPath const& child);
594 
595  // Typically the Rprims that get marked dirty per update iteration end up
596  // being a stable set of objects; to leverage this fact, we require the
597  // delegate notify the change tracker when that state changes, which bumps
598  // the varyingStateVersion, which triggers downstream invalidation.
599  unsigned _varyingStateVersion;
600 
601  // Tracks changes (insertions/removals) of prims in the render index.
602  // This is used to indicating that cached gather operations need to be
603  // re-evaluated, such as dirty lists or batch building.
604  unsigned _rprimIndexVersion;
605  unsigned _sprimIndexVersion;
606  unsigned _bprimIndexVersion;
607  unsigned _instancerIndexVersion;
608 
609  // The following tracks any changes of state. As a result it is very broad.
610  // The use case to detect, when no changes have been made, as to
611  // avoid the need to sync or reset progressive renderers.
612  unsigned _sceneStateVersion;
613 
614  // Used to detect that visibility changed somewhere in the render index.
615  unsigned _visChangeCount;
616 
617  // Used to detect changes to the set of active render tags
618  unsigned _renderTagVersion;
619 };
620 
621 
622 PXR_NAMESPACE_CLOSE_SCOPE
623 
624 #endif //PXR_IMAGING_HD_CHANGE_TRACKER_H
HD_API void ResetRprimVaryingState(SdfPath const &id)
Reset the varying state on one Rprim This is done for Rprims, where we choose not to clean them (due ...
HD_API unsigned GetVisibilityChangeCount() const
Returns the number of changes to visibility.
HD_API void MarkInstancerClean(SdfPath const &id, HdDirtyBits newBits=Clean)
Clean the specified dirty bits for the instancer with id.
HD_API void MarkBprimDirty(SdfPath const &id, HdDirtyBits bits)
Set the dirty flags to bits.
HD_API void MarkRenderTagsDirty()
Called to flag when the set of active render tags have changed.
HD_API HdDirtyBits GetTaskDirtyBits(SdfPath const &id)
Get the dirty bits for Task with the given id.
HD_API void MarkPrimvarDirty(SdfPath const &id, TfToken const &name)
Mark the primvar for the rprim with id as being dirty.
Tracks changes from the HdSceneDelegate, providing invalidation cues to the render engine...
Definition: changeTracker.h:50
HD_API void RprimInserted(SdfPath const &id, HdDirtyBits initialDirtyState)
Start tracking Rprim with the given id.
HD_API void SprimRemoved(SdfPath const &id)
Stop tracking sprim with the given id.
HD_API void MarkTaskClean(SdfPath const &id, HdDirtyBits newBits=Clean)
Set the dirty flags to newBits.
HD_API bool IsCullStyleDirty(SdfPath const &id)
Returns true if the rprim identified by id has dirty cullstyle.
unsigned GetSprimIndexVersion() const
Returns the current version of the Render Index&#39;s SPrim set.
static HD_API bool IsInstanceIndexDirty(HdDirtyBits dirtyBits, SdfPath const &id)
Returns true if the dirtyBits has a dirty instance index. id is for perflog.
static bool IsVarying(HdDirtyBits dirtyBits)
Returns true if the dirtyBits has no flags set except the varying flag.
HD_API void MarkRprimClean(SdfPath const &id, HdDirtyBits newBits=Clean)
Clear the dirty flags for an HdRprim.
HD_API HdDirtyBits GetInstancerDirtyBits(SdfPath const &id)
Returns the dirty bits for the instancer with id.
unsigned GetInstancerIndexVersion() const
Returns the current version of the Render Index&#39;s Instancer set.
HD_API void BprimInserted(SdfPath const &id, HdDirtyBits initialDirtyState)
Start tracking bprim with the given id.
HD_API bool IsAnyPrimvarDirty(SdfPath const &id)
Returns true if the rprim identified by id has any dirty primvars.
HD_API void MarkInstancerDirty(SdfPath const &id, HdDirtyBits bits=AllDirty)
Flag the Instancer with the given id as being dirty.
HD_API HdDirtyBits GetSprimDirtyBits(SdfPath const &id)
Get the dirty bits for sprim with the given id.
HD_API void InstancerRemoved(SdfPath const &id)
Stop tracking Instancer with the given id.
unsigned GetVaryingStateVersion() const
Returns the current version of varying state.
HD_API void TaskInserted(SdfPath const &id, HdDirtyBits initialDirtyState)
Start tracking Task with the given id.
HD_API void MarkStateDirty(TfToken const &name)
Marks a named state as being dirty., this bumps the version of the state.
HD_API bool IsDoubleSidedDirty(SdfPath const &id)
Returns true if the rprim identified by id has dirty doubleSided state.
HD_API HdDirtyBits GetBprimDirtyBits(SdfPath const &id)
Get the dirty bits for bprim with the given id.
unsigned GetRprimIndexVersion() const
Returns the current version of the Render Index&#39;s RPrim set.
HD_API bool IsTransformDirty(SdfPath const &id)
Returns true if the rprim identified by id has a dirty transform.
Token for efficient comparison, assignment, and hashing of known strings.
Definition: token.h:87
HD_API bool IsRprimDirty(SdfPath const &id)
Returns true if the rprim identified by id has any dirty flags set.
HD_API unsigned GetStateVersion(TfToken const &name) const
Returns the current version of the named state.
HD_API HdDirtyBits GetRprimDirtyBits(SdfPath const &id) const
Returns the dirty bits for the rprim with id.
HD_API bool IsPrimIdDirty(SdfPath const &id)
Returns true if the rprim identified by id has a dirty primID.
HD_API void MarkSprimDirty(SdfPath const &id, HdDirtyBits bits)
Set the dirty flags to bits.
HD_API void ResetVaryingState()
Clear Varying bit of all prims.
HD_API void MarkTaskDirty(SdfPath const &id, HdDirtyBits bits=AllDirty)
Set the dirty flags to bits.
HD_API void MarkCollectionDirty(TfToken const &collectionName)
Marks a named collection as being dirty, this bumps the version of the collection.
static bool IsDirty(HdDirtyBits dirtyBits)
Returns true if the dirtyBits has any flags set other than the varying flag.
unsigned GetSceneStateVersion() const
Returns the current version of the scene state.
unsigned GetBprimIndexVersion() const
Returns the current version of the Render Index&#39;s BPrim set.
HD_API void AddInstancerRprimDependency(SdfPath const &instancerId, SdfPath const &rprimId)
Insert a dependency between rprimId and parent instancer instancerId.
HD_API void MarkBprimClean(SdfPath const &id, HdDirtyBits newBits=Clean)
Set the dirty flags to newBits.
A path value used to locate objects in layers or scenegraphs.
Definition: path.h:288
HD_API void InstancerInserted(SdfPath const &id, HdDirtyBits initialDirtyState)
Start tracking Instancer with the given id.
HD_API bool IsTopologyDirty(SdfPath const &id)
Returns true if the rprim identified by id has a dirty topology.
static bool IsClean(HdDirtyBits dirtyBits)
Returns true if the dirtyBits has no flags set except the varying flag.
HD_API void AddCollection(TfToken const &collectionName)
Adds a named collection for tracking.
HD_API void BprimRemoved(SdfPath const &id)
Stop tracking bprim with the given id.
HD_API void MarkRprimDirty(SdfPath const &id, HdDirtyBits bits=AllDirty)
Flag the Rprim with the given id as being dirty.
HD_API void MarkAllRprimsDirty(HdDirtyBits bits)
Flag all the Rprim with the given id as being dirty.
HD_API bool IsVisibilityDirty(SdfPath const &id)
Returns true if the rprim identified by id has dirty visibility.
HD_API bool IsSubdivTagsDirty(SdfPath const &id)
Returns true if the rprim identified by id has a dirty subdiv tags.
HD_API void SprimInserted(SdfPath const &id, HdDirtyBits initialDirtyState)
Start tracking sprim with the given id.
HD_API bool IsExtentDirty(SdfPath const &id)
Returns true if the rprim identified by id has a dirty extent.
HD_API bool IsDisplayStyleDirty(SdfPath const &id)
Returns true if the rprim identified by id has a dirty display style.
HD_API void MarkSprimClean(SdfPath const &id, HdDirtyBits newBits=Clean)
Set the dirty flags to newBits.
HD_API void AddState(TfToken const &name)
Adds a named state for tracking.
HD_API void RprimRemoved(SdfPath const &id)
Stop tracking Rprim with the given id.
HD_API unsigned GetCollectionVersion(TfToken const &collectionName) const
Returns the current version of the named collection.
HD_API void RemoveInstancerRprimDependency(SdfPath const &instancerId, SdfPath const &rprimId)
Remove a dependency between rprimId and parent instancer instancerId.
HD_API void RemoveInstancerInstancerDependency(SdfPath const &parentInstancerId, SdfPath const &instancerId)
Remove a dependency between instancerId and parent instancer parentInstancerId.
HD_API bool IsPrimvarDirty(SdfPath const &id, TfToken const &name)
Returns true if the rprim identified by id with primvar name is dirty.
HD_API unsigned GetRenderTagVersion() const
Retrieve the current version number of the render tag set.
static HD_API bool IsInstancerDirty(HdDirtyBits dirtyBits, SdfPath const &id)
Returns true if the dirtyBits has a dirty instancer. id is for perflog.
HD_API void AddInstancerInstancerDependency(SdfPath const &parentInstancerId, SdfPath const &instancerId)
Insert a dependency between instancerId and parent instancer parentInstancerId.
HD_API void TaskRemoved(SdfPath const &id)
Stop tracking Task with the given id.