HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GA_DataArrayPageTableImpl.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_DataArrayPageTableImpl.h (GA Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __GA_DATAARRAYPAGETABLEIMPL_H_INCLUDED__
12 #define __GA_DATAARRAYPAGETABLEIMPL_H_INCLUDED__
13 
14 #include "GA_Types.h"
15 
16 #include <UT/UT_Array.h>
17 #include <UT/UT_Assert.h>
18 #include <UT/UT_Vector3.h>
19 #include <UT/UT_VectorTypes.h>
20 
21 #include <SYS/SYS_AtomicInt.h>
22 #include <SYS/SYS_Math.h>
23 #include <SYS/SYS_Memory.h>
24 #include <SYS/SYS_Types.h>
25 
26 #include <string.h>
27 
28 class UT_MemoryCounter;
29 
30 //#define VERBOSE_DATAARRAY_DEBUG_OUTPUT
31 
32 /// Internal namespace for GA classes.
33 /// SUBJECT TO CHANGE! NOT FOR USE BY HDK USERS!
34 namespace GA_Private {
35 
36 // class representing a page of numeric data
37 template <typename T>
39 {
40 public:
42  : myRefCount(1)
43  , myCapacity((int)GA_Size(capacity))
44  {
45  UT_ASSERT_P(capacity > 0);
46  UT_ASSERT_P(capacity <= GA_PAGE_SIZE);
47  myData = (T *)malloc(capacity * sizeof(T));
48  }
50  {
51  free(myData);
52  }
53 
54  /// Report memory usage (includes all shared memory)
55  int64
56  getMemoryUsage(bool inclusive) const
57  {
58  return (inclusive ? sizeof(*this) : 0) + myCapacity*sizeof(T);
59  }
60 
61  /// Count memory usage using a UT_MemoryCounter in order to count
62  /// shared memory correctly.
63  /// If inclusive is true, the size of this object is counted,
64  /// else only memory owned by this object is counted.
65  /// If this is pointed to by the calling object, inclusive should be true.
66  /// If this is contained in the calling object, inclusive should be false.
67  /// (Its memory was already counted in the size of the calling object.)
68  void countMemory(UT_MemoryCounter &counter, bool inclusive) const;
69 
70  // thread-safe reference counting methods
71  void ref() const { myRefCount.add(1); }
72  void unref() { if(myRefCount.add(-1) == 0) delete this; }
73  SYS_FORCE_INLINE bool isShared() const { return myRefCount.relaxedLoad() != 1; }
74 
76  copy(GA_PageOff newcapacity = GA_PageOff(GA_PAGE_SIZE)) const
77  {
78 #ifdef VERBOSE_DATAARRAY_DEBUG_OUTPUT
79  printf("Copying page %p capacity %d into capacity %d\n", this, (int)myCapacity, (int)newcapacity);
80  fflush(stdout);
81 #endif
82  UT_ASSERT_P(myCapacity > 0 && myCapacity <= GA_PAGE_SIZE);
83  UT_ASSERT_P(newcapacity > 0 && newcapacity <= GA_PAGE_SIZE);
84 
85  ga_DataArrayPage<T> *d = new ga_DataArrayPage<T>(newcapacity);
86  if (d && d->myData)
87  {
88  GA_Size sizetocopy = SYSmin(myCapacity, newcapacity);
89  memcpy(d->myData, myData, sizetocopy * sizeof(T));
90  }
91  return d;
92  }
93 
94  const T *castToData() const { return myData; }
95  T *castToData() { return myData; }
96 
97  int capacity() const { return myCapacity; }
98 
99 private:
100  T * myData;
101  mutable SYS_AtomicInt32 myRefCount;
102  int myCapacity;
103 };
104 
105 
106 template<typename T> static inline bool
107 ga_IsNotZero(T a) { return (bool) a; }
108 template<> inline bool
109 ga_IsNotZero(fpreal16 a) { return !a.isZero(); }
110 template<> inline bool
111 ga_IsNotZero(UT_Vector3H a) { return a.x() || a.y() || a.z(); }
112 template<> inline bool
113 ga_IsNotZero(UT_Vector3F a) { return a.x() || a.y() || a.z(); }
114 template<> inline bool
115 ga_IsNotZero(UT_Vector3D a) { return a.x() || a.y() || a.z(); }
116 template<> inline bool
117 ga_IsNotZero(UT_Vector4H a) { return a.x() || a.y() || a.z() || a.w(); }
118 template<> inline bool
119 ga_IsNotZero(UT_Vector4F a) { return a.x() || a.y() || a.z() || a.w(); }
120 template<> inline bool
121 ga_IsNotZero(UT_Vector4D a) { return a.x() || a.y() || a.z() || a.w(); }
122 
123 
125 {
126 };
127 
128 // Internal implementation extracted from ga_DataArrayPageTable so that
129 // GA_Detail::getPos3()/setPos3() can perform fast direct lookups.
130 // @c T is the storage type, either a scalar type or a POD type
131 // @c TB is the underlying scalar type (same as T if T is a scalar type)
132 // @c SLICE is the component of a POD type represented by this table
133 // @c VECTORSIZE is the number of @c TB components making up @c T
134 template <typename T, typename TB, int SLICE, int VECTORSIZE>
136 {
137 protected:
138 
140  {
141  union
142  {
144  char rawvalue[sizeof(T)];
145 
146  // We can't just have T value because fpreal16 has
147  // a constructor.
148  const T & value() const { return *((const T*)rawvalue); }
149  T & value() { return *((T*)rawvalue); }
150  const TB & scalarValue() const { return ((const TB*)rawvalue)[SLICE]; }
151  TB & scalarValue() { return ((TB*)rawvalue)[SLICE]; }
152  } myData;
153 
155 
156  // Note the usage of this is handled by the caller that thinks
157  // this is a pointer.
158  int64
159  getMemoryUsage(bool inclusive) const
160  {
161  int64 mem = inclusive ? sizeof(*this) : 0;
162  if (!myRawData)
163  return mem;
164  else
165  return mem + myData.ptr->getMemoryUsage(true);
166  }
167  void countMemory(UT_MemoryCounter &counter, bool inclusive) const;
168  };
169 
170  // The internal array of myPages is shared among slices.
171  // It is only allocated by slice 0 and cannot be resized, once shared.
173 
174  // In order to share myCountInLast among slices,
175  // it can't be a directly-stored integer. Its value
176  // is kept in element 0 of the UT_Array, but is
177  // only allocated by slice 0; the rest share the same
178  // internal array of UT_Array.
180  // Same is true of myCapacityInLast
182  // The default value with which to fill new pages and allocations
184 
185 public:
186 
188  : myDefault(def)
189  , myCountInLast((SLICE == 0) ? 1 : 0)
190  , myCapacityInLast((SLICE == 0) ? 1 : 0)
191  {
192  if (SLICE == 0)
193  {
196  }
197  }
198 
200  countInLast() const { return myCountInLast(0); }
201 
203  countInLast() { return myCountInLast(0); }
204 
206  capacityInLast() const { return myCapacityInLast(0); }
207 
210 
212  get(GA_Offset offset) const
213  {
214  return get(GAgetPageNum(offset), GAgetPageOff(offset));
215  }
216  SYS_FORCE_INLINE void
218  {
219  set(GAgetPageNum(offset), GAgetPageOff(offset), v);
220  }
222  get(GA_PageNum pageid, GA_PageOff offset) const
223  {
224  UT_ASSERT_P(pageid >= 0 && pageid < myPages.entries());
226  UT_ASSERT_P(pageid != myPages.entries() - 1 || offset < countInLast());
227  const ga_DataArrayPagePtr &page = myPages(pageid);
228  if (!page.myRawData)
229  return page.myData.scalarValue();
230  else
231  return ((TB*)&(page.myRawData[offset]))[SLICE];
232  }
233  SYS_FORCE_INLINE void
235  {
236  UT_ASSERT_P(pageid >= 0 && pageid < myPages.entries());
237  UT_ASSERT_P(offset >= 0 && offset < GA_PAGE_SIZE);
238  UT_ASSERT_P(pageid != myPages.entries() - 1 || offset < countInLast());
239 #ifdef VERBOSE_DATAARRAY_DEBUG_OUTPUT
240  printf("(table %p) Setting slice %d of page %d offset %d value %d (pages %d; countinlast %d; capacityinlast %d)\n", this, (int)SLICE, (int)pageid, (int)offset, (int)v, (int)myPages.entries(), (int)countInLast(), (int)capacityInLast());
241  fflush(stdout);
242 #endif
243  UT_ASSERT_P(pageid != myPages.entries() - 1 || (!myPages(pageid).myRawData && !capacityInLast()) || (myPages(pageid).myRawData && capacityInLast()));
244  ga_DataArrayPagePtr &page = myPages(pageid);
245  if (page.myRawData)
246  {
247 #ifdef VERBOSE_DATAARRAY_DEBUG_OUTPUT
248  printf(" &page = %p; page.myRawData = %p\n", &page, page.myRawData);
249  fflush(stdout);
250 #endif
251  if (page.myData.ptr->isShared())
252  {
253  bool islast = pageid == myPages.entries() - 1;
254  GA_PageOff capacity = islast ? capacityInLast() : GA_PageOff(GA_PAGE_SIZE);
255  ((TB*)&forceHardenToData(pageid, capacity)[offset])[SLICE] = v;
256  }
257  else
258  ((TB*)&page.myRawData[offset])[SLICE] = v;
259  }
260  else
261  {
262  // Setting a constant page.
263  if (page.myData.scalarValue() != v)
264  {
265 #ifdef VERBOSE_DATAARRAY_DEBUG_OUTPUT
266  printf(" non-default value\n");
267  fflush(stdout);
268 #endif
269  if (countInLast() == 1 && pageid == myPages.entries() - 1)
270  {
271 #ifdef VERBOSE_DATAARRAY_DEBUG_OUTPUT
272  printf(" no need to harden (countInLast = %d; entries = %d)\n", countInLast(), myPages.entries());
273  fflush(stdout);
274 #endif
275  // Only one item, so just change its value
276  page.myData.scalarValue() = v;
277  }
278  else
279  {
280 #ifdef VERBOSE_DATAARRAY_DEBUG_OUTPUT
281  printf(" need to harden (countInLast = %d; entries = %d)\n", countInLast(), myPages.entries());
282  fflush(stdout);
283 #endif
284  // Need to actually expand.
285  bool islast = pageid == myPages.entries() - 1;
286  GA_PageOff capacity = islast ? countInLast() : GA_PageOff(GA_PAGE_SIZE);
287  ((TB*)&forceHardenToData(pageid, capacity)[offset])[SLICE] = v;
288  }
289  }
290  }
291  }
292 
293  SYS_FORCE_INLINE void
295  {
296  UT_ASSERT_P(pageid >= 0 && pageid < myPages.entries());
297  UT_ASSERT_P(offset >= 0 && offset < GA_PAGE_SIZE);
298  UT_ASSERT_P(pageid != myPages.entries() - 1 || offset < countInLast());
299 #ifdef VERBOSE_DATAARRAY_DEBUG_OUTPUT
300  printf("(table %p) Adding to slice %d of page %d offset %d\n", this, (int)SLICE, (int)pageid, (int)offset);
301  fflush(stdout);
302 #endif
303  ga_DataArrayPagePtr &page = myPages(pageid);
304  if (page.myRawData)
305  {
306  if (page.myData.ptr->isShared())
307  {
308  bool islast = pageid == myPages.entries() - 1;
309  GA_PageOff capacity = islast ? capacityInLast() : GA_PageOff(GA_PAGE_SIZE);
310  ((TB*)&forceHardenToData(pageid, capacity)[offset])[SLICE] += v;
311  }
312  else
313  ((TB*)&page.myRawData[offset])[SLICE] += v;
314  }
315  else if (countInLast() == 1 && pageid == myPages.entries() - 1)
316  {
317  page.myData.scalarValue() += v;
318  }
319  else
320  {
321  bool islast = pageid == myPages.entries() - 1;
322  GA_PageOff capacity = islast ? countInLast() : GA_PageOff(GA_PAGE_SIZE);
323  ((TB*)&forceHardenToData(pageid, capacity)[offset])[SLICE] += v;
324  }
325  }
326 
329  {
330  return getVector(GAgetPageNum(offset), GAgetPageOff(offset));
331  }
332  SYS_FORCE_INLINE void
334  {
335  setVector(GAgetPageNum(offset), GAgetPageOff(offset), v);
336  }
339  {
340  UT_ASSERT_P(pageid >= 0 && pageid < myPages.entries());
341  UT_ASSERT_P(offset >= 0 && offset < GA_PAGE_SIZE);
342  UT_ASSERT_P(pageid != myPages.entries() - 1 || offset < countInLast());
343 #ifdef VERBOSE_DATAARRAY_DEBUG_OUTPUT
344  printf("(table %p) Getting page %d offset %d (slice = %d; vectorsize = %d; value[%d] = %e)\n", this, (int)pageid, (int)offset, (int)SLICE, (int)VECTORSIZE, (int)SLICE, get(pageid, offset));
345  fflush(stdout);
346 #endif
347  const ga_DataArrayPagePtr &page = myPages(pageid);
348  if (!page.myRawData)
349  return page.myData.value();
350  else
351  return page.myRawData[offset];
352  }
353  SYS_FORCE_INLINE void
355  {
356  UT_ASSERT_P(pageid >= 0 && pageid < myPages.entries());
357  UT_ASSERT_P(offset >= 0 && offset < GA_PAGE_SIZE);
358  UT_ASSERT_P(pageid != myPages.entries() - 1 || offset < countInLast());
359 #ifdef VERBOSE_DATAARRAY_DEBUG_OUTPUT
360  printf("(table %p) Setting page %d offset %d (slice = %d; vectorsize = %d; v[0] = %e; previousvalue[%d] = %e)\n", this, (int)pageid, (int)offset, (int)SLICE, (int)VECTORSIZE, ((TB*)&v)[0], (int)SLICE, get(pageid, offset));
361  fflush(stdout);
362 #endif
363  ga_DataArrayPagePtr &page = myPages(pageid);
364  if (page.myRawData)
365  {
366  if (page.myData.ptr->isShared())
367  {
368  bool islast = pageid == myPages.entries() - 1;
369  GA_PageOff capacity = islast ? capacityInLast() : GA_PageOff(GA_PAGE_SIZE);
370  forceHardenToData(pageid, capacity)[offset] = v;
371  }
372  else
373  page.myRawData[offset] = v;
374  }
375  else
376  {
377  // Setting a constant page.
378  if (page.myData.value() != v)
379  {
380 #ifdef VERBOSE_DATAARRAY_DEBUG_OUTPUT
381  printf(" non-default value\n");
382  fflush(stdout);
383 #endif
384  if (countInLast() == 1 && pageid == myPages.entries() - 1)
385  {
386 #ifdef VERBOSE_DATAARRAY_DEBUG_OUTPUT
387  printf(" no need to harden (countInLast = %d; entries = %d)\n", countInLast(), myPages.entries());
388  fflush(stdout);
389 #endif
390  // Only one item, so just change its value
391  page.myData.value() = v;
392  }
393  else
394  {
395 #ifdef VERBOSE_DATAARRAY_DEBUG_OUTPUT
396  printf(" need to harden (countInLast = %d; entries = %d)\n", countInLast(), myPages.entries());
397  fflush(stdout);
398 #endif
399  // Need to actually expand.
400  bool islast = pageid == myPages.entries() - 1;
401  GA_PageOff capacity = islast ? countInLast() : GA_PageOff(GA_PAGE_SIZE);
402  forceHardenToData(pageid, capacity)[offset] = v;
403  }
404  }
405  }
406 #ifdef VERBOSE_DATAARRAY_DEBUG_OUTPUT
407  printf(" newvalue[%d] = %e)\n", (int)SLICE, get(pageid, offset));
408  fflush(stdout);
409 #endif
410  }
411  SYS_FORCE_INLINE void
413  {
414  addVector(GAgetPageNum(offset), GAgetPageOff(offset), v);
415  }
416  SYS_FORCE_INLINE void
418  {
419  UT_ASSERT_P(pageid >= 0 && pageid < myPages.entries());
420  UT_ASSERT_P(offset >= 0 && offset < GA_PAGE_SIZE);
421  UT_ASSERT_P(pageid != myPages.entries() - 1 || offset < countInLast());
422 #ifdef VERBOSE_DATAARRAY_DEBUG_OUTPUT
423  printf("(table %p) Adding to page %d offset %d\n", this, (int)pageid, (int)offset);
424  fflush(stdout);
425 #endif
426  ga_DataArrayPagePtr &page = myPages(pageid);
427  if (page.myRawData)
428  {
429  if (page.myData.ptr->isShared())
430  {
431  bool islast = pageid == myPages.entries() - 1;
432  GA_PageOff capacity = islast ? capacityInLast() : GA_PageOff(GA_PAGE_SIZE);
433  forceHardenToData(pageid, capacity)[offset] += v;
434  }
435  else
436  page.myRawData[offset] += v;
437  }
438  else if (countInLast() == 1 && pageid == myPages.entries() - 1)
439  {
440  page.myData.value() += v;
441  }
442  else
443  {
444  bool islast = pageid == myPages.entries() - 1;
445  GA_PageOff capacity = islast ? countInLast() : GA_PageOff(GA_PAGE_SIZE);
446  forceHardenToData(pageid, capacity)[offset] += v;
447  }
448  }
449 
452  {
453  ga_DataArrayPage<T> *page = new ga_DataArrayPage<T>(capacity);
454  T *data = page->castToData();
455 
456  if (ga_IsNotZero(value))
457  {
458  for (GA_Size i = 0; i < startdef; ++i)
459  data[i] = value;
460  }
461  else
462  {
463  memset(data, 0, startdef * sizeof(T));
464  }
465  if (startdef < capacity)
466  {
467  if (ga_IsNotZero(myDefault))
468  {
469  for (GA_Size i = startdef; i < capacity; ++i)
470  data[i] = myDefault;
471  }
472  else
473  {
474  memset(data + startdef, 0, (capacity - startdef) * sizeof(T));
475  }
476  }
477  return page;
478  }
479 
480  // Doesn't test, just hardens.
481  T *
483  {
484  ga_DataArrayPagePtr & page = myPages(pageid);
485  ga_DataArrayPage<T> * pageptr;
486  T * result;
487 
488  bool islast = (pageid == myPages.entries() - 1);
489  UT_ASSERT_P(islast || capacity == GA_PageOff(GA_PAGE_SIZE));
490  if (!page.myRawData)
491  {
492 #ifdef VERBOSE_DATAARRAY_DEBUG_OUTPUT
493  printf("(table %p) Hardening page %d, pages = %d, countInLast = %d\n", this, (int)pageid, (int)myPages.entries(), (int)countInLast());
494  fflush(stdout);
495 #endif
496  if (islast)
497  {
498 #ifdef VERBOSE_DATAARRAY_DEBUG_OUTPUT
499  printf(" beforevalue[0][%d] = %e)\n", (int)SLICE, get(pageid, 0));
500  fflush(stdout);
501 #endif
502  UT_ASSERT_P(countInLast() <= capacity);
503  pageptr = createConstantPage(page.myData.value(), countInLast(), capacity);
504 #ifdef VERBOSE_DATAARRAY_DEBUG_OUTPUT
505  printf(" aftervalue[0][%d] = %e)\n", (int)SLICE, get(pageid, 0));
506  fflush(stdout);
507 #endif
508  }
509  else
510  pageptr = createConstantPage(page.myData.value(), GA_PageOff(GA_PAGE_SIZE), capacity);
511  page.myData.ptr = pageptr;
512  page.myRawData = result = pageptr->castToData();
513  }
514  else
515  {
516 #ifdef VERBOSE_DATAARRAY_DEBUG_OUTPUT
517  printf("(table %p) Re-hardening page %d, pages = %d, countInLast = %d capacityInLast = %d newcapacity = %d\n", this, (int)pageid, (int)myPages.entries(), (int)countInLast(), (int)capacityInLast(), (int)capacity);
518  fflush(stdout);
519 #endif
520  pageptr = page.myData.ptr;
521  ga_DataArrayPage<T> *oldpage = pageptr;
522  GA_PageOff oldcapacity = islast ? capacityInLast() : GA_PageOff(GA_PAGE_SIZE);
523  pageptr = oldpage->copy(capacity);
524  page.myData.ptr = pageptr;
525  page.myRawData = result = pageptr->castToData();
526  if (oldcapacity < capacity)
527  {
528  if (ga_IsNotZero(myDefault))
529  {
530  for (GA_Size i = oldcapacity; i < capacity; ++i)
531  result[i] = myDefault;
532  }
533  else
534  {
535  memset(result + oldcapacity, 0, (capacity - oldcapacity) * sizeof(T));
536  }
537  }
538  oldpage->unref();
539  }
540 
541  if (islast)
542  capacityInLast() = capacity;
543 
544  UT_ASSERT_P(islast || page.myData.ptr->capacity() == GA_PAGE_SIZE);
545  return result;
546  }
547 
550  {
551  const ga_DataArrayPagePtr &page = myPages(pageid);
552  if (!page.myRawData || page.myData.ptr->isShared())
553  {
554  GA_PageOff capacity = (pageid != myPages.entries() - 1)
556  : countInLast();
557  return forceHardenToData(pageid, capacity);
558  }
559  return page.myRawData;
560  }
561 
562  // Does not unshare shared pages.
565  {
566  const ga_DataArrayPagePtr &page = myPages(pageid);
567 
568  if (!page.myRawData)
569  {
570  return forceHardenToData(pageid);
571  }
572  else
573  {
574  return page.myRawData;
575  }
576  }
577 
578  void
579  setConstant(GA_Offset start_offset, GA_Offset end_offset, T value)
580  {
581  GA_PageNum startid = GAgetPageNum(start_offset);
582  GA_PageOff startoff = GAgetPageOff(start_offset);
583  GA_PageNum endid = GAisValid(end_offset) ? GAgetPageNum(end_offset + GA_PAGE_SIZE - 1) : GA_PageNum(myPages.entries());
584  GA_PageOff endoff = GAisValid(end_offset) ? GAgetPageOff(end_offset) : countInLast();
585  if (startoff != 0)
586  {
587  GA_PageNum pageid = startid;
588  ga_DataArrayPagePtr &page = myPages(pageid);
589  GA_PageOff endstart = (startid != endid-1 || endoff == 0) ? GA_PageOff(GA_PAGE_SIZE) : endoff;
590  if (page.myRawData)
591  {
592  if (page.myData.ptr->isShared())
593  {
594  bool islast = pageid == myPages.entries() - 1;
595  GA_PageOff capacity = islast ? capacityInLast() : GA_PageOff(GA_PAGE_SIZE);
596  forceHardenToData(pageid, capacity);
597  }
598  for (GA_PageOff i = startoff; i < endstart; ++i)
599  page.myRawData[i] = value;
600  }
601  else
602  {
603  // Setting a constant page.
604  if (page.myData.value() != value)
605  {
606  // NOTE: We're never at the start, so we need to expand
607  bool islast = pageid == myPages.entries() - 1;
608  GA_PageOff capacity = islast ? countInLast() : GA_PageOff(GA_PAGE_SIZE);
609  forceHardenToData(pageid, capacity);
610  for (GA_PageOff i = startoff; i < endstart; ++i)
611  page.myRawData[i] = value;
612  }
613  }
614  ++startid;
615  startoff = GA_PageOff(0);
616  }
617  for (GA_PageNum pageid = startid; pageid < endid; ++pageid)
618  {
619  ga_DataArrayPagePtr &page = myPages(pageid);
620  if (pageid != endid-1 || endoff == 0 || (pageid == myPages.entries() - 1 && endoff == countInLast()))
621  {
622  // NOTE: This is a copy-paste from makePageConstant, which isn't accessible here.
623  if (page.myRawData)
624  page.myData.ptr->unref();
625  page.myData.value() = value;
626  page.myRawData = NULL;
627  if (pageid == myPages.entries() - 1)
628  capacityInLast() = GA_PageOff(0);
629  }
630  else
631  {
632  if (page.myRawData)
633  {
634  if (page.myData.ptr->isShared())
635  {
636  bool islast = pageid == myPages.entries() - 1;
637  GA_PageOff capacity = islast ? capacityInLast() : GA_PageOff(GA_PAGE_SIZE);
638  forceHardenToData(pageid, capacity);
639  }
640  for (GA_PageOff i(0); i < endoff; ++i)
641  page.myRawData[i] = value;
642  }
643  else
644  {
645  // Setting a constant page.
646  if (page.myData.value() != value)
647  {
648  // NOTE: We're never all the way to the end in this path, so we need to expand
649  bool islast = pageid == myPages.entries() - 1;
650  GA_PageOff capacity = islast ? countInLast() : GA_PageOff(GA_PAGE_SIZE);
651  forceHardenToData(pageid, capacity);
652  for (GA_PageOff i(0); i < endoff; ++i)
653  page.myRawData[i] = value;
654  }
655  }
656  }
657  }
658  }
659 };
660 
661 // Convenience types
662 typedef ga_DataArrayPageTableImpl<UT_Vector3F,fpreal32,0,3>
670 
671 // Interface used in GA_Handle for direct access to page data
672 
673 template <typename T>
674 static SYS_SAFE_FORCE_INLINE bool
675 ga_pageTableGet(GA_Private::ga_DataArrayPageTableImplV3 *, GA_Offset, T &)
676 {
677  return false;
678 }
679 
680 template <>
684 {
685  if (pagetable)
686  {
687  result = pagetable->getVector(off);
688  return true;
689  }
690  return false;
691 }
692 
693 template <typename T>
694 static SYS_SAFE_FORCE_INLINE bool
695 ga_pageTableSet(GA_Private::ga_DataArrayPageTableImplV3 *, GA_Offset, const T &)
696 {
697  return false;
698 }
699 
700 template <>
703  GA_Offset off, const UT_Vector3 &val)
704 {
705  if (pagetable)
706  {
707  pagetable->setVector(off, val);
708  return true;
709  }
710  return false;
711 }
712 
713 template <typename T, typename S>
714 static SYS_SAFE_FORCE_INLINE bool
715 ga_pageTableAdd(
717  GA_Offset, const S &)
718 {
719  return false;
720 }
721 
722 
723 template <>
727  GA_Offset off, const UT_Vector3F &val)
728 {
729  if (pagetable)
730  {
731  pagetable->addVector(off, val);
732  return true;
733  }
734  return false;
735 }
736 
737 template <>
741  GA_Offset off, const UT_Vector3D &val)
742 {
743  if (pagetable)
744  {
745  pagetable->addVector(off, UT_Vector3F(val));
746  return true;
747  }
748  return false;
749 }
750 
751 } // namespace GA_Private
752 #endif // __GA_DATAARRAYPAGETABLEIMPL_H_INCLUDED__
SYS_FORCE_INLINE GA_PageOff countInLast() const
typedef int(APIENTRYP RE_PFNGLXSWAPINTERVALSGIPROC)(int)
ga_DataArrayPageTableImpl< int16, int16, 0, 1 > ga_DataArrayPageTableImplI16
SYS_FORCE_INLINE GA_PageOff & countInLast()
GA_Size GA_PageOff
Definition: GA_Types.h:645
SYS_FORCE_INLINE void addVector(GA_Offset offset, T v)
ga_DataArrayPageTableImpl< UT_Vector3F, fpreal32, 0, 3 > ga_DataArrayPageTableImplV3
ga_DataArrayPageTableImpl< int64, int64, 0, 1 > ga_DataArrayPageTableImplI64
SYS_SAFE_FORCE_INLINE bool ga_pageTableAdd< UT_Vector3F, UT_Vector3F >(GA_Private::ga_DataArrayPageTableImplV3 *pagetable, GA_Offset off, const UT_Vector3F &val)
bool isZero() const
Definition: fpreal16.h:658
constexpr SYS_FORCE_INLINE T & y() noexcept
Definition: UT_Vector4.h:493
const GLdouble * v
Definition: glcorearb.h:837
auto printf(const S &fmt, const T &...args) -> int
Definition: printf.h:626
GLsizei const GLfloat * value
Definition: glcorearb.h:824
bool GAisValid(GA_Size v)
Definition: GA_Types.h:649
constexpr SYS_FORCE_INLINE T & z() noexcept
Definition: UT_Vector3.h:667
SYS_SAFE_FORCE_INLINE bool ga_pageTableGet< UT_Vector3 >(GA_Private::ga_DataArrayPageTableImplV3 *pagetable, GA_Offset off, UT_Vector3 &result)
void setConstant(GA_Offset start_offset, GA_Offset end_offset, T value)
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1222
**But if you need a result
Definition: thread.h:613
#define SYS_SAFE_FORCE_INLINE
Definition: SYS_Inline.h:54
ga_DataArrayPageTableImpl< int32, int32, 0, 1 > ga_DataArrayPageTableImplI32
3D Vector class.
4D Vector class.
Definition: UT_Vector4.h:174
exint GA_Size
Defines the bit width for index and offset types in GA.
Definition: GA_Types.h:235
GA_PageOff GAgetPageOff(GA_Offset v)
Definition: GA_Types.h:660
constexpr SYS_FORCE_INLINE T & x() noexcept
Definition: UT_Vector4.h:491
SYS_FORCE_INLINE GA_PageOff & capacityInLast()
SYS_FORCE_INLINE void add(GA_PageNum pageid, GA_PageOff offset, TB v)
GA_Size GA_Offset
Definition: GA_Types.h:641
SYS_FORCE_INLINE T getVector(GA_Offset offset) const
GLintptr offset
Definition: glcorearb.h:665
void countMemory(UT_MemoryCounter &counter, bool inclusive) const
constexpr SYS_FORCE_INLINE T & z() noexcept
Definition: UT_Vector4.h:495
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:155
T * forceHardenToData(GA_PageNum pageid, GA_PageOff capacity=GA_PageOff(GA_PAGE_SIZE))
void countMemory(UT_MemoryCounter &counter, bool inclusive) const
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
SYS_FORCE_INLINE T * hardenToData(GA_PageNum pageid)
SYS_FORCE_INLINE T * softenToData(GA_PageNum pageid)
long long int64
Definition: SYS_Types.h:116
SYS_FORCE_INLINE void addVector(GA_PageNum pageid, GA_PageOff offset, T v)
SYS_FORCE_INLINE void set(GA_PageNum pageid, GA_PageOff offset, TB v)
ga_DataArrayPage< T > * copy(GA_PageOff newcapacity=GA_PageOff(GA_PAGE_SIZE)) const
SYS_SAFE_FORCE_INLINE bool ga_pageTableSet< UT_Vector3 >(GA_Private::ga_DataArrayPageTableImplV3 *pagetable, GA_Offset off, const UT_Vector3 &val)
#define GA_PAGE_SIZE
Definition: GA_Types.h:224
exint append()
Definition: UT_Array.h:142
SYS_FORCE_INLINE GA_PageOff capacityInLast() const
UT_Vector3T< fpreal32 > UT_Vector3F
SYS_FORCE_INLINE T relaxedLoad() const
SYS_FORCE_INLINE void setVector(GA_Offset offset, const T &v)
ga_DataArrayPage< T > * createConstantPage(T value, GA_PageOff startdef=GA_PageOff(GA_PAGE_SIZE), GA_PageOff capacity=GA_PageOff(GA_PAGE_SIZE)) const
int64 getMemoryUsage(bool inclusive) const
Report memory usage (includes all shared memory)
union GA_Private::ga_DataArrayPageTableImpl::ga_DataArrayPagePtr::@27 myData
GA_Size GA_PageNum
Definition: GA_Types.h:644
constexpr SYS_FORCE_INLINE T & w() noexcept
Definition: UT_Vector4.h:497
GLuint GLfloat * val
Definition: glcorearb.h:1608
T add(T val)
Atomically adds val to myValue, returning the new value of myValue.
Definition: core.h:1131
SYS_SAFE_FORCE_INLINE bool ga_pageTableAdd< UT_Vector3F, UT_Vector3D >(GA_Private::ga_DataArrayPageTableImplV3 *pagetable, GA_Offset off, const UT_Vector3D &val)
constexpr SYS_FORCE_INLINE T & y() noexcept
Definition: UT_Vector3.h:665
#define SYSmin(a, b)
Definition: SYS_Math.h:1539
SYS_FORCE_INLINE bool isShared() const
SYS_FORCE_INLINE void set(GA_Offset offset, TB v)
Definition: format.h:895
SYS_FORCE_INLINE T getVector(GA_PageNum pageid, GA_PageOff offset) const
GA_PageNum GAgetPageNum(GA_Offset v)
Definition: GA_Types.h:656
SYS_FORCE_INLINE void setVector(GA_PageNum pageid, GA_PageOff offset, const T &v)
constexpr SYS_FORCE_INLINE T & x() noexcept
Definition: UT_Vector3.h:663