HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
GA_PageHandle.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: GA_PageHandle.h ( GA Library, C++)
7  *
8  * COMMENTS: A heavyweight probe to deal with sequential access of
9  * a specific attribute of specific type, where one can
10  * either get a marshalled or raw pointer to underlying data.
11  */
12 
13 #ifndef __GA_PAGEHANDLE_H_INCLUDED__
14 #define __GA_PAGEHANDLE_H_INCLUDED__
15 
16 #include "GA_API.h"
17 #include "GA_AIFTuple.h"
18 #include "GA_ATINumeric.h"
19 #include "GA_Attribute.h"
20 #include "GA_Types.h"
21 
22 #include <UT/UT_Assert.h>
23 #include <UT/UT_Matrix3.h>
24 #include <UT/UT_Matrix4.h>
25 #include <UT/UT_Quaternion.h>
26 #include <UT/UT_Vector2.h>
27 #include <UT/UT_Vector3.h>
28 #include <UT/UT_Vector4.h>
29 
30 #include <SYS/SYS_Types.h>
31 
32 
33 class GA_Detail;
34 
35 
36 template <typename T, typename TB, bool READ, bool WRITE, typename EXTERNAL_ATTRIB, typename INTERNAL_ATTRIB, typename DETAIL>
38 {
39 public:
40  typedef T value_type;
41 
43  {
44  clear();
45  }
47  EXTERNAL_ATTRIB *attrib,
48  int component = 0)
49  {
50  clear();
51  bind(attrib, component);
52  }
54  DETAIL *gdp,
55  GA_AttributeOwner owner,
56  const char *name,
57  int component=0);
58 
60  {
61  if (WRITE)
62  flushIfNeeded();
63  }
64 
65  void bind(EXTERNAL_ATTRIB *attrib, int component = 0);
66  /// Bind unsafe does no checking of the attribute, assuming it
67  /// is already a GA_ATINumeric.
68  void bindUnsafe(EXTERNAL_ATTRIB *attrib, int component = 0);
69  void bind(DETAIL *gdp, GA_AttributeOwner owner, const char *name, int component = 0);
70 
71  /// Somewhat expensive as it must flush and rebind!
72  /// It is preferred to have several page handles, one for each
73  /// component.
74  void setComponent(int comp) { bind(myAttrib, comp); }
75 
76  EXTERNAL_ATTRIB * getAttribute() const { return myAttrib; }
77  const EXTERNAL_ATTRIB *operator->() const
78  {
79  return myAttrib;
80  }
81 
82  void bumpDataId() const
83  {
84  if (myAttrib)
85  myAttrib->bumpDataId();
86  }
87 
88  void clear()
89  {
90  myAttrib = 0;
91  myDataPtr = 0;
93 #if !USE_PAGEARRAY_NUMERIC
94  myPageFetcher = 0;
95  myPageWriter = 0;
96 #endif
97  myIsConstant = false;
98  }
99 
100  /// Sets the default value
101  /// If the attribute is unbound, this is the value that
102  /// will be read.
104  {
105  for (GA_PageOff i(0); i < GA_PAGE_SIZE; i++)
106  myMarshalledData[i] = value;
108  myIsConstant = true;
109  // We now are a valid offset (but
110  // we will still want to update for
111  // setpage)
112  myBaseOffset = GA_Offset(0);
113  }
114 
115  /// This returns if the page was constant when it was fetched.
116  /// It may no longer be constant if someone wrote to it.
118  { return myIsConstant; }
119 
120  void makeConstant(T cval)
121  {
122  myAttrib->getAIFTuple()->makeConstant(myAttrib, (TB *)&cval, sizeof(T)/sizeof(TB), myComponent);
123  }
124 
125  SYS_FORCE_INLINE bool isValid() const { return myAttrib; }
126  SYS_FORCE_INLINE bool isInvalid() const { return !myAttrib; }
127 
128  void setPage(GA_Offset pagebase);
129 
130  inline T get(GA_Offset off) const
131  {
132  return getRelative(GA_PageOff(off-myBaseOffset));
133  }
134  inline T getRelative(GA_PageOff rel) const
135  {
136  UT_ASSERT_P(rel >= 0 && rel < GA_PAGE_SIZE);
137  return myDataPtr[rel];
138  }
139 
140  inline void set(GA_Offset off, T value)
141  {
142  setRelative(GA_PageOff(off-myBaseOffset), value);
143  }
144  inline void setRelative(GA_PageOff rel, T value)
145  {
146  UT_ASSERT_P(rel >= 0 && rel < GA_PAGE_SIZE);
147  myDataPtr[rel] = value;
148  }
149 
150  // Returns a reference so you can do things like:
151  // page.value(offset) += 5
152  inline T & value(GA_Offset off)
153  {
155  }
156  inline T & valueRelative(GA_PageOff rel)
157  {
158  UT_ASSERT_P(rel >= 0 && rel < GA_PAGE_SIZE);
159  return myDataPtr[rel];
160  }
161 
162  // Writes backout the page table if it was copied in.
163  // Normally end users do not have to do this as it will be
164  // done automatically when switching pages or destructing.
165  void flushIfNeeded();
166 
167 protected:
168 
169 #if !USE_PAGEARRAY_NUMERIC
170  /// A utility template class used to declare and set the page Getter
171  /// function, as the signature depends on whether or not the page is
172  /// writeable.
173  template <typename A_T, typename A_TB, bool A_WRITE>
174  struct GetterAdapter
175  {
176  };
177  template <typename A_T, typename A_TB>
178  struct GetterAdapter<A_T, A_TB, true>
179  {
180  typedef A_T *(*GAprobeAttribPageGet)(
181  GA_Attribute *atr,
182  A_T *marshall,
183  GA_Offset,
184  int comp,
185  bool &isconstant);
186 
187  static inline GAprobeAttribPageGet
188  bindNumericGetter(GA_ATINumeric *atr)
189  {
190  return GA_ATINumeric::binderPage<A_T, A_TB>::bindGetter(atr);
191  }
192  };
193  template <typename A_T, typename A_TB>
194  struct GetterAdapter<A_T, A_TB, false>
195  {
196  typedef A_T *(*GAprobeAttribPageGet)(
197  const GA_Attribute *atr,
198  A_T *marshall,
199  GA_Offset,
200  int comp,
201  bool &isconstant);
202 
203  static inline GAprobeAttribPageGet
204  bindNumericGetter(const GA_ATINumeric *atr)
205  {
206  return GA_ATINumeric::binderPage<A_T, A_TB>::bindGetterRO(atr);
207  }
208  };
209 
210  typedef typename GetterAdapter<T,TB,WRITE>::GAprobeAttribPageGet
211  GAprobeAttribPageGet;
212  typedef void (*GAprobeAttribPageSet)(
213  GA_Attribute *atr,
214  const T *marshall,
215  GA_Offset,
216  int comp);
217 #endif
218 
219 protected:
222  INTERNAL_ATTRIB * myAttrib;
226 
227 #if !USE_PAGEARRAY_NUMERIC
228  GAprobeAttribPageGet myPageFetcher;
229  GAprobeAttribPageSet myPageWriter;
230 #endif
231 };
232 
233 template <typename T>
235 {
236 public:
237  typedef T value_type;
238 
241 };
242 
243 template <typename T>
245 {
246 public:
247  typedef T value_type;
248 
251 };
252 
257 
260 
263 
266 
269 
274 
279 
284 
289 
294 
299 
304 
305 
306 ///////////////////////////////////////////////////////////////////////////////
307 //
308 // GA_PageHandleT implementation
309 //
310 
311 template <typename T, typename TB, bool READ, bool WRITE, typename EXTERNAL_ATTRIB, typename INTERNAL_ATTRIB, typename DETAIL>
312 inline void
314  EXTERNAL_ATTRIB *attrib,
315  int component)
316 {
317  if (WRITE)
318  flushIfNeeded();
319  clear();
320  myAttrib = INTERNAL_ATTRIB::cast(attrib);
321  if (!myAttrib)
322  return;
323 
324  if (myAttrib->getTupleSize() < ((1+component) * sizeof(T)/sizeof(TB)))
325  {
326  myAttrib = 0;
327  return;
328  }
329  myComponent = component;
330 #if !USE_PAGEARRAY_NUMERIC
331  if (READ)
332  {
333  myPageFetcher = GetterAdapter<T,TB,WRITE>::bindNumericGetter(myAttrib);
334  }
335  // NOTE: The SYSconst_cast is only needed in order to compile when WRITE is false,
336  // in which case, it won't be called anyway.
337  if (WRITE)
338  myPageWriter = GA_ATINumeric::binderPage<T, TB>::bindSetter(SYSconst_cast(myAttrib));
339 #endif
340 }
341 
342 template <typename T, typename TB, bool READ, bool WRITE, typename EXTERNAL_ATTRIB, typename INTERNAL_ATTRIB, typename DETAIL>
343 inline void
345  EXTERNAL_ATTRIB *attrib,
346  int component)
347 {
348  if (WRITE)
349  flushIfNeeded();
350  clear();
351 
352  myAttrib = (INTERNAL_ATTRIB *)(attrib);
353  myComponent = component;
354 #if !USE_PAGEARRAY_NUMERIC
355  if (READ)
356  {
357  myPageFetcher = GetterAdapter<T,TB,WRITE>::bindNumericGetter(myAttrib);
358  }
359  // NOTE: The SYSconst_cast is only needed in order to compile when WRITE is false,
360  // in which case, it won't be called anyway.
361  if (WRITE)
362  myPageWriter = GA_ATINumeric::binderPage<T, TB>::bindSetter(SYSconst_cast(myAttrib));
363 #endif
364 }
365 
366 template <typename T, typename TB, bool READ, bool WRITE, typename EXTERNAL_ATTRIB, typename INTERNAL_ATTRIB, typename DETAIL>
367 inline void
369 {
370  // Check if this is the same page as before.
371  if (myDataPtr
372  && pagebase >= myBaseOffset
373  && (pagebase < myBaseOffset + GA_PAGE_SIZE))
374  {
375  return;
376  }
377 
378  if (!isValid())
379  {
380  // We still want to set our page offset with invalid pages
381  // so default values will work
382  pagebase -= GAgetPageOff(pagebase);
383  myBaseOffset = pagebase;
384  return;
385  }
386 
387  if (WRITE)
388  flushIfNeeded();
389 
390  // Set our new base.
391  pagebase -= GAgetPageOff(pagebase);
392  myBaseOffset = pagebase;
393 
394  // Read in our data.
395 #if USE_PAGEARRAY_NUMERIC
396  GA_PageNum pagenum = GAgetPageNum(pagebase);
397  auto &src = myAttrib->getData();
398  if (myComponent == 0 && UT_StorageNum<TB>::theStorage == src.GA_ATINumeric::DataType::Base::getStorage()
399  && (sizeof(T) / sizeof(TB)) == src.getTupleSize())
400  {
401  if (WRITE)
402  {
403  GA_PageArray<TB,(sizeof(T) / sizeof(TB))> &matchsrc = SYSconst_cast(src).template castTupleSize<sizeof(T)/sizeof(TB)>().template castType<TB>();
404 
405  matchsrc.hardenPage(pagenum);
406  myDataPtr = reinterpret_cast<T*>(SYSconst_cast(matchsrc.getPageData(pagenum)));
407  myIsConstant = false;
408  }
409  else
410  {
411  const GA_PageArray<TB,(sizeof(T) / sizeof(TB))> &matchsrc = src.template castTupleSize<sizeof(T)/sizeof(TB)>().template castType<TB>();
412 
413  if (matchsrc.isPageConstant(pagenum))
414  {
415  T v;
416  const T *data = reinterpret_cast<const T*>(matchsrc.getPageData(pagenum));
417 
418  // Can skip if already marshalled same value last time
419  bool equal = myIsConstant;
420  if (equal)
421  {
422  if (!data)
423  {
424  memset(&v,0,sizeof(T));
425  data = &v;
426  }
427  equal = (myMarshalledData[0] == *data);
428  }
429  UT_ASSERT_P(!equal || myDataPtr == myMarshalledData);
430  if (!equal)
431  {
432  GA_Size count = ((pagebase + GA_PAGE_SIZE) <= matchsrc.size()) ? GA_PAGE_SIZE : (matchsrc.size() & GA_PAGE_MASK);
433  if (!data)
434  {
435  memset(myMarshalledData, 0, count*sizeof(myMarshalledData[0]));
436  }
437  else
438  {
439  for (GA_Size off = 0; off < count; ++off)
440  myMarshalledData[off] = *data;
441  }
442  myDataPtr = myMarshalledData;
443  myIsConstant = true;
444  }
445  }
446  else
447  {
448  myDataPtr = reinterpret_cast<T*>(SYSconst_cast(matchsrc.getPageData(pagenum)));
449  myIsConstant = false;
450  }
451  }
452  }
453  else
454  {
455  GA_Size count = ((pagebase + GA_PAGE_SIZE) <= src.size()) ? GA_PAGE_SIZE : (src.size() & GA_PAGE_MASK);
456  if (myComponent <= 0)
457  {
458  for (GA_Size off = 0; off < count; ++off)
459  {
460  typename UT_FixedVectorTraits<T>::FixedVectorType v = src.template getVector<TB, sizeof(T) / sizeof(TB)>(pagebase + off);
461  myMarshalledData[off] = *reinterpret_cast<const T*>(&v);
462  }
463  }
464  else
465  {
466  UT_ASSERT_MSG_P((SYSisSame<T,TB>()), "Don't currently support vector types when myComponent > 0.");
467  for (GA_Size off = 0; off < count; ++off)
468  {
469  TB v = src.template get<TB>(pagebase + off, myComponent);
470  myMarshalledData[off] = *reinterpret_cast<const T*>(&v);
471  }
472  }
473  myDataPtr = myMarshalledData;
474  myIsConstant = src.isPageConstant(pagenum);
475  }
476 #else
477  if (myPageFetcher)
478  myDataPtr = (*myPageFetcher)(myAttrib, myMarshalledData, pagebase,
479  myComponent, myIsConstant);
480  else
481  myDataPtr = myMarshalledData;
482 #endif
483 }
484 
485 #endif // __GA_PAGEHANDLE_H_INCLUDED__
T & value(GA_Offset off)
Definition of a geometry attribute.
Definition: GA_Attribute.h:189
const EXTERNAL_ATTRIB * operator->() const
Definition: GA_PageHandle.h:77
GA_PageHandleV< UT_Vector4D >::ROType GA_ROPageHandleV4D
GA_PageHandleV< UT_Vector2F >::ROType GA_ROPageHandleV2
void setPage(GA_Offset pagebase)
GA_PageHandleT< T, T, true, false, const GA_Attribute, const GA_ATINumeric, const GA_Detail > ROType
GA_PageHandleV< UT_QuaternionF >::RWType GA_RWPageHandleQ
GA_PageHandleV< UT_Matrix4F >::ROType GA_ROPageHandleM4
GA_PageHandleV< UT_Vector3F >::ROType GA_ROPageHandleV3
GA_Size GA_PageOff
Definition: GA_Types.h:621
GA_PageHandleScalar< fpreal64 >::ROType GA_ROPageHandleD
GA_PageHandleV< UT_Matrix2D >::ROType GA_ROPageHandleM2D
void setRelative(GA_PageOff rel, T value)
GA_PageHandleV< UT_Matrix3D >::RWType GA_RWPageHandleM3D
GA_PageHandleV< UT_Vector3D >::RWType GA_RWPageHandleV3D
const GLdouble * v
Definition: glcorearb.h:836
GA_Offset myBaseOffset
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
GA_PageHandleScalar< fpreal16 >::ROType GA_ROPageHandleH
GA_PageHandleV< UT_Vector4F >::ROType GA_ROPageHandleV4
SYS_FORCE_INLINE T * SYSconst_cast(const T *foo)
Definition: SYS_Types.h:126
void flushIfNeeded()
GA_PageHandleV< UT_Vector2D >::RWType GA_RWPageHandleV2D
GA_PageHandleV< UT_Vector3D >::ROType GA_ROPageHandleV3D
GA_PageHandleScalar< fpreal >::ROType GA_ROPageHandleR
GA_PageHandleScalar< int32 >::ROType GA_ROPageHandleI
T & valueRelative(GA_PageOff rel)
png_uint_32 i
Definition: png.h:2877
exint GA_Size
Defines the bit width for index and offset types in GA.
Definition: GA_Types.h:211
GA_PageOff GAgetPageOff(GA_Offset v)
Definition: GA_Types.h:636
GA_PageHandleV< UT_QuaternionF >::ROType GA_ROPageHandleQ
#define GA_INVALID_OFFSET
Definition: GA_Types.h:654
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:101
GA_PageHandleV< UT_Vector3F >::RWType GA_RWPageHandleV3
GA_PageHandleV< UT_Vector4D >::RWType GA_RWPageHandleV4D
GA_PageHandleV< UT_Matrix2F >::ROType GA_ROPageHandleM2
GA_Size GA_Offset
Definition: GA_Types.h:617
T getRelative(GA_PageOff rel) const
GA_PageHandleV< UT_Matrix2D >::RWType GA_RWPageHandleM2D
GA_PageHandleV< UT_Vector4F >::RWType GA_RWPageHandleV4
GA_PageHandleT(EXTERNAL_ATTRIB *attrib, int component=0)
Definition: GA_PageHandle.h:46
GA_PageHandleT< T, T, true, true, GA_Attribute, GA_ATINumeric, GA_Detail > RWType
SYS_FORCE_INLINE bool isValid() const
SYS_FORCE_INLINE bool isInvalid() const
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
GA_PageHandleV< UT_Matrix3D >::ROType GA_ROPageHandleM3D
void makeConstant(T cval)
#define GA_PAGE_MASK
Definition: GA_Types.h:201
void setDefaultValue(T value)
GLboolean * data
Definition: glcorearb.h:130
SYS_FORCE_INLINE bool isCurrentPageConstant() const
GA_PageHandleV< UT_QuaternionD >::ROType GA_ROPageHandleQD
GLuint const GLchar * name
Definition: glcorearb.h:785
#define GA_PAGE_SIZE
Definition: GA_Types.h:200
GA_PageHandleScalar< fpreal16 >::RWType GA_RWPageHandleH
GLint GLsizei count
Definition: glcorearb.h:404
GA_PageHandleV< UT_Matrix3F >::ROType GA_ROPageHandleM3
GA_PageHandleV< UT_QuaternionD >::RWType GA_RWPageHandleQD
GA_PageHandleScalar< fpreal64 >::RWType GA_RWPageHandleD
GLsizei const GLfloat * value
Definition: glcorearb.h:823
GA_AttributeOwner
Definition: GA_Types.h:33
void bindUnsafe(EXTERNAL_ATTRIB *attrib, int component=0)
GA_PageHandleScalar< int64 >::ROType GA_ROPageHandleID
void bind(EXTERNAL_ATTRIB *attrib, int component=0)
#define UT_ASSERT_MSG_P(ZZ, MM)
Definition: UT_Assert.h:104
GA_PageHandleScalar< fpreal >::RWType GA_RWPageHandleR
GA_PageHandleV< UT_Matrix3F >::RWType GA_RWPageHandleM3
GA_Size GA_PageNum
Definition: GA_Types.h:620
GA_PageHandleV< UT_Matrix4D >::ROType GA_ROPageHandleM4D
GA_PageHandleT< T, typename T::value_type, true, true, GA_Attribute, GA_ATINumeric, GA_Detail > RWType
GA_PageHandleT< T, typename T::value_type, true, false, const GA_Attribute, const GA_ATINumeric, const GA_Detail > ROType
GA_PageHandleV< UT_Vector2F >::RWType GA_RWPageHandleV2
bool equal(T1 a, T2 b, T3 t)
Definition: ImathFun.h:143
EXTERNAL_ATTRIB * getAttribute() const
Definition: GA_PageHandle.h:76
GA_PageHandleV< UT_Matrix2F >::RWType GA_RWPageHandleM2
GA_PageHandleScalar< fpreal32 >::ROType GA_ROPageHandleF
Container class for all geometry.
Definition: GA_Detail.h:96
GA_PageHandleScalar< int64 >::RWType GA_RWPageHandleID
GA_PageHandleScalar< int32 >::RWType GA_RWPageHandleI
GA_PageHandleV< UT_Vector2D >::ROType GA_ROPageHandleV2D
GA_PageHandleScalar< fpreal32 >::RWType GA_RWPageHandleF
T myMarshalledData[GA_PAGE_SIZE]
void bumpDataId() const
Definition: GA_PageHandle.h:82
void set(GA_Offset off, T value)
GA_PageNum GAgetPageNum(GA_Offset v)
Definition: GA_Types.h:632
GA_PageHandleV< UT_Matrix4D >::RWType GA_RWPageHandleM4D
void setComponent(int comp)
Definition: GA_PageHandle.h:74
INTERNAL_ATTRIB * myAttrib
GLenum src
Definition: glcorearb.h:1792
GA_PageHandleV< UT_Matrix4F >::RWType GA_RWPageHandleM4