Panda3D
vertexDataBuffer.I
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file vertexDataBuffer.I
10  * @author drose
11  * @date 2007-05-14
12  */
13 
14 /**
15  *
16  */
17 INLINE VertexDataBuffer::
18 VertexDataBuffer() :
19  _resident_data(nullptr),
20  _size(0),
21  _reserved_size(0)
22 {
23 }
24 
25 /**
26  *
27  */
28 INLINE VertexDataBuffer::
29 VertexDataBuffer(size_t size) :
30  _resident_data(nullptr),
31  _size(0),
32  _reserved_size(0)
33 {
34  do_unclean_realloc(size);
35  _size = size;
36 }
37 
38 /**
39  *
40  */
41 INLINE VertexDataBuffer::
42 VertexDataBuffer(const VertexDataBuffer &copy) :
43  _resident_data(nullptr),
44  _size(0),
45  _reserved_size(0)
46 {
47  (*this) = copy;
48 }
49 
50 /**
51  *
52  */
53 INLINE VertexDataBuffer::
54 ~VertexDataBuffer() {
55  clear();
56 }
57 
58 /**
59  * Returns a read-only pointer to the raw data, or NULL if the data is not
60  * currently resident. If the data is not currently resident, this will
61  * implicitly request it to become resident soon.
62  *
63  * If force is true, this method will never return NULL (unless the data is
64  * actually empty), but may block until the data is available.
65  */
66 INLINE const unsigned char *VertexDataBuffer::
67 get_read_pointer(bool force) const {
68  LightMutexHolder holder(_lock);
69 
70  const unsigned char *ptr;
71  if (_resident_data != nullptr || _size == 0) {
72  ptr = _resident_data;
73  } else {
74  nassertr(_block != nullptr, nullptr);
75  nassertr(_reserved_size >= _size, nullptr);
76 
77  // We don't necessarily need to page the buffer all the way into independent
78  // status; it's sufficient just to return the block's pointer, which will
79  // force its page to resident status.
80  ptr = _block->get_pointer(force);
81  }
82 #ifdef _DEBUG
83  assert(((uintptr_t)ptr % MEMORY_HOOK_ALIGNMENT) == 0);
84 #endif
85  return (const unsigned char *)ASSUME_ALIGNED(ptr, MEMORY_HOOK_ALIGNMENT);
86 }
87 
88 /**
89  * Returns a writable pointer to the raw data.
90  */
91 INLINE unsigned char *VertexDataBuffer::
93  LightMutexHolder holder(_lock);
94 
95  if (_resident_data == nullptr && _reserved_size != 0) {
96  do_page_in();
97  }
98  nassertr(_reserved_size >= _size, nullptr);
99 #ifdef _DEBUG
100  assert(((uintptr_t)_resident_data % MEMORY_HOOK_ALIGNMENT) == 0);
101 #endif
102  return (unsigned char *)ASSUME_ALIGNED(_resident_data, MEMORY_HOOK_ALIGNMENT);
103 }
104 
105 /**
106  * Returns the number of bytes in the buffer.
107  */
108 INLINE size_t VertexDataBuffer::
109 get_size() const {
110  return _size;
111 }
112 
113 /**
114  * Returns the total number of bytes "reserved" in the buffer. This may be
115  * greater than or equal to get_size(). If it is greater, the additional
116  * bytes are extra unused bytes in the buffer, and this indicates the maximum
117  * value that may be passed to set_size() without first calling one of the
118  * realloc methods.
119  */
120 INLINE size_t VertexDataBuffer::
122  return _reserved_size;
123 }
124 
125 /**
126  * Changes the size of the buffer. The new size must be less than or equal to
127  * the "reserved" size, which can only be changed via clean_realloc() or
128  * unclean_realloc().
129  */
130 INLINE void VertexDataBuffer::
131 set_size(size_t size) {
132  LightMutexHolder holder(_lock);
133  nassertv(size <= _reserved_size);
134 
135  if (size != _size) {
136  if (_resident_data == nullptr && _reserved_size != 0) {
137  do_page_in();
138  }
139 
140  _size = size;
141  }
142 }
143 
144 /**
145  * Changes the "reserved" size of the buffer, preserving its data (except for
146  * any data beyond the new end of the buffer, if the buffer is being reduced).
147  * If the buffer is expanded, the new data is uninitialized.
148  *
149  * It is an error to set the reserved size smaller than the size specified
150  * with set_size().
151  */
152 INLINE void VertexDataBuffer::
153 clean_realloc(size_t reserved_size) {
154  LightMutexHolder holder(_lock);
155  do_clean_realloc(reserved_size);
156 }
157 
158 /**
159  * Changes the size of the buffer, without regard to preserving its data. The
160  * buffer may contain random data after this call.
161  *
162  * It is an error to set the reserved size smaller than the size specified
163  * with set_size().
164  */
165 INLINE void VertexDataBuffer::
166 unclean_realloc(size_t reserved_size) {
167  LightMutexHolder holder(_lock);
168  do_unclean_realloc(reserved_size);
169 }
170 
171 /**
172  * Empties the buffer and sets its size to 0.
173  */
174 INLINE void VertexDataBuffer::
175 clear() {
176  LightMutexHolder holder(_lock);
177  _size = 0;
178  do_unclean_realloc(0);
179 }
180 
181 /**
182  * Moves the buffer out of independent memory and puts it on a page in the
183  * indicated book. The buffer may still be directly accessible as long as its
184  * page remains resident. Any subsequent attempt to rewrite the buffer will
185  * implicitly move it off of the page and back into independent memory.
186  */
187 INLINE void VertexDataBuffer::
189  LightMutexHolder holder(_lock);
190  do_page_out(book);
191 }
unsigned char * get_write_pointer()
Returns a writable pointer to the raw data.
size_t get_size() const
Returns the number of bytes in the buffer.
const unsigned char * get_read_pointer(bool force) const
Returns a read-only pointer to the raw data, or NULL if the data is not currently resident.
void clear()
Empties the buffer and sets its size to 0.
void clean_realloc(size_t reserved_size)
Changes the "reserved" size of the buffer, preserving its data (except for any data beyond the new en...
Similar to MutexHolder, but for a light mutex.
A block of bytes that stores the actual raw vertex data referenced by a GeomVertexArrayData object.
size_t get_reserved_size() const
Returns the total number of bytes "reserved" in the buffer.
void set_size(size_t size)
Changes the size of the buffer.
A collection of VertexDataPages, which can be used to allocate new VertexDataBlock objects.
void unclean_realloc(size_t reserved_size)
Changes the size of the buffer, without regard to preserving its data.
void page_out(VertexDataBook &book)
Moves the buffer out of independent memory and puts it on a page in the indicated book.