HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups 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  EXTERNAL_ATTRIB * operator->() const
78  {
79  return myAttrib;
80  }
81 
82  void bumpDataId() const
83  {
84  if (myAttrib)
85  myAttrib->bumpDataId();
86  }
87 
89  {
90  if (myAttrib)
91  return myAttrib->getDataId();
92  return GA_INVALID_DATAID;
93  }
94 
95 
96  void clear()
97  {
98  myAttrib = 0;
99  myDataPtr = 0;
101  myIsConstant = false;
102  }
103 
104  /// Sets the default value
105  /// If the attribute is unbound, this is the value that
106  /// will be read.
108  {
109  for (GA_PageOff i(0); i < GA_PAGE_SIZE; i++)
110  myMarshalledData[i] = value;
112  myIsConstant = true;
113  // We now are a valid offset (but
114  // we will still want to update for
115  // setpage)
116  myBaseOffset = GA_Offset(0);
117  }
118 
119  /// This returns if the page was constant when it was fetched.
120  /// It may no longer be constant if someone wrote to it.
122  { return myIsConstant; }
123 
124  void makeConstant(T cval)
125  {
126  myAttrib->getAIFTuple()->makeConstant(myAttrib, (TB *)&cval, sizeof(T)/sizeof(TB), myComponent);
127  }
128 
129  /// Sets all components of all elements of the specified page to
130  /// the given values.
131  /// NOTE: The length of values must be equal to the tuple size.
133  {
134  myAttrib->getData().setPageConstant(pagenum, values.data());
135  myIsConstant = true;
136  }
137 
138  SYS_FORCE_INLINE bool isValid() const { return myAttrib; }
139  SYS_FORCE_INLINE bool isInvalid() const { return !myAttrib; }
140 
141  void setPage(GA_Offset pagebase);
142 
143  inline T get(GA_Offset off) const
144  {
145  return getRelative(GA_PageOff(off-myBaseOffset));
146  }
147  inline T getRelative(GA_PageOff rel) const
148  {
149  UT_ASSERT_P(rel >= 0 && rel < GA_PAGE_SIZE);
150  return myDataPtr[rel];
151  }
152 
153  inline void set(GA_Offset off, T value)
154  {
155  setRelative(GA_PageOff(off-myBaseOffset), value);
156  }
157  inline void setRelative(GA_PageOff rel, T value)
158  {
159  UT_ASSERT_P(rel >= 0 && rel < GA_PAGE_SIZE);
160  myDataPtr[rel] = value;
161  }
162 
163  // Returns a reference so you can do things like:
164  // page.value(offset) += 5
165  inline T & value(GA_Offset off)
166  {
168  }
169  inline T & valueRelative(GA_PageOff rel)
170  {
171  UT_ASSERT_P(rel >= 0 && rel < GA_PAGE_SIZE);
172  return myDataPtr[rel];
173  }
174 
175  // Writes backout the page table if it was copied in.
176  // Normally end users do not have to do this as it will be
177  // done automatically when switching pages or destructing.
178  void flushIfNeeded();
179 
180 protected:
183  INTERNAL_ATTRIB * myAttrib;
187 };
188 
189 template <typename T>
191 {
192 public:
193  typedef T value_type;
194 
197 };
198 
199 template <typename T>
201 {
202 public:
203  typedef T value_type;
204 
207 };
208 
213 
216 
219 
222 
225 
230 
235 
240 
245 
250 
255 
260 
261 
262 ///////////////////////////////////////////////////////////////////////////////
263 //
264 // GA_PageHandleT implementation
265 //
266 
267 template <typename T, typename TB, bool READ, bool WRITE, typename EXTERNAL_ATTRIB, typename INTERNAL_ATTRIB, typename DETAIL>
268 inline void
270  EXTERNAL_ATTRIB *attrib,
271  int component)
272 {
273  if (WRITE)
274  flushIfNeeded();
275  clear();
276  myAttrib = INTERNAL_ATTRIB::cast(attrib);
277  if (!myAttrib)
278  return;
279 
280  if (myAttrib->getTupleSize() < ((1+component) * sizeof(T)/sizeof(TB)))
281  {
282  myAttrib = 0;
283  return;
284  }
285  myComponent = component;
286 }
287 
288 template <typename T, typename TB, bool READ, bool WRITE, typename EXTERNAL_ATTRIB, typename INTERNAL_ATTRIB, typename DETAIL>
289 inline void
291  EXTERNAL_ATTRIB *attrib,
292  int component)
293 {
294  if (WRITE)
295  flushIfNeeded();
296  clear();
297 
298  myAttrib = (INTERNAL_ATTRIB *)(attrib);
299  myComponent = component;
300 }
301 
302 template <typename T, typename TB, bool READ, bool WRITE, typename EXTERNAL_ATTRIB, typename INTERNAL_ATTRIB, typename DETAIL>
303 inline void
305 {
306  // Check if this is the same page as before.
307  if (myDataPtr
308  && pagebase >= myBaseOffset
309  && (pagebase < myBaseOffset + GA_PAGE_SIZE))
310  {
311  return;
312  }
313 
314  if (!isValid())
315  {
316  // We still want to set our page offset with invalid pages
317  // so default values will work
318  pagebase -= GAgetPageOff(pagebase);
319  myBaseOffset = pagebase;
320  return;
321  }
322 
323  if (WRITE)
324  flushIfNeeded();
325 
326  // Set our new base.
327  pagebase -= GAgetPageOff(pagebase);
328  myBaseOffset = pagebase;
329 
330  // Read in our data.
331  GA_PageNum pagenum = GAgetPageNum(pagebase);
332  auto &src = myAttrib->getData();
333  if (myComponent == 0 && UT_StorageNum<TB>::theStorage == src.GA_ATINumeric::DataType::Base::getStorage()
334  && (sizeof(T) / sizeof(TB)) == src.getTupleSize())
335  {
336  if (WRITE)
337  {
338  GA_PageArray<TB,(sizeof(T) / sizeof(TB))> &matchsrc = SYSconst_cast(src).template castTupleSize<sizeof(T)/sizeof(TB)>().template castType<TB>();
339 
340  matchsrc.hardenPage(pagenum);
341  myDataPtr = reinterpret_cast<T*>(SYSconst_cast(matchsrc.getPageData(pagenum)));
342  myIsConstant = false;
343  }
344  else
345  {
346  const GA_PageArray<TB,(sizeof(T) / sizeof(TB))> &matchsrc = src.template castTupleSize<sizeof(T)/sizeof(TB)>().template castType<TB>();
347 
348  if (matchsrc.isPageConstant(pagenum))
349  {
350  T v;
351  const T *data = reinterpret_cast<const T*>(matchsrc.getPageData(pagenum));
352 
353  // Can skip if already marshalled same value last time
354  bool equal = myIsConstant;
355  if (equal)
356  {
357  if (!data)
358  {
359  memset(&v,0,sizeof(T));
360  data = &v;
361  }
362  equal = (myMarshalledData[0] == *data);
363  }
364  UT_ASSERT_P(!equal || myDataPtr == myMarshalledData);
365  if (!equal)
366  {
367  GA_Size count = ((pagebase + GA_PAGE_SIZE) <= matchsrc.size()) ? GA_PAGE_SIZE : (matchsrc.size() & GA_PAGE_MASK);
368  if (!data)
369  {
370  memset(myMarshalledData, 0, count*sizeof(myMarshalledData[0]));
371  }
372  else
373  {
374  for (GA_Size off = 0; off < count; ++off)
375  myMarshalledData[off] = *data;
376  }
377  myDataPtr = myMarshalledData;
378  myIsConstant = true;
379  }
380  }
381  else
382  {
383  myDataPtr = reinterpret_cast<T*>(SYSconst_cast(matchsrc.getPageData(pagenum)));
384  myIsConstant = false;
385  }
386  }
387  }
388  else
389  {
390  GA_Size count = ((pagebase + GA_PAGE_SIZE) <= src.size()) ? GA_PAGE_SIZE : (src.size() & GA_PAGE_MASK);
391  if (myComponent <= 0)
392  {
393  for (GA_Size off = 0; off < count; ++off)
394  {
395  typename UT_FixedVectorTraits<T>::FixedVectorType v = src.template getVector<TB, sizeof(T) / sizeof(TB)>(pagebase + off);
396  myMarshalledData[off] = *reinterpret_cast<const T*>(&v);
397  }
398  }
399  else
400  {
401  UT_ASSERT_MSG_P((SYSisSame<T,TB>()), "Don't currently support vector types when myComponent > 0.");
402  for (GA_Size off = 0; off < count; ++off)
403  {
404  TB v = src.template get<TB>(pagebase + off, myComponent);
405  myMarshalledData[off] = *reinterpret_cast<const T*>(&v);
406  }
407  }
408  myDataPtr = myMarshalledData;
409  myIsConstant = src.isPageConstant(pagenum);
410  }
411 }
412 
413 #endif // __GA_PAGEHANDLE_H_INCLUDED__
T & value(GA_Offset off)
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
int64 GA_DataId
Definition: GA_Types.h:663
const GLdouble * v
Definition: glcorearb.h:836
GA_Offset myBaseOffset
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:127
void flushIfNeeded()
GA_PageHandleV< UT_Vector2D >::RWType GA_RWPageHandleV2D
GA_PageHandleV< UT_Vector3D >::ROType GA_ROPageHandleV3D
GA_PageHandleScalar< fpreal >::ROType GA_ROPageHandleR
#define GA_INVALID_DATAID
Definition: GA_Types.h:664
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
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
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:125
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)
GLenum GLsizei GLsizei GLint * values
Definition: glcorearb.h:1601
#define GA_PAGE_MASK
Definition: GA_Types.h:201
void setDefaultValue(T value)
void setPageConstant(GA_PageNum pagenum, T values)
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
EXTERNAL_ATTRIB * operator->() const
Definition: GA_PageHandle.h:77
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)
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_DataId getDataId() const
Definition: GA_PageHandle.h:88
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:95
GA_PageHandleScalar< int64 >::RWType GA_RWPageHandleID
GA_PageHandleScalar< int32 >::RWType GA_RWPageHandleI
#define WRITE(z, n, data)
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
#define UT_ASSERT_MSG_P(ZZ, MM)
Definition: UT_Assert.h:128
GLenum src
Definition: glcorearb.h:1792
GA_PageHandleV< UT_Matrix4F >::RWType GA_RWPageHandleM4