HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
bufferSource.h
Go to the documentation of this file.
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_BUFFER_SOURCE_H
8 #define PXR_IMAGING_HD_BUFFER_SOURCE_H
9 
10 #include "pxr/pxr.h"
11 #include "pxr/imaging/hd/api.h"
12 #include "pxr/imaging/hd/version.h"
14 #include "pxr/base/tf/diagnostic.h"
15 #include "pxr/base/tf/token.h"
16 
17 #include <atomic>
18 #include <memory>
19 #include <vector>
20 
21 
23 
24 class HdBufferSource;
25 using HdBufferSourceSharedPtr = std::shared_ptr<HdBufferSource>;
26 using HdBufferSourceConstSharedPtr = std::shared_ptr<HdBufferSource const>;
27 using HdBufferSourceSharedPtrVector = std::vector<HdBufferSourceSharedPtr>;
28 using HdBufferSourceWeakPtr = std::weak_ptr<HdBufferSource>;
29 
30 /// \class HdBufferSource
31 ///
32 /// A transient buffer of data that has not yet been committed.
33 ///
34 /// HdBufferSource is an abstract interface class, to be registered to the
35 /// resource registry with the buffer array range that specifies the
36 /// destination resource.
37 ///
39 {
40 public:
41  HdBufferSource() : _state(UNRESOLVED) { }
42 
43  HD_API
44  virtual ~HdBufferSource();
45 
46  /// Return the name of this buffer source.
47  virtual TfToken const &GetName() const = 0;
48 
49  /// Add the buffer spec for this buffer source into given bufferspec vector.
50  /// note: buffer specs has to be determined before the source resolution.
51  virtual void GetBufferSpecs(HdBufferSpecVector *specs) const = 0;
52 
53  /// Computes and returns a hash value for the underlying data.
54  HD_API
55  virtual size_t ComputeHash() const;
56 
57  /// Prepare the access of GetData(). This process may include some
58  /// computations (e.g. cpu smooth normals).
59  /// Note: Resolve may be called in parallel from multiple threads
60  /// across buffer sources, so be careful if it uses static/shared
61  /// states among objects.
62  /// Returns true if it resolved. If the buffer source has to wait
63  /// some results of other buffer sources, or the buffer source is
64  /// being resolved by other threads, it returns false.
65  virtual bool Resolve() = 0;
66 
67  /// Following interfaces will be called after Resolve.
68 
69  /// Returns the raw pointer to the underlying data.
70  virtual void const* GetData() const = 0;
71 
72  /// Returns the data type and count (array size) for this buffer source.
73  virtual HdTupleType GetTupleType() const = 0;
74 
75  /// Returns the number of elements (e.g. VtVec3dArray().GetLength()) from
76  /// the source array.
77  virtual size_t GetNumElements() const = 0;
78 
79  /// Returns true it this computation has already been resolved.
80  bool IsResolved() const {
81  return _state >= RESOLVED;
82  }
83 
84  /// Returns true if an error occurred during resolve.
85  bool HasResolveError() const {
86  return _state == RESOLVE_ERROR;
87  }
88 
89  /// \name Chained Buffers
90  /// Buffer sources may be daisy-chained together.
91  ///
92  /// Pre-chained buffer sources typically represent sources that
93  /// are inputs to computed buffer sources (e.g. coarse vertex
94  /// privmar data needing to be quadrangulated or refined) and
95  /// will be scheduled to be resolved along with their owning
96  /// buffer sources.
97  ///
98  /// Post-chained buffer sources typically represent additional
99  /// results produced by a computation (e.g. primitive param data
100  /// computed along with index buffer data) and will be scheduled
101  /// to be committed along with their owning buffer sources.
102  /// @{
103 
104  /// Returns true if this buffer has a pre-chained buffer.
105  HD_API
106  virtual bool HasPreChainedBuffer() const;
107 
108  /// Returns the pre-chained buffer.
109  HD_API
111 
112  /// Returns true if this buffer has any chained buffer(s)
113  HD_API
114  virtual bool HasChainedBuffer() const;
115 
116  /// Returns the vector of chained buffers.
117  HD_API
119 
120  /// @}
121 
122  /// Checks the validity of the source buffer.
123  /// The function should be called to determine if
124  /// AddBufferSpec() and Resolve() would return valid
125  /// results.
126  HD_API
127  bool IsValid() const;
128 
129 protected:
130  /// Marks this buffer source as resolved. It has to be called
131  /// at the end of Resolve on concrete implementations.
132  void _SetResolved() {
133  TF_VERIFY(_state == BEING_RESOLVED);
134  _state = RESOLVED;
135  }
136 
137  /// Called during Resolve() to indicate an unrecoverable failure occurred
138  /// and the results of the computation can not be used.
139  /// Further calls to Resolve() will not lead to success.
140  ///
141  /// This is different from Resolve() returning false, which indicates
142  /// that additional calls to Resolve() will eventually lead to success.
143  ///
144  /// This is also later in the pipeline than IsValid, which checks
145  /// that the buffer is setup such that Resolve() can be successful.
147  TF_VERIFY(_state == BEING_RESOLVED);
148  _state = RESOLVE_ERROR;
149  }
150 
151  /// Non-blocking lock acquisition.
152  /// If no one else is resolving this buffer source, returns true.
153  /// In that case the caller needs to call _SetResolved at the end
154  /// of computation.
155  /// It returns false if anyone else has already acquired lock.
156  bool _TryLock() {
157  State oldState = UNRESOLVED;
158  return _state.compare_exchange_strong(oldState, BEING_RESOLVED);
159  }
160 
161  /// Checks the validity of the source buffer.
162  /// This function is called by IsValid() to do the real checking.
163  ///
164  /// Should only be implemented in classes at leafs of the class hierarchy
165  /// (Please place common validation code in a new non-virtual method)
166  ///
167  /// This code should return false:
168  /// - If the buffer would produce an invalid BufferSpec
169  /// - If a required dependent buffer is invalid
170  /// For example, return false when:
171  /// The data type is invalid, causing an invalid BufferSpec.
172  ///
173  /// The resolve step requires a 'source' buffer and that buffer is invalid.
174  ///
175  /// If returning false, the buffer will not be registered with the resource
176  /// registry. AddBufferSpec and Resolve will not be called
177  virtual bool _CheckValid() const = 0;
178 
179 protected:
181  HdBufferSource(State state) : _state(state) { }
182 
183 private:
184  // Don't allow copies
185  HdBufferSource(const HdBufferSource &) = delete;
186  HdBufferSource &operator=(const HdBufferSource &) = delete;
187 
188  std::atomic<State> _state;
189 };
190 
191 /// An abstract base class for a plain old data buffer source that doesn't
192 /// need to be resolved.
194 public:
196 
197  HD_API
198  bool Resolve() override { return true; }
199 };
200 
201 /// An abstract base class for cpu computation followed by buffer
202 /// transfer to the GPU.
203 ///
204 /// concrete class needs to implement
205 /// virtual void GetBufferSpecs(HdBufferSpecVector *specs) const;
206 /// virtual void Resolve();
207 /// and set the result via _SetResult().
208 ///
210 public:
211  HD_API
212  virtual TfToken const &GetName() const override;
213  HD_API
214  virtual size_t ComputeHash() const override;
215  HD_API
216  virtual void const* GetData() const override;
217  HD_API
218  virtual HdTupleType GetTupleType() const override;
219  HD_API
220  virtual size_t GetNumElements() const override;
221 
222 protected:
224  _result = result;
225  }
226 
227 private:
228  HdBufferSourceSharedPtr _result;
229 };
230 
231 /// An abstract base class for pure cpu computation.
232 /// the result won't be scheduled for GPU transfer.
233 ///
235 public:
236  HD_API
237  virtual TfToken const &GetName() const override;
238  HD_API
239  virtual void const* GetData() const override;
240  HD_API
241  virtual size_t ComputeHash() const override;
242  HD_API
243  virtual size_t GetNumElements() const override;
244  HD_API
245  virtual HdTupleType GetTupleType() const override;
246  HD_API
247  virtual void GetBufferSpecs(HdBufferSpecVector *specs) const override;
248 };
249 
250 
252 
253 #endif //PXR_IMAGING_HD_BUFFER_SOURCE_H
virtual HD_API bool HasChainedBuffer() const
Returns true if this buffer has any chained buffer(s)
virtual void const * GetData() const =0
Following interfaces will be called after Resolve.
virtual bool Resolve()=0
virtual HD_API void const * GetData() const override
Following interfaces will be called after Resolve.
#define PXR_NAMESPACE_OPEN_SCOPE
Definition: pxr.h:73
virtual HD_API size_t ComputeHash() const override
Computes and returns a hash value for the underlying data.
virtual HD_API TfToken const & GetName() const override
Return the name of this buffer source.
#define HD_API
Definition: api.h:23
virtual TfToken const & GetName() const =0
Return the name of this buffer source.
std::vector< HdBufferSourceSharedPtr > HdBufferSourceSharedPtrVector
Definition: bufferSource.h:27
HdBufferSource(State state)
Definition: bufferSource.h:181
virtual HD_API void GetBufferSpecs(HdBufferSpecVector *specs) const override
**But if you need a result
Definition: thread.h:622
virtual HD_API bool HasPreChainedBuffer() const
Returns true if this buffer has a pre-chained buffer.
virtual HD_API size_t GetNumElements() const override
bool HasResolveError() const
Returns true if an error occurred during resolve.
Definition: bufferSource.h:85
Definition: token.h:70
virtual size_t GetNumElements() const =0
HD_API bool Resolve() override
Definition: bufferSource.h:198
std::vector< struct HdBufferSpec > HdBufferSpecVector
virtual bool _CheckValid() const =0
virtual void GetBufferSpecs(HdBufferSpecVector *specs) const =0
virtual HD_API size_t ComputeHash() const override
Computes and returns a hash value for the underlying data.
virtual HD_API size_t ComputeHash() const
Computes and returns a hash value for the underlying data.
virtual HD_API size_t GetNumElements() const override
void _SetResult(HdBufferSourceSharedPtr const &result)
Definition: bufferSource.h:223
virtual HdTupleType GetTupleType() const =0
Returns the data type and count (array size) for this buffer source.
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
void _SetResolveError()
Definition: bufferSource.h:146
virtual HD_API HdTupleType GetTupleType() const override
Returns the data type and count (array size) for this buffer source.
void _SetResolved()
Definition: bufferSource.h:132
virtual HD_API TfToken const & GetName() const override
Return the name of this buffer source.
virtual HD_API void const * GetData() const override
Following interfaces will be called after Resolve.
virtual HD_API HdTupleType GetTupleType() const override
Returns the data type and count (array size) for this buffer source.
std::shared_ptr< HdBufferSource const > HdBufferSourceConstSharedPtr
Definition: bufferSource.h:26
virtual HD_API HdBufferSourceSharedPtr GetPreChainedBuffer() const
Returns the pre-chained buffer.
std::shared_ptr< class HdBufferSource > HdBufferSourceSharedPtr
virtual HD_API ~HdBufferSource()
bool IsResolved() const
Returns true it this computation has already been resolved.
Definition: bufferSource.h:80
state
Definition: core.h:2289
HD_API bool IsValid() const
std::weak_ptr< HdBufferSource > HdBufferSourceWeakPtr
Definition: bufferSource.h:28
virtual HD_API HdBufferSourceSharedPtrVector GetChainedBuffers() const
Returns the vector of chained buffers.