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