HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
dataSource.h
Go to the documentation of this file.
1 //
2 // Copyright 2021 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_DATASOURCE_H
8 #define PXR_IMAGING_HD_DATASOURCE_H
9 
10 #include "pxr/pxr.h"
11 
12 #include "pxr/imaging/hd/api.h"
14 
15 #include "pxr/base/tf/token.h"
16 #include "pxr/base/vt/value.h"
17 #include "pxr/base/vt/visitValue.h"
18 
19 #include <iosfwd>
20 #include <memory>
21 #include <vector>
22 #include <atomic>
23 
25 
26 /// HD_DECLARE_DATASOURCE_ABSTRACT
27 /// Used for non-instantiable classes, this defines a set of functions
28 /// for manipulating handles to this type of datasource.
29 #define HD_DECLARE_DATASOURCE_ABSTRACT(type) \
30  using Handle = std::shared_ptr<type>; \
31  using AtomicHandle = Handle; \
32  static Handle AtomicLoad(AtomicHandle &ptr) { \
33  return std::atomic_load(&ptr); \
34  } \
35  static void AtomicStore(AtomicHandle &ptr, const Handle &v) { \
36  std::atomic_store(&ptr, v); \
37  } \
38  static bool AtomicCompareExchange(AtomicHandle &ptr, \
39  AtomicHandle &expected, \
40  const Handle &desired) { \
41  return std::atomic_compare_exchange_strong(&ptr, &expected, desired); \
42  } \
43  static Handle Cast(const HdDataSourceBase::Handle &v) { \
44  return std::dynamic_pointer_cast<type>(v); \
45  }
46 
47 /// HD_DECLARE_DATASOURCE
48 /// Used for instantiable classes, this defines functions for manipulating
49 /// and allocating handles to this type of datasource.
50 ///
51 /// Use of this macro in derived classes is important to make sure that
52 /// core and client code share the same handle type and allocator.
53 #define HD_DECLARE_DATASOURCE(type) \
54  HD_DECLARE_DATASOURCE_ABSTRACT(type) \
55  template <typename ... Args> \
56  static Handle New(Args&& ... args) { \
57  return Handle(new type(std::forward<Args>(args) ... )); \
58  }
59 
60 /// HD_DECLARE_DATASOURCE_INITIALIZER_LIST_NEW
61 /// Used for declaring a `New` function for datasource types that have a
62 /// constructor that takes an initializer_list<T>.
63 #define HD_DECLARE_DATASOURCE_INITIALIZER_LIST_NEW(type, T) \
64  static Handle New(std::initializer_list<T> initList) { \
65  return Handle(new type(initList)); \
66  }
67 
68 #define HD_DECLARE_DATASOURCE_HANDLES(type) \
69  using type##Handle = type::Handle; \
70  using type##AtomicHandle = type::AtomicHandle;
71 
72 /// \class HdDataSourceBase
73 ///
74 /// Represents an object which can produce scene data.
75 /// \sa HdContainerDataSource HdVectorDataSource HdSampledDataSource
76 /// Note that most derived classes will have standard API for allocation
77 /// and handle manipulation. Derived classes that don't support instantiation
78 /// should use HD_DECLARE_DATASOURCE_ABSTRACT, which omits the
79 /// definition of ::New().
80 ///
82 {
83 public:
85 
86  HD_API
87  virtual ~HdDataSourceBase() = 0;
88 };
89 
91 
92 /// \class HdContainerDataSource
93 ///
94 /// A datasource representing structured (named, hierarchical) data, for
95 /// example a geometric primitive or a sub-object like a material definition.
96 /// Note that implementations are responsible for providing cache invalidation,
97 /// if necessary.
98 ///
100 {
101 public:
103 
104  /// Returns the list of names for which \p Get(...) is expected to return
105  /// a non-null value. This call is expected to be threadsafe.
106  virtual TfTokenVector GetNames() = 0;
107 
108  /// Returns the child datasource of the given name. This call is expected
109  /// to be threadsafe.
110  virtual HdDataSourceBaseHandle Get(const TfToken &name) = 0;
111 
112  /// A convenience function: given \p container, return the descendant
113  /// identified by \p locator, which may be at any depth. Returns
114  /// \p container itself on an empty locator, or null if \p locator doesn't
115  /// identify a valid descendant.
116  HD_API
117  static HdDataSourceBaseHandle Get(
118  const Handle &container,
119  const HdDataSourceLocator &locator);
120 };
121 
123 
124 /// \class HdVectorDataSource
125 ///
126 /// A datasource representing indexed data. This should be used when a scene
127 /// index is expected to manipulate the indexing; for array-valued data, a
128 /// \p HdSampledDataSource can be used instead. Note that implementations are
129 /// responsible for providing cache invalidation, if necessary.
130 ///
132 {
133 public:
135 
136  /// Return the number of elements in this datasource. This call is
137  /// expected to be threadsafe.
138  virtual size_t GetNumElements() = 0;
139 
140  /// Return the element at position \p element in this datasource. This
141  /// is expected to return non-null for the range [0, \p numElements).
142  /// This call is expected to be threadsafe.
143  virtual HdDataSourceBaseHandle GetElement(size_t element) = 0;
144 };
145 
147 
148 /// \class HdSampledDataSource
149 ///
150 /// A datasource representing time-sampled values. Note that implementations
151 /// are responsible for providing cache invalidation, if necessary.
152 ///
154 {
155 public:
157  using Time = float;
158 
159  /// Returns the value of this data source at frame-relative time
160  /// \p shutterOffset. The caller does not track the frame; the scene
161  /// index producing this datasource is responsible for that, if applicable.
162  /// Note that, although this call returns a VtValue for each shutter
163  /// offset, the type of the held value is expected to be the same across
164  /// all shutter offsets. This call is expected to be threadsafe.
165  virtual VtValue GetValue(Time shutterOffset) = 0;
166 
167  /// Given a shutter window of interest (\p startTime and \p endTime
168  /// relative to the current frame), return a list of sample times for the
169  /// caller to query with GetValue such that the caller can reconstruct the
170  /// signal over the shutter window. For a sample-based attribute, this
171  /// might be a list of times when samples are defined. For a procedural
172  /// scene, this might be a generated distribution. Note that the returned
173  /// samples don't need to be within \p startTime and \p endTime; if
174  /// a boundary sample is outside of the window, implementers can return it,
175  /// and callers should expect it and interpolate to \p startTime or
176  /// \p endTime accordingly. If this call returns \p true, the caller is
177  /// expected to pass the list of \p outSampleTimes to \p GetValue. If this
178  /// call returns \p false, this value is uniform across the shutter window
179  /// and the caller should call \p GetValue(0) to get that uniform value.
181  Time startTime,
182  Time endTime,
183  std::vector<Time> * outSampleTimes) = 0;
184 
185 protected:
187 
188  HD_API
189  virtual VtValue _GetDefaultValue();
190 };
191 
193 
194 /// \class HdTypedSampledDataSource
195 ///
196 /// A datasource representing a concretely-typed sampled value.
197 ///
198 template <typename T>
200 {
201 public:
203  using Type = T;
204 
205  /// Returns the value of this data source at frame-relative time
206  /// \p shutterOffset, as type \p T.
207  virtual T GetTypedValue(Time shutterOffset) = 0;
208 
209 protected:
210  virtual VtValue _GetDefaultValue() override {
211  if constexpr (VtIsKnownValueType<T>()) {
212  return VtValue(T());
213  } else {
214  return VtValue();
215  }
216  }
217 };
218 
219 /// \class HdBlockDataSource
220 ///
221 /// A datasource representing the absence of a datasource. If a container has
222 /// a child datasource which is a block datasource, that's equivalent to that
223 /// child being null. This type is useful when composing containers, where a
224 /// block might shadow sampled data, and sampled data might shadow nullptr.
225 ///
227 {
228 public:
230 
232 };
233 
235 
236 // Utilities //////////////////////////////////////////////////////////////////
237 
238 // Helper to let HdVisitSampledDataSourceType access a source's value type.
240 {
241 public:
242  static VtValue
243  GetDefaultValue(const HdSampledDataSourceHandle &dataSource) {
244  return dataSource ? dataSource->_GetDefaultValue() : VtValue {};
245  }
246 };
247 
248 /// Helper function to determine the type of a TypeSampledDataSource and perform
249 /// some operations.
250 /// Takes a "SampledDataSource", a "Visitor" class (which has a static "Visit"
251 /// function) and some arguments. The data source's type "T" will be determined
252 /// and Visitor<T>::Visit will be called with your arguments. If the data
253 /// source's type cannot be determined or it is an untyped SampledDataSource,
254 /// Visitor<VtValue>::Visit will be called.
255 ///
256 /// This is identical to `VtVisitValueType<Visitor, TypeArgs...>(value,
257 /// args...)` except that instead of a VtValue `value`, the value type is
258 /// determined by the passed `dataSource`.
259 template <
260  template <class T, class ...> class Visitor,
261  typename ...TypeArgs,
262  typename ...FnArgs
263  >
264 auto
266  const HdSampledDataSourceHandle& dataSource, FnArgs&&... args)
267 {
268  return VtVisitValueType<Visitor, TypeArgs...>(
270  std::forward<FnArgs>(args)...);
271 }
272 
273 /// Overload that accepts a leading class template argument that is passed to
274 /// the visitor as the second template argument.
275 ///
276 /// This is identical to `VtVisitValueType<Visitor, Tmpl, TypeArgs...>(value,
277 /// args...)` except that instead of a VtValue `value`, the value type is
278 /// determined by the passed `dataSource`.
279 template <
280  template <class T, template <class...> class, class ...> class Visitor,
281  template <class...> class Tmpl,
282  typename ...TypeArgs,
283  typename ...FnArgs
284  >
285 auto
287  const HdSampledDataSourceHandle& dataSource, FnArgs&&... args)
288 {
289  return VtVisitValueType<Visitor, Tmpl, TypeArgs...>(
291  std::forward<FnArgs>(args)...);
292 }
293 
294 /// A VtValue visitor that invokes DataSource<T>::New(args...) if T is one of
295 /// the "known" Vt value types (see VtVisitValue). If T is not one of the known
296 /// types, then if `UntypedDataSource` is `void` return `nullptr`, otherwise
297 /// return UntypedDataSource::New(args...).
298 template <
299  typename T,
300  template <typename...> class DataSource,
301  class UntypedDataSource>
303 {
304  template <class ...Args>
305  static HdDataSourceBaseHandle Visit(Args&&... args)
306  {
307  if constexpr (std::is_same_v<T, VtValue>) {
308  if constexpr (std::is_void_v<UntypedDataSource>) {
309  return nullptr;
310  }
311  else {
312  return UntypedDataSource::New(std::forward<Args>(args)...);
313  }
314  }
315  else {
316  return DataSource<T>::New(std::forward<Args>(args)...);
317  }
318  }
319 };
320 
321 /// Helper function to create a new typed data source with the same type as the
322 /// input sampled data source. DataSource<T>::New will be returned using the
323 /// provided args. For untyped input data sources nullptr or
324 /// UntypedDataSource::New will be returned (if UntypedDataSource was provided).
325 template <
326  template <typename...> class DataSource,
327  class UntypedDataSource = void,
328  typename... Args>
329 HdDataSourceBaseHandle
331  const HdSampledDataSourceHandle& dataSource, Args&&... args)
332 {
334  Hd_CopySampledDataSourceTypeVisitor, DataSource, UntypedDataSource>(
335  dataSource, std::forward<Args>(args)...);
336 }
337 
338 /// Merges contributing sample times from several data sources.
339 HD_API
340 bool
342  size_t count,
343  const HdSampledDataSourceHandle *inputDataSources,
344  HdSampledDataSource::Time startTime,
346  std::vector<HdSampledDataSource::Time> * outSampleTimes);
347 
348 /// Print a datasource to a stream, for debugging/testing.
349 HD_API
350 void
352  std::ostream &,
353  HdDataSourceBaseHandle,
354  int indentLevel = 0);
355 
356 /// Print a datasource to stdout, for debugging/testing
357 HD_API
358 void
359 HdDebugPrintDataSource(HdDataSourceBaseHandle, int indentLevel = 0);
360 
362 
363 #endif // PXR_IMAGING_HD_DATASOURCE_H
virtual HdDataSourceBaseHandle GetElement(size_t element)=0
virtual VtValue _GetDefaultValue() override
Definition: dataSource.h:210
static HdDataSourceBaseHandle Visit(Args &&...args)
Definition: dataSource.h:305
HdDataSourceBaseHandle HdCopySampledDataSourceType(const HdSampledDataSourceHandle &dataSource, Args &&...args)
Definition: dataSource.h:330
void
Definition: png.h:1083
#define PXR_NAMESPACE_OPEN_SCOPE
Definition: pxr.h:73
auto VtVisitValueType(VtValue const &value, FnArgs &&...args)
Definition: visitValue.h:187
HD_DECLARE_DATASOURCE_ABSTRACT(HdContainerDataSource)
#define HD_API
Definition: api.h:23
static VtValue GetDefaultValue(const HdSampledDataSourceHandle &dataSource)
Definition: dataSource.h:243
virtual TfTokenVector GetNames()=0
virtual HdDataSourceBaseHandle Get(const TfToken &name)=0
HD_DECLARE_DATASOURCE_ABSTRACT(HdTypedSampledDataSource< T >)
Definition: token.h:70
auto HdVisitSampledDataSourceType(const HdSampledDataSourceHandle &dataSource, FnArgs &&...args)
Definition: dataSource.h:265
virtual size_t GetNumElements()=0
std::vector< TfToken > TfTokenVector
Convenience types.
Definition: token.h:440
#define HD_DECLARE_DATASOURCE_HANDLES(type)
Definition: dataSource.h:68
GLuint const GLchar * name
Definition: glcorearb.h:786
HD_DECLARE_DATASOURCE_ABSTRACT(HdSampledDataSource)
HD_API bool HdGetMergedContributingSampleTimesForInterval(size_t count, const HdSampledDataSourceHandle *inputDataSources, HdSampledDataSource::Time startTime, HdSampledDataSource::Time endTime, std::vector< HdSampledDataSource::Time > *outSampleTimes)
Merges contributing sample times from several data sources.
virtual VtValue GetValue(Time shutterOffset)=0
IMATH_NAMESPACE::V2f IMATH_NAMESPACE::Box2i std::string this attribute is obsolete as of OpenEXR v3 float
HD_DECLARE_DATASOURCE_ABSTRACT(HdVectorDataSource)
#define HD_DECLARE_DATASOURCE_ABSTRACT(type)
Definition: dataSource.h:29
virtual T GetTypedValue(Time shutterOffset)=0
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
**If you just want to fire and args
Definition: thread.h:618
virtual HD_API ~HdDataSourceBase()=0
virtual bool GetContributingSampleTimesForInterval(Time startTime, Time endTime, std::vector< Time > *outSampleTimes)=0
HD_API void HdDebugPrintDataSource(std::ostream &, HdDataSourceBaseHandle, int indentLevel=0)
Print a datasource to a stream, for debugging/testing.
HD_DECLARE_DATASOURCE(HdBlockDataSource)
virtual HD_API VtValue _GetDefaultValue()
Definition: value.h:89
GLint GLsizei count
Definition: glcorearb.h:405
void * Handle
Definition: plugin.h:27