renderIndex.h
1 //
2 // Copyright 2016 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_RENDER_INDEX_H
8 #define PXR_IMAGING_HD_RENDER_INDEX_H
9 
10 #include "pxr/pxr.h"
11 #include "pxr/imaging/hd/api.h"
12 #include "pxr/imaging/hd/version.h"
13 #include "pxr/imaging/hd/changeTracker.h"
14 #include "pxr/imaging/hd/dirtyList.h"
15 #include "pxr/imaging/hd/perfLog.h"
16 #include "pxr/imaging/hd/primTypeIndex.h"
17 #include "pxr/imaging/hd/resourceRegistry.h"
18 #include "pxr/imaging/hd/sortedIds.h"
19 #include "pxr/imaging/hd/tokens.h"
20 
21 #include "pxr/imaging/hd/sceneIndex.h"
22 #include "pxr/imaging/hd/mergingSceneIndex.h"
23 #include "pxr/imaging/hd/legacyPrimSceneIndex.h"
24 #include "pxr/imaging/hd/legacyTaskFactory.h"
25 #include "pxr/imaging/hd/noticeBatchingSceneIndex.h"
26 
27 #include "pxr/imaging/hf/perfLog.h"
28 
29 #include "pxr/usd/sdf/path.h"
30 
31 #include "pxr/base/gf/vec4i.h"
32 #include "pxr/base/tf/hashmap.h"
33 
34 #include <tbb/enumerable_thread_specific.h>
35 
36 #include <vector>
37 #include <unordered_map>
38 #include <memory>
39 #include <optional>
40 
41 PXR_NAMESPACE_OPEN_SCOPE
42 
43 class HdRprim;
44 class HdSprim;
45 class HdBprim;
46 class HdDrawItem;
47 class HdRprimCollection;
48 class HdSceneDelegate;
49 class HdRenderDelegate;
50 class HdExtComputation;
51 class VtValue;
52 class HdInstancer;
53 class HdDriver;
54 
55 using HdDriverVector = std::vector<HdDriver*>;
56 using HdRprimCollectionVector = std::vector<HdRprimCollection>;
57 using HdTaskSharedPtr = std::shared_ptr<class HdTask>;
58 using HdResourceRegistrySharedPtr = std::shared_ptr<class HdResourceRegistry>;
59 using HdTaskSharedPtrVector = std::vector<HdTaskSharedPtr>;
60 using HdTaskContext = std::unordered_map<TfToken,
61  VtValue,
63 
110 class HdRenderIndex final
111 {
112 public:
113  typedef std::vector<HdDrawItem const*> HdDrawItemPtrVector;
114 
124  // hgi = Hgi::CreatePlatformDefaultHgi()
125  // hgiDriver = new HdDriver<Hgi*>(HgiTokens→renderDriver, hgi)
126  // HdRenderIndex::New(_renderDelegate, {_hgiDriver})
127  //
136  HD_API
137  static HdRenderIndex* New(
138  HdRenderDelegate *renderDelegate,
139  HdDriverVector const& drivers,
140  const std::string &instanceName=std::string(),
141  const std::string &appName=std::string());
142 
154  HdRenderDelegate *renderDelegate,
155  HdDriverVector const& drivers,
156  HdSceneIndexBaseRefPtr const &terminalSceneIndex);
157 
166  static HdRenderIndex *
167  NewForFrontendEmulation(HdRenderDelegate *nullRenderDelegate);
168 
169  HD_API
170  ~HdRenderIndex();
171 
173  HD_API
174  void Clear();
175 
180  HD_API
181  void RemoveSubtree(const SdfPath &root, HdSceneDelegate* sceneDelegate);
182 
183  // ---------------------------------------------------------------------- //
186  HD_API
187  SdfPath GetRprimPathFromPrimId(int primId) const;
188 
189  // ---------------------------------------------------------------------- //
191  // ---------------------------------------------------------------------- //
192 
196  HD_API
197  void EnqueueCollectionToSync(HdRprimCollection const &collection);
198 
204  HD_API
205  void SyncAll(HdTaskSharedPtrVector *tasks, HdTaskContext *taskContext);
206 
208  HD_API bool IsSyncAllInProgress() const;
209 
210  // ---------------------------------------------------------------------- //
212  // ---------------------------------------------------------------------- //
213 
215  // by renderTags and collection.
218  HD_API
219  HdDrawItemPtrVector GetDrawItems(HdRprimCollection const& collection,
220  TfTokenVector const& renderTags);
221 
222  // ---------------------------------------------------------------------- //
224  // ---------------------------------------------------------------------- //
225 
226  HdChangeTracker& GetChangeTracker() { return _tracker; }
227  HdChangeTracker const& GetChangeTracker() const { return _tracker; }
228 
229  // ---------------------------------------------------------------------- //
231  // ---------------------------------------------------------------------- //
232 
234  HD_API
235  bool IsRprimTypeSupported(TfToken const& typeId) const;
236 
238  HD_API
239  void InsertRprim(TfToken const& typeId,
240  HdSceneDelegate* sceneDelegate,
241  SdfPath const& rprimId);
242 
244  HD_API
245  void RemoveRprim(SdfPath const& id);
246 
248  bool HasRprim(SdfPath const& id) {
249  return _rprimMap.find(id) != _rprimMap.end();
250  }
251 
253  HD_API
254  HdRprim const *GetRprim(SdfPath const &id) const;
255 
257  HD_API
259 
266  HD_API
268  SdfPath* sceneDelegateId,
269  SdfPath* instancerId) const;
270 
272  HD_API
273  TfToken GetRenderTag(SdfPath const& id) const;
274 
276  TfToken UpdateRenderTag(SdfPath const& id,
277  HdDirtyBits bits);
278 
281  HD_API
282  const SdfPathVector &GetRprimIds() { return _rprimIds.GetIds(); }
283 
284 
286  HD_API
287  SdfPathVector GetRprimSubtree(SdfPath const& root);
288 
289 
290  // ---------------------------------------------------------------------- //
292  // ---------------------------------------------------------------------- //
293 
295  HD_API
296  void InsertInstancer(HdSceneDelegate* delegate,
297  SdfPath const &id);
298 
300  HD_API
301  void RemoveInstancer(SdfPath const& id);
302 
304  bool HasInstancer(SdfPath const& id) {
305  return _instancerMap.find(id) != _instancerMap.end();
306  }
307 
309  HD_API
310  HdInstancer *GetInstancer(SdfPath const &id) const;
311 
312  // ---------------------------------------------------------------------- //
314  // ---------------------------------------------------------------------- //
315 
322  template <typename T>
323  void InsertTask(HdSceneDelegate* delegate, SdfPath const& id);
324 
331  HD_API
332  void RemoveTask(SdfPath const& id);
333 
340  bool HasTask(SdfPath const& id) {
341  return _taskMap.find(id) != _taskMap.end();
342  }
343 
345  HD_API
346  HdTaskSharedPtr const& GetTask(SdfPath const& id) const;
347 
348  // ---------------------------------------------------------------------- //
350  // ---------------------------------------------------------------------- //
351 
353  HD_API
354  bool IsSprimTypeSupported(TfToken const& typeId) const;
355 
357  HD_API
358  void InsertSprim(TfToken const& typeId,
359  HdSceneDelegate* delegate,
360  SdfPath const& sprimId);
361 
362  HD_API
363  void RemoveSprim(TfToken const& typeId, SdfPath const &id);
364 
365  HD_API
366  HdSprim *GetSprim(TfToken const& typeId, SdfPath const &id) const;
367 
370  HD_API
371  SdfPathVector GetSprimSubtree(TfToken const& typeId,
372  SdfPath const& root);
373 
375  HD_API
376  HdSprim *GetFallbackSprim(TfToken const& typeId) const;
377 
378 
379  // ---------------------------------------------------------------------- //
381  // ---------------------------------------------------------------------- //
382 
384  HD_API
385  bool IsBprimTypeSupported(TfToken const& typeId) const;
386 
388  HD_API
389  void InsertBprim(TfToken const& typeId,
390  HdSceneDelegate* delegate,
391  SdfPath const& bprimId);
392 
393  HD_API
394  void RemoveBprim(TfToken const& typeId, SdfPath const &id);
395 
396  HD_API
397  HdBprim *GetBprim(TfToken const& typeId, SdfPath const &id) const;
398 
401  HD_API
402  SdfPathVector GetBprimSubtree(TfToken const& typeId,
403  SdfPath const& root);
404 
406  HD_API
407  HdBprim *GetFallbackBprim(TfToken const& typeId) const;
408 
409  // ---------------------------------------------------------------------- //
411  // ---------------------------------------------------------------------- //
412  HD_API
413  void InsertSceneIndex(
414  const HdSceneIndexBaseRefPtr &inputScene,
415  SdfPath const& scenePathPrefix,
416  bool needsPrefixing = true);
417 
418  HD_API
419  void RemoveSceneIndex(
420  const HdSceneIndexBaseRefPtr &inputScene);
421 
424  HD_API
425  HdSceneIndexBaseRefPtr GetTerminalSceneIndex() const;
426 
427  HD_API
428  HdSceneIndexBaseRefPtr GetEmulationSceneIndex() const;
429 
430  // ---------------------------------------------------------------------- //
432  // ---------------------------------------------------------------------- //
436  HD_API
437  HdRenderDelegate *GetRenderDelegate() const;
438 
439  // The render delegate may require access to a render context / device
440  // that is provided by the application.
441  HD_API
442  HdDriverVector const& GetDrivers() const;
443 
446  HD_API
447  HdResourceRegistrySharedPtr GetResourceRegistry() const;
448 
456  HD_API
458 
464  HD_API
466 
472  HD_API
474 
480  HD_API
482 
483  HD_API
484  std::string GetInstanceName() const;
485 
486 private:
487  // The render index constructor is private so we can check
488  // renderDelegate before construction: see HdRenderIndex::New(...).
490  HdRenderDelegate *renderDelegate,
491  HdDriverVector const& drivers,
492  const std::string &instanceName,
493  const std::string &appName,
494  HdSceneIndexBaseRefPtr const &terminalSceneIndex = nullptr,
495  bool createFrontendEmulationOnly = false);
496 
497  // ---------------------------------------------------------------------- //
498  // Private Helper methods
499  // ---------------------------------------------------------------------- //
500 
501  // Go through all RPrims and reallocate their instance ids
502  // This is called once we have exhausted all 24bit instance ids.
503  void _CompactPrimIds();
504 
505  // Allocate the next available instance id to the prim
506  void _AllocatePrimId(HdRprim* prim);
507 
508  using HdTaskCreateFnc =
509  std::function<HdTaskSharedPtr(HdSceneDelegate*, SdfPath const&)>;
510 
511  // Implements InsertTask<T>.
512  // Inserts task going through emulation if enabled.
513  HD_API
514  void _InsertSceneDelegateTask(
515  HdSceneDelegate* delegate,
516  SdfPath const& taskId,
517  HdLegacyTaskFactorySharedPtr factory);
518 
519  template <typename T>
520  static inline const TfToken & _GetTypeId();
521 
522 
523  // Private versions of equivalent public methods which insert and remove
524  // from this render index.
525  //
526  // The public versions check to see if scene delegate emulation is active.
527  // If not, they call through to these. Otherwise, they forward to the
528  // the HdLegacyPrimSceneIndex member. If a legacy render delegate is also
529  // in use, the scene index chain will terminate with a
530  // HdSceneIndexAdapterSceneDelegate. That will call the private versions
531  // directly so that the internal render index tables are updated.
532  //
533  // This prevents cyclic insertion/removals while allowing a single
534  // HdRenderIndex to be used for both front and back-end emulation.
535  //
536  // Note: all render index users should call the public APIs; only
537  // sceneIndexAdapterSceneDelegate.cpp should call these versions, to keep
538  // state synchronized. Note, for example, that _RemoveSubtree and _Clear
539  // don't affect the task map, since tasks aren't part of emulation, whereas
540  // RemoveSubtree and Clear do affect the task map...
542  void _InsertRprim(TfToken const& typeId,
543  HdSceneDelegate* sceneDelegate,
544  SdfPath const& rprimId);
545  void _InsertSprim(TfToken const& typeId,
546  HdSceneDelegate* delegate,
547  SdfPath const& sprimId);
548  void _InsertBprim(TfToken const& typeId,
549  HdSceneDelegate* delegate,
550  SdfPath const& bprimId);
551  void _InsertInstancer(HdSceneDelegate* delegate,
552  SdfPath const &id);
553  void _InsertTask(HdSceneDelegate* delegate,
554  SdfPath const &id,
555  HdTaskSharedPtr const &task);
556 
557  void _RemoveRprim(SdfPath const& id);
558  void _RemoveSprim(TfToken const& typeId, SdfPath const& id);
559  void _RemoveBprim(TfToken const& typeId, SdfPath const& id);
560  void _RemoveInstancer(SdfPath const& id);
561  void _RemoveSubtree(SdfPath const& id, HdSceneDelegate* sceneDelegate);
562  void _RemoveRprimSubtree(const SdfPath &root,
563  HdSceneDelegate* sceneDelegate);
564  void _RemoveInstancerSubtree(const SdfPath &root,
565  HdSceneDelegate* sceneDelegate);
566  void _RemoveExtComputationSubtree(const SdfPath &root,
567  HdSceneDelegate* sceneDelegate);
568  void _RemoveTaskSubtree(const SdfPath &root,
569  HdSceneDelegate* sceneDelegate);
570  void _RemoveTask(SdfPath const &id);
571  void _Clear();
572 
573  // ---------------------------------------------------------------------- //
574  // Index State
575  // ---------------------------------------------------------------------- //
576  struct _RprimInfo {
577  HdSceneDelegate *sceneDelegate;
578  HdRprim *rprim;
579  };
580 
581  class _NoticeBatchingContext;
582 
583  HdLegacyPrimSceneIndexRefPtr _emulationSceneIndex;
584  std::unique_ptr<_NoticeBatchingContext> _emulationBatchingCtx;
585 
586  std::unique_ptr<class HdSceneIndexAdapterSceneDelegate> _siSd;
587 
588  HdMergingSceneIndexRefPtr _mergingSceneIndex;
589  std::unique_ptr<_NoticeBatchingContext> _mergingBatchingCtx;
590 
591  HdSceneIndexBaseRefPtr _terminalSceneIndex;
592 
593  struct _TaskInfo {
594  HdSceneDelegate *sceneDelegate;
595  HdTaskSharedPtr task;
596  };
597 
598  typedef std::unordered_map<SdfPath, _TaskInfo, SdfPath::Hash> _TaskMap;
599  typedef TfHashMap<SdfPath, _RprimInfo, SdfPath::Hash> _RprimMap;
600  typedef std::vector<SdfPath> _RprimPrimIDVector;
601 
602  typedef Hd_PrimTypeIndex<HdSprim> _SprimIndex;
603  typedef Hd_PrimTypeIndex<HdBprim> _BprimIndex;
604 
605  _RprimMap _rprimMap;
606  Hd_SortedIds _rprimIds;
607 
608  // Prim id -> rprim path table. Only maintained (and non-empty optional)
609  // if the prim id is not coming from the given terminal scene index.
610  //
611  std::optional<_RprimPrimIDVector> _rprimPrimIdMap;
612 
613  _TaskMap _taskMap;
614 
615  _SprimIndex _sprimIndex;
616  _BprimIndex _bprimIndex;
617 
618  HdChangeTracker _tracker;
619 
620  typedef TfHashMap<SdfPath, HdInstancer*, SdfPath::Hash> _InstancerMap;
621  _InstancerMap _instancerMap;
622 
623  HdRenderDelegate *_renderDelegate;
624  HdDriverVector _drivers;
625 
626  HdSceneIndexBaseRefPtr _finalEmulationSceneIndex;
627 
628  std::string _instanceName;
629 
630  // ---------------------------------------------------------------------- //
631  // Sync State
632  // ---------------------------------------------------------------------- //
633  HdRprimCollectionVector _collectionsToSync;
634  HdDirtyList _rprimDirtyList;
635 
636  // Call depth to SyncAll(). Should only ever be 0 or 1.
637  std::atomic<int> _syncAllDepth;
638 
639  // ---------------------------------------------------------------------- //
640 
642  void _InitPrimTypes();
643 
645  bool _CreateFallbackPrims();
646 
648  void _DestroyFallbackPrims();
649 
650  typedef tbb::enumerable_thread_specific<HdDrawItemPtrVector>
651  _ConcurrentDrawItems;
652 
653  void _AppendDrawItems(const SdfPathVector &rprimIds,
654  size_t begin,
655  size_t end,
656  HdRprimCollection const& collection,
657  _ConcurrentDrawItems* result);
658 
662  static void _ConfigureReprs();
663 
664  // Remove default constructor
665  HdRenderIndex() = delete;
666 
667  // Don't allow copies
668  HdRenderIndex(const HdRenderIndex &) = delete;
669  HdRenderIndex &operator=(const HdRenderIndex &) = delete;
670 
671 };
672 
673 template <typename T>
674 void
676 {
677  _InsertSceneDelegateTask(
678  delegate, id, HdMakeLegacyTaskFactory<T>());
679 }
680 
681 PXR_NAMESPACE_CLOSE_SCOPE
682 
683 #endif //PXR_IMAGING_HD_RENDER_INDEX_H
Hydra Representation of a Client defined computation.
The render index is part of the Hydra 1.0 API and is only used for emulation purposes so that HdScene...
Definition: renderIndex.h:110
HD_API bool IsRprimTypeSupported(TfToken const &typeId) const
Returns whether the rprim type is supported by this render index.
HD_API void InsertBprim(TfToken const &typeId, HdSceneDelegate *delegate, SdfPath const &bprimId)
Insert a bprim into index.
HD_API HdRenderDelegate * GetRenderDelegate() const
Currently, a render index only supports connection to one type of render delegate,...
static HdRenderIndex * NewForBackendEmulation(HdRenderDelegate *renderDelegate, HdDriverVector const &drivers, HdSceneIndexBaseRefPtr const &terminalSceneIndex)
Create a render index with the given render delegate that populates itself by observing the given sce...
HD_API HdRprim const * GetRprim(SdfPath const &id) const
Returns the rprim of id.
Tracks changes from the HdSceneDelegate, providing invalidation cues to the render engine.
Definition: changeTracker.h:34
This class exists to facilitate point cloud style instancing.
Definition: instancer.h:108
HD_API void RemoveSubtree(const SdfPath &root, HdSceneDelegate *sceneDelegate)
Clear all entries in the render index under the given root and belong to a specified delegate.
Functor to use for hash maps from tokens to other things.
Definition: token.h:176
HD_API void InsertInstancer(HdSceneDelegate *delegate, SdfPath const &id)
Insert an instancer into index.
HD_API void SceneIndexEmulationNoticeBatchBegin()
An application or legacy scene delegate may prefer for the scene index observer notices generated fro...
static HdRenderIndex * NewForFrontendEmulation(HdRenderDelegate *nullRenderDelegate)
Create a render index for "front-end" emulation.
HD_API void InsertSprim(TfToken const &typeId, HdSceneDelegate *delegate, SdfPath const &sprimId)
Insert a sprim into index.
HD_API void InsertRprim(TfToken const &typeId, HdSceneDelegate *sceneDelegate, SdfPath const &rprimId)
Insert a rprim into index.
static HD_API HdRenderIndex * New(HdRenderDelegate *renderDelegate, HdDriverVector const &drivers, const std::string &instanceName=std::string(), const std::string &appName=std::string())
"instanceName" is an optional identifier useful for applications to associate this render index with ...
HD_API bool IsSyncAllInProgress() const
Returns true while a thread is invoking SyncAll().
HD_API const SdfPathVector & GetRprimIds()
Returns a sorted list of all Rprims in the render index.
Definition: renderIndex.h:282
HD_API void RemoveRprim(SdfPath const &id)
Remove a rprim from index.
Scene delegate which observes notices from an HdSceneIndex and applies them to an HdRenderIndex.
Token for efficient comparison, assignment, and hashing of known strings.
Definition: token.h:80
HdDriver represents a device object, commonly a render device, that is owned by the application and p...
Definition: driver.h:23
The render engine state for a given rprim from the scene graph.
Definition: rprim.h:37
HD_API HdSceneIndexBaseRefPtr GetTerminalSceneIndex() const
The terminal scene index that is driving what is in the render index through emulation.
HD_API void Clear()
Clear all r (render), s (state) and b (buffer) prims.
HD_API HdInstancer * GetInstancer(SdfPath const &id) const
Returns the instancer of id.
HD_API void RemoveTask(SdfPath const &id)
HD_API void SyncAll(HdTaskSharedPtrVector *tasks, HdTaskContext *taskContext)
Syncs input tasks, B & S prims, (external) computations and updates the Rprim dirty list to then sync...
Adapter class providing data exchange with the client scene graph.
HD_API HdSprim * GetFallbackSprim(TfToken const &typeId) const
Returns the fullback prim for the Sprim of the given type.
bool HasInstancer(SdfPath const &id)
Returns true if instancer id exists in index.
Definition: renderIndex.h:304
HD_API bool IsBprimTypeSupported(TfToken const &typeId) const
Returns whether the bprim type is supported by this render index.
std::vector< TfToken > TfTokenVector
Convenience types.
Definition: token.h:489
bool HasTask(SdfPath const &id)
Definition: renderIndex.h:340
A named, semantic collection of objects.
A path value used to locate objects in layers or scenegraphs.
Definition: path.h:280
HD_API bool IsSprimTypeSupported(TfToken const &typeId) const
Returns whether the sprim type is supported by this render index.
HD_API SdfPathVector GetRprimSubtree(SdfPath const &root)
Returns the subtree rooted under the given path.
Used for faster iteration of dirty Rprims by the render index.
Definition: dirtyList.h:86
bool HasRprim(SdfPath const &id)
Returns true if rprim id exists in index.
Definition: renderIndex.h:248
HD_API SdfPathVector GetBprimSubtree(TfToken const &typeId, SdfPath const &root)
Returns the subtree rooted under the given path for the given bprim type.
Sprim (state prim) is a base class of managing state for non-drawable scene entity (e....
Definition: sprim.h:34
HD_API HdSceneDelegate * GetSceneDelegateForRprim(SdfPath const &id) const
Returns the scene delegate for the given rprim.
A draw item is a light-weight representation of an HdRprim's resources and material to be used for re...
Definition: drawItem.h:47
HD_API HdDrawItemPtrVector GetDrawItems(HdRprimCollection const &collection, TfTokenVector const &renderTags)
Returns a list of relevant draw items that match the criteria specified.
HD_API void MergingSceneIndexNoticeBatchEnd()
Flushes any queued scene index observer notices from the merging scene index and disables further que...
Bprim (buffer prim) is a base class of managing a blob of data that is used to communicate between th...
Definition: bprim.h:39
HD_API void SceneIndexEmulationNoticeBatchEnd()
Flushes any queued scene index observer notices and disables further queueing.
HD_API void MergingSceneIndexNoticeBatchBegin()
Consolidate notices generated by the merging scene index to vectorized batches.
HD_API void EnqueueCollectionToSync(HdRprimCollection const &collection)
Hydra's core currently needs to know the collections used by tasks to aggregate the reprs that need t...
void InsertTask(HdSceneDelegate *delegate, SdfPath const &id)
Definition: renderIndex.h:675
HD_API HdBprim * GetFallbackBprim(TfToken const &typeId) const
Returns the fallback prim for the Bprim of the given type.
TfToken UpdateRenderTag(SdfPath const &id, HdDirtyBits bits)
Like GetRenderTag, but updates the render tag if dirty.
HD_API bool GetSceneDelegateAndInstancerIds(SdfPath const &id, SdfPath *sceneDelegateId, SdfPath *instancerId) const
Query function to return the id's of the scene delegate and instancer associated with the Rprim at th...
HD_API void RemoveInstancer(SdfPath const &id)
Remove an instancer from index.
Provides a container which may hold any type, and provides introspection and iteration over array typ...
Definition: value.h:89
HD_API SdfPath GetRprimPathFromPrimId(int primId) const
Given a prim id, returns the path of the corresponding rprim or an empty path if none is found.
HD_API SdfPathVector GetSprimSubtree(TfToken const &typeId, SdfPath const &root)
Returns the subtree rooted under the given path for the given sprim type.
HD_API TfToken GetRenderTag(SdfPath const &id) const
Returns the render tag for the given rprim.
HD_API HdTaskSharedPtr const & GetTask(SdfPath const &id) const
Returns the task for the given id.
HD_API HdResourceRegistrySharedPtr GetResourceRegistry() const
Returns a shared ptr to the resource registry of the current render delegate.