dataSource.h
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"
13 #include "pxr/imaging/hd/dataSourceLocator.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 
24 PXR_NAMESPACE_OPEN_SCOPE
25 
31 template <typename U>
33 {
34  using value_type = U;
35  template <typename V>
36  struct rebind { using other = HdDataSourceAllocator<V>; };
37  HdDataSourceAllocator() = default;
38  template <typename V>
40  U* allocate(size_t n) { return std::allocator<U>{ }.allocate(n); }
41  void deallocate(U* p, size_t n)
42  { std::allocator<U>{ }.deallocate(p, n); }
43  template <typename... Args>
44  void construct(U*p, Args&&... args)
45  { ::new(static_cast<void*>(p)) U(std::forward<Args>(args)...); }
46  void destroy(U* p) { p->~U(); }
47 };
48 
49 // XXX: clang is strict about qualified friend declarations, and will not
50 // forward PXR_NS -> PXR_INTERNAL_NS when present. But PXR_INTERNAL_NS is not
51 // always defined in all builds, so we can't just use that, either.
52 #if defined(PXR_INTERNAL_NS)
53 #define _HD_ALLOCATOR_FRIEND \
54  template <typename> friend struct PXR_INTERNAL_NS::HdDataSourceAllocator;
55 #else
56 #define _HD_ALLOCATOR_FRIEND \
57  template <typename> friend struct PXR_NS::HdDataSourceAllocator;
58 #endif
59 
66 #define HD_DECLARE_DATASOURCE_ABSTRACT(type) \
67  using Handle = std::shared_ptr<type>; \
68  using AtomicHandle = Handle; \
69  static Handle AtomicLoad(AtomicHandle &ptr) { \
70  return std::atomic_load(&ptr); \
71  } \
72  static void AtomicStore(AtomicHandle &ptr, const Handle &v) { \
73  std::atomic_store(&ptr, v); \
74  } \
75  static bool AtomicCompareExchange(AtomicHandle &ptr, \
76  AtomicHandle &expected, \
77  const Handle &desired) { \
78  return std::atomic_compare_exchange_strong(&ptr, &expected, desired); \
79  } \
80  static Handle Cast(const HdDataSourceBase::Handle &v) { \
81  return std::dynamic_pointer_cast<type>(v); \
82  }
83 
91 #define HD_DECLARE_DATASOURCE(type) \
92  HD_DECLARE_DATASOURCE_ABSTRACT(type) \
93  _HD_ALLOCATOR_FRIEND \
94  template <typename ... Args> \
95  static Handle New(Args&& ... args) { \
96  return std::allocate_shared<type>( \
97  PXR_NS::HdDataSourceAllocator<type>{ }, \
98  std::forward<Args>(args)...); \
99  }
100 
109 #define HD_DECLARE_DATASOURCE_INITIALIZER_LIST_NEW(type, T) \
110  static Handle New(std::initializer_list<T> initList) { \
111  return std::allocate_shared<type>( \
112  PXR_NS::HdDataSourceAllocator<type>{ }, \
113  (initList)); \
114  }
115 
116 #define HD_DECLARE_DATASOURCE_HANDLES(type) \
117  using type##Handle = type::Handle; \
118  using type##AtomicHandle = type::AtomicHandle;
119 
130 {
131 public:
132  HD_DECLARE_DATASOURCE_ABSTRACT(HdDataSourceBase)
133 
134  HD_API
135  virtual ~HdDataSourceBase() = 0;
136 };
137 
138 HD_DECLARE_DATASOURCE_HANDLES(HdDataSourceBase);
139 
148 {
149 public:
150  HD_DECLARE_DATASOURCE_ABSTRACT(HdContainerDataSource);
151 
154  virtual TfTokenVector GetNames() = 0;
155 
158  virtual HdDataSourceBaseHandle Get(const TfToken &name) = 0;
159 
164  HD_API
165  static HdDataSourceBaseHandle Get(
166  const Handle &container,
167  const HdDataSourceLocator &locator);
168 };
169 
170 HD_DECLARE_DATASOURCE_HANDLES(HdContainerDataSource);
171 
180 {
181 public:
182  HD_DECLARE_DATASOURCE_ABSTRACT(HdVectorDataSource);
183 
186  virtual size_t GetNumElements() = 0;
187 
191  virtual HdDataSourceBaseHandle GetElement(size_t element) = 0;
192 };
193 
194 HD_DECLARE_DATASOURCE_HANDLES(HdVectorDataSource);
195 
202 {
203 public:
204  HD_DECLARE_DATASOURCE_ABSTRACT(HdSampledDataSource);
205  using Time = float;
206 
213  virtual VtValue GetValue(Time shutterOffset) = 0;
214 
229  Time startTime,
230  Time endTime,
231  std::vector<Time> * outSampleTimes) = 0;
232 
233 protected:
234  friend class Hd_SampledDataSourceDefaultValueAccessor;
235 
236  HD_API
237  virtual VtValue _GetDefaultValue();
238 };
239 
240 HD_DECLARE_DATASOURCE_HANDLES(HdSampledDataSource);
241 
246 template <typename T>
248 {
249 public:
250  HD_DECLARE_DATASOURCE_ABSTRACT(HdTypedSampledDataSource<T>);
251  using Type = T;
252 
255  virtual T GetTypedValue(Time shutterOffset) = 0;
256 
257 protected:
258  virtual VtValue _GetDefaultValue() override {
259  if constexpr (VtIsKnownValueType<T>()) {
260  return VtValue(T());
261  } else {
262  return VtValue();
263  }
264  }
265 };
266 
275 {
276 public:
277  HD_DECLARE_DATASOURCE(HdBlockDataSource);
278 protected:
279  HdBlockDataSource() = default;
280 };
281 
282 HD_DECLARE_DATASOURCE_HANDLES(HdBlockDataSource);
283 
284 // Utilities //////////////////////////////////////////////////////////////////
285 
286 // Helper to let HdVisitSampledDataSourceType access a source's value type.
287 class Hd_SampledDataSourceDefaultValueAccessor
288 {
289 public:
290  static VtValue
291  GetDefaultValue(const HdSampledDataSourceHandle &dataSource) {
292  return dataSource ? dataSource->_GetDefaultValue() : VtValue {};
293  }
294 };
295 
307 template <
308  template <class T, class ...> class Visitor,
309  typename ...TypeArgs,
310  typename ...FnArgs
311  >
312 auto
313 HdVisitSampledDataSourceType(
314  const HdSampledDataSourceHandle& dataSource, FnArgs&&... args)
315 {
316  return VtVisitValueType<Visitor, TypeArgs...>(
317  Hd_SampledDataSourceDefaultValueAccessor::GetDefaultValue(dataSource),
318  std::forward<FnArgs>(args)...);
319 }
320 
327 template <
328  template <class T, template <class...> class, class ...> class Visitor,
329  template <class...> class Tmpl,
330  typename ...TypeArgs,
331  typename ...FnArgs
332  >
333 auto
334 HdVisitSampledDataSourceType(
335  const HdSampledDataSourceHandle& dataSource, FnArgs&&... args)
336 {
337  return VtVisitValueType<Visitor, Tmpl, TypeArgs...>(
338  Hd_SampledDataSourceDefaultValueAccessor::GetDefaultValue(dataSource),
339  std::forward<FnArgs>(args)...);
340 }
341 
346 template <
347  typename T,
348  template <typename...> class DataSource,
349  class UntypedDataSource>
350 struct Hd_CopySampledDataSourceTypeVisitor
351 {
352  template <class ...Args>
353  static HdDataSourceBaseHandle Visit(Args&&... args)
354  {
355  if constexpr (std::is_same_v<T, VtValue>) {
356  if constexpr (std::is_void_v<UntypedDataSource>) {
357  return nullptr;
358  }
359  else {
360  return UntypedDataSource::New(std::forward<Args>(args)...);
361  }
362  }
363  else {
364  return DataSource<T>::New(std::forward<Args>(args)...);
365  }
366  }
367 };
368 
373 template <
374  template <typename...> class DataSource,
375  class UntypedDataSource = void,
376  typename... Args>
377 HdDataSourceBaseHandle
378 HdCopySampledDataSourceType(
379  const HdSampledDataSourceHandle& dataSource, Args&&... args)
380 {
381  return HdVisitSampledDataSourceType<
382  Hd_CopySampledDataSourceTypeVisitor, DataSource, UntypedDataSource>(
383  dataSource, std::forward<Args>(args)...);
384 }
385 
387 HD_API
388 bool
389 HdGetMergedContributingSampleTimesForInterval(
390  size_t count,
391  const HdSampledDataSourceHandle *inputDataSources,
392  HdSampledDataSource::Time startTime,
393  HdSampledDataSource::Time endTime,
394  std::vector<HdSampledDataSource::Time> * outSampleTimes);
395 
397 HD_API
398 void
399 HdDebugPrintDataSource(
400  std::ostream &,
401  HdDataSourceBaseHandle,
402  int indentLevel = 0);
403 
405 HD_API
406 void
407 HdDebugPrintDataSource(HdDataSourceBaseHandle, int indentLevel = 0);
408 
409 PXR_NAMESPACE_CLOSE_SCOPE
410 
411 #endif // PXR_IMAGING_HD_DATASOURCE_H
A datasource representing indexed data.
Definition: dataSource.h:179
virtual HdDataSourceBaseHandle Get(const TfToken &name)=0
Returns the child datasource of the given name.
virtual bool GetContributingSampleTimesForInterval(Time startTime, Time endTime, std::vector< Time > *outSampleTimes)=0
Given a shutter window of interest (startTime and endTime relative to the current frame),...
HdDataSourceAllocator.
Definition: dataSource.h:32
A datasource representing structured (named, hierarchical) data, for example a geometric primitive or...
Definition: dataSource.h:147
virtual VtValue GetValue(Time shutterOffset)=0
Returns the value of this data source at frame-relative time shutterOffset.
Token for efficient comparison, assignment, and hashing of known strings.
Definition: token.h:80
virtual HdDataSourceBaseHandle GetElement(size_t element)=0
Return the element at position element in this datasource.
Represents an object that can identify the location of a data source.
A datasource representing the absence of a datasource.
Definition: dataSource.h:274
A datasource representing a concretely-typed sampled value.
Definition: dataSource.h:247
virtual size_t GetNumElements()=0
Return the number of elements in this datasource.
std::vector< TfToken > TfTokenVector
Convenience types.
Definition: token.h:489
virtual T GetTypedValue(Time shutterOffset)=0
Returns the value of this data source at frame-relative time shutterOffset, as type T.
Represents an object which can produce scene data.
Definition: dataSource.h:129
Provides a container which may hold any type, and provides introspection and iteration over array typ...
Definition: value.h:89
virtual TfTokenVector GetNames()=0
Returns the list of names for which Get(...) is expected to return a non-null value.
A datasource representing time-sampled values.
Definition: dataSource.h:201
TfToken class for efficient string referencing and hashing, plus conversions to and from stl string c...