HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GT_VtArray.h
Go to the documentation of this file.
1 //
2 // Copyright 2017 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 _GUSD_GT_VTARRAY_H_
25 #define _GUSD_GT_VTARRAY_H_
26 
27 #include <GT/GT_DataArray.h>
28 #include <GT/GT_DANumeric.h>
29 #include <UT/UT_XXHash.h>
30 #include <SYS/SYS_Compiler.h>
31 #include <SYS/SYS_Math.h>
32 
33 #include "pxr/pxr.h"
34 #include "pxr/base/vt/array.h"
35 
36 #include "gusd/UT_TypeTraits.h"
37 #include "gusd/GT_Utils.h"
38 
40 
41 /// GT_DataArray implementation that wraps a VtArray.
42 ///
43 /// This allows, in some cases, for arrays read in from USD to be
44 /// pushed into GT prims without having to incur copying.
45 /// Example:
46 /// \code
47 /// VtArray<int> valsFromUSD;
48 /// GT_DataArrayHandle hnd(new GusdGT_VtArray<int>(valsFromUSD));
49 /// \endcode
50 ///
51 /// These arrays are designed to be read-only.
52 /// If you need to make edits, use the following pattern:
53 ///
54 /// \code
55 /// GusdGT_VtArray<int> srcData;
56 /// // swap data into tmp array, modify.
57 /// VtArray<int> tmp;
58 /// srcData.swap(tmp);
59 /// tmp[10] = 37;
60 /// // swap data back into place.
61 /// srcData.swap(tmp);
62 /// \endcode
63 ///
64 /// Note that this kind of swapping trick does *not* require the
65 /// full array to be copied; only the internal references are swapped.
66 template <class T>
68 {
69 public:
70  SYS_STATIC_ASSERT(GusdIsPodTuple<T>());
71 
73  using ValueType = T;
76 
77  static const int tupleSize = GusdGetTupleSize<T>();
78  static const GT_Storage storage =
80 
83 
84  ~GusdGT_VtArray() override = default;
85 
86  const char* className() const override { return "GusdGT_VtArray"; }
87 
88  const T& operator()(GT_Offset o) const
89  {
90  UT_ASSERT_P(o >= 0 && o <= _size);
91  return reinterpret_cast<T*>(_data)[o];
92  }
93 
94  PODType operator()(GT_Offset o, int idx) const
95  { return getT<PODType>(o, idx); }
96 
97  const ArrayType& operator*() const { return _array; }
98 
99  const PODType* data() const { return _data; }
100  const void * getBackingData() const override { return _data; }
101 
102  /// Swap our array contents with another array.
103  void swap(ArrayType& o);
104 
105  SYS_HashType hashRange(exint b, exint e) const override
106  {
107  return UT_XXH64(_data+b*tupleSize,
108  sizeof(PODType)*tupleSize*(e-b), 0);
109  }
110  bool isEqual(const GT_DataArray &src) const override
111  {
112  if (&src == this)
113  return true;
114  if (src.entries() != _size)
115  return false;
116  if (src.getTupleSize() != tupleSize)
117  return false;
118  if (src.getStorage() != storage)
119  return false;
120  const auto *other = dynamic_cast<const This *>(&src);
121  if (!other)
122  return GT_DataArray::isEqual(src);
123  if (_data == other->_data)
124  return true;
125  // If we use std::equal and the arrays have matching Nan's, the
126  // std::equal comparison will fail while memcmp will succeed.
127  return !::memcmp(_data, other->_data, sizeof(PODType)*tupleSize*_size);
128  }
129 
130  GT_DataArrayHandle harden() const override;
131 
132  const PODType* getData(GT_Offset o) const
133  {
134  UT_ASSERT_P(o >= 0 && o <= _size);
135  return _data + o*tupleSize;
136  }
137 
138  /// Access to individual elements as given POD type.
139  /// For performance, this is preferred to the virtual getXX() methods.
140  template <typename PODT>
141  PODT getT(GT_Offset o, int idx=0) const;
142 
143  /// Get access to a raw array of data.
144  /// If @a OTHERPODT is not the same as the array's underlying type,
145  /// the raw array will be stored in the given @a buf.
146  template <typename PODT>
147  const PODT* getArrayT(GT_DataArrayHandle& buf) const;
148 
149  /// Extract a tuple into @a dst
150  template <typename PODT>
151  void importT(GT_Offset o, PODT* dst, int tsize=-1) const;
152 
153  /// Extract data for entire array into @a dst.
154  template <typename PODT>
156  int tsize=-1, int stride=-1) const;
157 
158  /// Extended form of array extraction that supports repeated elems.
159  template <typename PODT>
160  void extendedFillT(PODT* dst, GT_Offset start,
161  GT_Size length, int tsize=-1,
162  int nrepeats=1, int stride=-1) const;
163 
164  GT_Storage getStorage() const override { return storage; }
165  GT_Size getTupleSize() const override { return tupleSize; }
166  GT_Size entries() const override { return _size; }
167  GT_Type getTypeInfo() const override { return _type; }
168  int64 getMemoryUsage() const override
169  { return sizeof(*this) + sizeof(T)*_size; }
170 
171  // Type-specific virtual getters.
172 
173 #define _DECL_GETTERS(suffix,podt) \
174 public: \
175  virtual podt SYS_CONCAT(get,suffix)(GT_Offset o, \
176  int idx=0) const override \
177  { return getT<podt>(o, idx); } \
178  \
179  virtual const podt* SYS_CONCAT(get,SYS_CONCAT(suffix,Array)) \
180  (GT_DataArrayHandle& buf) const override \
181  { return getArrayT<podt>(buf); } \
182  \
183 protected: \
184  virtual void doImport(GT_Offset o, podt* dst, \
185  GT_Size tsize) const override \
186  { importT(o, dst, tsize); } \
187  \
188  virtual void doFillArray(podt* dst, GT_Offset start, \
189  GT_Size length, int tsize, \
190  int stride) const override \
191  { fillArrayT(dst, start, length, \
192  tsize, stride); } \
193  \
194  virtual void extendedFill(podt* dst, GT_Offset start, \
195  GT_Size length, int tsize, \
196  int nrepeats, \
197  int stride=-1) const override \
198  { extendedFillT(dst, start, length, \
199  tsize, nrepeats, stride); } \
200  /* end of macro */
201 
202  _DECL_GETTERS(I8, int8);
203  _DECL_GETTERS(I16, int16);
204  _DECL_GETTERS(U8, uint8);
205  _DECL_GETTERS(I32, int32);
206  _DECL_GETTERS(I64, int64);
207  _DECL_GETTERS(F16, fpreal16);
208  _DECL_GETTERS(F32, fpreal32);
209  _DECL_GETTERS(F64, fpreal64);
210 
211 #undef _DECL_GETTER
212 
213 protected:
214  /// Update our @a _data member to point at the array data.
215  /// This must be called after any operation that changes
216  /// the contents of @a _array.
217  void _UpdateDataPointer(bool makeUnique);
218 
219 private:
220  // No string support. For strings, use GusdGT_VtStringArray.
221  GT_String getS(GT_Offset, int) const override { return nullptr; }
222  GT_Size getStringIndexCount() const override { return -1; }
223  GT_Offset getStringIndex(GT_Offset,int) const override { return -1; }
224  void getIndexedStrings(UT_StringArray&,
225  UT_IntArray&) const override {}
226 
227 protected:
229  const GT_Type _type;
231  const PODType* _data; /// Raw pointer to the underlying data.
232  /// Held separately as an optimization.
233 };
234 
235 
236 template <class T>
238  : _array(array), _type(type), _size(array.size())
239 {
240  _UpdateDataPointer(false);
241 }
242 
243 
244 template <class T>
246  : _type(type), _size(0), _data(nullptr)
247 {}
248 
249 
250 template <class T>
251 void
253 {
254  // Access a non-const pointer to make the array unique.
255  _data = reinterpret_cast<const PODType*>(
256  makeUnique ? _array.data() : _array.cdata());
257  UT_ASSERT(_size == 0 || _data != nullptr);
258 }
259 
260 
261 template <class T>
262 void
264 {
265  _array.swap(o);
266  _size = _array.GetSize();
267  _UpdateDataPointer(false);
268 }
269 
270 
271 template <class T>
274 {
275  This* copy = new This(_array, _type);
276  copy->_UpdateDataPointer(true);
277  return GT_DataArrayHandle(copy);
278 }
279 
280 
281 template <class T>
282 template <typename PODT>
283 PODT
285 {
286  UT_ASSERT_P(o >= 0 && o < _size);
287  UT_ASSERT_P(idx >= 0 && idx < tupleSize);
288  return static_cast<PODT>(_data[tupleSize*o + idx]);
289 }
290 
291 
292 template <class T>
293 template <typename PODT>
294 const PODT*
296 {
298  return reinterpret_cast<const PODT*>(_data);
299 
300  using _GTArrayType = GT_DANumeric<PODT>;
301 
302  _GTArrayType* tmpArray = new _GTArrayType(_size, tupleSize, _type);
303  fillArrayT(tmpArray->data(), 0, _size, tupleSize);
304  buf = tmpArray;
305  return tmpArray->data();
306 }
307 
308 
309 template <class T>
310 template <typename PODT>
311 void
312 GusdGT_VtArray<T>::importT(GT_Offset o, PODT* dst, int tsize) const
313 {
314  tsize = tsize < 1 ? tupleSize : SYSmin(tsize, tupleSize);
315  const PODType* src = getData(o);
316  if( src )
317  {
318  for(int i = 0; i < tsize; ++i)
319  dst[i] = static_cast<PODT>(src[i]);
320  }
321 }
322 
323 
324 template <class T>
325 template <typename PODT>
326 void
328  int tsize, int stride) const
329 {
330  if(_size == 0)
331  return;
332  if(tsize < 1)
333  tsize = tupleSize;
334  // Stride is >= the unclamped tuple size.
335  // This seems wrong, but is consistent with GT_DANumeric.
336  stride = SYSmax(stride, tsize);
337  tsize = SYSmin(tsize, tupleSize);
339  tsize == tupleSize && stride == tupleSize) {
340  // direct copy is safe
341  memcpy(dst, getData(start), length*tsize*sizeof(PODT));
342  } else {
343  const PODType* src = getData(start*tupleSize);
344  for(GT_Offset i = 0; i < length; ++i, src += tupleSize, dst += stride) {
345  for(int j = 0; j < tsize; ++j)
346  dst[j] = static_cast<PODT>(src[j]);
347  }
348  }
349 }
350 
351 
352 template <class T>
353 template <typename PODT>
354 void
356  GT_Size length, int tsize,
357  int nrepeats, int stride) const
358 {
359  if(nrepeats == 1)
360  return fillArrayT(dst, start, length, tsize, stride);
361  if(_size == 0)
362  return;
363  if(tsize < 1)
364  tsize = tupleSize;
365  stride = SYSmax(stride, tsize);
366  tsize = SYSmin(tsize, tupleSize);
367 
368  const PODType* src = getData(start*tupleSize);
369  for(GT_Offset i = 0; i < length; ++i, src += tupleSize) {
370  for(int r = 0; r < nrepeats; ++r, dst += stride) {
371  for(int j = 0; j < tsize; ++j)
372  dst[j] = static_cast<PODT>(src[j]);
373  }
374  }
375 }
376 
378 
379 #endif /*_GUSD_GT_VTARRAY_H_*/
#define SYSmax(a, b)
Definition: SYS_Math.h:1513
GT_Storage
Definition: GT_Types.h:18
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1222
const void * getBackingData() const override
Definition: GT_VtArray.h:100
int int32
Definition: SYS_Types.h:39
const T & operator()(GT_Offset o) const
Definition: GT_VtArray.h:88
OIIO_UTIL_API bool copy(string_view from, string_view to, std::string &err)
GLuint start
Definition: glcorearb.h:475
typename GusdPodTupleTraits< T >::ValueType PODType
Definition: GT_VtArray.h:75
GT_Type getTypeInfo() const override
Return "type" information for the data. This defaults to GT_TYPE_NONE.
Definition: GT_VtArray.h:167
_DECL_GETTERS(I8, int8)
int64 exint
Definition: SYS_Types.h:125
GT_Type
Definition: GT_Types.h:34
std::size_t SYS_HashType
Define the type for hash values.
Definition: SYS_Hash.h:19
GLenum src
Definition: glcorearb.h:1793
float fpreal32
Definition: SYS_Types.h:200
GT_DataArrayHandle harden() const override
Create a "hardened" version of the array.
Definition: GT_VtArray.h:273
GLsizeiptr size
Definition: glcorearb.h:664
const PODType * getData(GT_Offset o) const
Definition: GT_VtArray.h:132
double fpreal64
Definition: SYS_Types.h:201
unsigned char uint8
Definition: SYS_Types.h:36
GT_Size getTupleSize() const override
Number of elements for each array element.
Definition: GT_VtArray.h:165
static const GT_Storage storage
Definition: GT_VtArray.h:78
GLenum array
Definition: glew.h:9108
ArrayType _array
Definition: GT_VtArray.h:228
const PODT * getArrayT(GT_DataArrayHandle &buf) const
Definition: GT_VtArray.h:295
GT_Size _size
Definition: GT_VtArray.h:230
Abstract data class for an array of float, int or string data.
Definition: GT_DataArray.h:40
PODType operator()(GT_Offset o, int idx) const
Definition: GT_VtArray.h:94
UT_IntrusivePtr< GT_DataArray > GT_DataArrayHandle
Definition: GT_DataArray.h:32
void extendedFillT(PODT *dst, GT_Offset start, GT_Size length, int tsize=-1, int nrepeats=1, int stride=-1) const
Extended form of array extraction that supports repeated elems.
Definition: GT_VtArray.h:355
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:152
void importT(GT_Offset o, PODT *dst, int tsize=-1) const
Extract a tuple into dst.
Definition: GT_VtArray.h:312
int64 GT_Offset
Definition: GT_Types.h:124
long long int64
Definition: SYS_Types.h:116
void swap(ArrayType &o)
Swap our array contents with another array.
Definition: GT_VtArray.h:263
VtArray< T > ArrayType
Definition: GT_VtArray.h:74
static const int tupleSize
Definition: GT_VtArray.h:77
signed char int8
Definition: SYS_Types.h:35
Definition: types.h:166
SYS_STATIC_ASSERT(GusdIsPodTuple< T >())
void _UpdateDataPointer(bool makeUnique)
Definition: GT_VtArray.h:252
const PODType * data() const
Definition: GT_VtArray.h:99
GT_Storage getStorage() const override
Type of data stored in the array.
Definition: GT_VtArray.h:164
const GT_Type _type
Definition: GT_VtArray.h:229
virtual GT_Size entries() const =0
Number of entries in the array.
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glcorearb.h:2540
int64 GT_Size
Definition: GT_Types.h:123
GLuint GLsizei GLsizei * length
Definition: glcorearb.h:795
GusdGT_VtArray(const ArrayType &array, GT_Type type=GT_TYPE_NONE)
Definition: GT_VtArray.h:237
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1394
short int16
Definition: SYS_Types.h:37
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
virtual GT_Storage getStorage() const =0
Type of data stored in the array.
An array of numeric values (int32, int64, fpreal16, fpreal32, fpreal64)
Definition: GT_DANumeric.h:23
getOption("OpenEXR.storage") storage
Definition: HDK_Image.dox:276
int64 getMemoryUsage() const override
Definition: GT_VtArray.h:168
const ArrayType & operator*() const
Definition: GT_VtArray.h:97
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:153
SYS_HashType hashRange(exint b, exint e) const override
Definition: GT_VtArray.h:105
GLint GLenum GLboolean GLsizei stride
Definition: glcorearb.h:872
const char * className() const override
Definition: GT_VtArray.h:86
type
Definition: core.h:1059
GLenum GLenum dst
Definition: glcorearb.h:1793
GLboolean r
Definition: glcorearb.h:1222
virtual GT_Size getTupleSize() const =0
Number of elements for each array element.
#define SYSmin(a, b)
Definition: SYS_Math.h:1514
GT_Size entries() const override
Number of entries in the array.
Definition: GT_VtArray.h:166
virtual bool isEqual(const GT_DataArray &src) const
Compare whether two data arrays are equal.
bool isEqual(const GT_DataArray &src) const override
Compare whether two data arrays are equal.
Definition: GT_VtArray.h:110
void fillArrayT(PODT *dst, GT_Offset start, GT_Size length, int tsize=-1, int stride=-1) const
Extract data for entire array into dst.
Definition: GT_VtArray.h:327
~GusdGT_VtArray() override=default
PODT getT(GT_Offset o, int idx=0) const
Definition: GT_VtArray.h:284
const PODType * _data
Definition: GT_VtArray.h:231