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 private:
180  // Don't allow copies
181  HdBufferSource(const HdBufferSource &) = delete;
182  HdBufferSource &operator=(const HdBufferSource &) = delete;
183 
184  enum State { UNRESOLVED=0, BEING_RESOLVED, RESOLVED, RESOLVE_ERROR};
185  std::atomic<State> _state;
186 };
187 
188 /// A abstract base class for cpu computation followed by buffer
189 /// transfer to the GPU.
190 ///
191 /// concrete class needs to implement
192 /// virtual void GetBufferSpecs(HdBufferSpecVector *specs) const;
193 /// virtual void Resolve();
194 /// and set the result via _SetResult().
195 ///
197 public:
198  HD_API
199  virtual TfToken const &GetName() const override;
200  HD_API
201  virtual size_t ComputeHash() const override;
202  HD_API
203  virtual void const* GetData() const override;
204  HD_API
205  virtual HdTupleType GetTupleType() const override;
206  HD_API
207  virtual size_t GetNumElements() const override;
208 
209 protected:
211  _result = result;
212  }
213 
214 private:
215  HdBufferSourceSharedPtr _result;
216 };
217 
218 /// A abstract base class for pure cpu computation.
219 /// the result won't be scheduled for GPU transfer.
220 ///
222 public:
223  HD_API
224  virtual TfToken const &GetName() const override;
225  HD_API
226  virtual void const* GetData() const override;
227  HD_API
228  virtual size_t ComputeHash() const override;
229  HD_API
230  virtual size_t GetNumElements() const override;
231  HD_API
232  virtual HdTupleType GetTupleType() const override;
233  HD_API
234  virtual void GetBufferSpecs(HdBufferSpecVector *specs) const override;
235 };
236 
237 
239 
240 #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.
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
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
std::vector< struct HdBufferSpec > HdBufferSpecVector
virtual bool _CheckValid() const =0
virtual void GetBufferSpecs(HdBufferSpecVector *specs) const =0
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1425
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:210
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
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.