Panda3D

Loading...
Searching...
No Matches
geomVertexArrayData.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 geomVertexArrayData.I
10 * @author drose
11 * @date 2005-03-17
12 */
13
14/**
15 * Returns the format object that describes this array.
16 */
17INLINE const GeomVertexArrayFormat *GeomVertexArrayData::
18 get_array_format() const {
19 return _array_format;
20}
21
22/**
23 * Returns the usage hint that describes to the rendering backend how often
24 * the vertex data will be modified and/or rendered. See geomEnums.h.
25 */
26INLINE GeomVertexArrayData::UsageHint GeomVertexArrayData::
27 get_usage_hint() const {
28 CDReader cdata(_cycler);
29 return cdata->_usage_hint;
30}
31
32/**
33 * Returns true if the array has the named column, false otherwise. This is
34 * really just a shortcut for asking the same thing from the format.
35 */
36INLINE bool GeomVertexArrayData::
37 has_column(const InternalName *name) const {
38 return _array_format->has_column(name);
39}
40
41/**
42 * Returns the number of rows stored in the array, based on the number of
43 * bytes and the stride. This should be the same for all arrays within a
44 * given GeomVertexData object.
45 */
46INLINE int GeomVertexArrayData::
47 get_num_rows() const {
48 CDReader cdata(_cycler);
49 nassertr(_array_format->get_stride() != 0, 0);
50 return cdata->_buffer.get_size() / _array_format->get_stride();
51}
52
53/**
54 * Sets the length of the array to n rows.
55 *
56 * Normally, you would not call this directly, since all of the arrays in a
57 * particular GeomVertexData must have the same number of rows; instead, call
58 * GeomVertexData::set_num_rows().
59 *
60 * The return value is true if the number of rows was changed, false if the
61 * object already contained n rows (or if there was some error).
62 *
63 * The new vertex data is initialized to 0, including the "color" column (but
64 * see GeomVertexData::set_num_rows()).
65 *
66 * Don't call this in a downstream thread unless you don't mind it blowing
67 * away other changes you might have recently made in an upstream thread.
68 */
69INLINE bool GeomVertexArrayData::
70 set_num_rows(int n) {
71 return modify_handle()->set_num_rows(n);
72}
73
74/**
75 * This method behaves like set_num_rows(), except the new data is not
76 * initialized. Furthermore, after this call, *any* of the data in the
77 * GeomVertexArrayData may be uninitialized, including the earlier rows.
78 *
79 * Normally, you would not call this directly, since all of the arrays in a
80 * particular GeomVertexData must have the same number of rows; instead, call
81 * GeomVertexData::unclean_set_num_rows().
82 */
83INLINE bool GeomVertexArrayData::
84 unclean_set_num_rows(int n) {
85 return modify_handle()->unclean_set_num_rows(n);
86}
87
88/**
89 * This ensures that enough memory space for n rows is allocated, so that you
90 * may increase the number of rows to n without causing a new memory
91 * allocation. This is a performance optimization only; it is especially
92 * useful when you know ahead of time that you will be adding n rows to the
93 * data.
94 */
95INLINE bool GeomVertexArrayData::
96 reserve_num_rows(int n) {
97 return modify_handle()->reserve_num_rows(n);
98}
99
100/**
101 * Removes all of the rows in the array. Functionally equivalent to
102 * set_num_rows(0).
103 */
104INLINE void GeomVertexArrayData::
105 clear_rows() {
106 return modify_handle()->clear_rows();
107}
108
109/**
110 * Returns the number of bytes stored in the array.
111 */
112INLINE size_t GeomVertexArrayData::
113 get_data_size_bytes() const {
114 CDReader cdata(_cycler);
115 return cdata->_buffer.get_size();
116}
117
118/**
119 * Returns a sequence number which is guaranteed to change at least every time
120 * the array vertex data is modified.
121 */
122INLINE UpdateSeq GeomVertexArrayData::
123 get_modified() const {
124 CDReader cdata(_cycler);
125 return cdata->_modified;
126}
127
128/**
129 * Returns true if the vertex data is currently resident in memory. If this
130 * returns true, the next call to get_handle()->get_read_pointer() will
131 * probably not block. If this returns false, the vertex data will be brought
132 * back into memory shortly; try again later.
133 */
134INLINE bool GeomVertexArrayData::
135 request_resident(Thread *current_thread) const {
136 const GeomVertexArrayData::CData *cdata = _cycler.read_unlocked(current_thread);
137
138#ifdef DO_PIPELINING
139 cdata->ref();
140#endif
141
142 cdata->_rw_lock.acquire();
143
144 ((GeomVertexArrayData *)this)->mark_used();
145 bool is_resident = (cdata->_buffer.get_read_pointer(false) != nullptr);
146
147 cdata->_rw_lock.release();
148
149#ifdef DO_PIPELINING
150 unref_delete((CycleData *)cdata);
151#endif
152
153 return is_resident;
154}
155
156/**
157 * Returns an object that can be used to read the actual data bytes stored in
158 * the array. Calling this method locks the data, and will block any other
159 * threads attempting to read or write the data, until the returned object
160 * destructs.
161 */
162INLINE CPT(GeomVertexArrayDataHandle) GeomVertexArrayData::
163get_handle(Thread *current_thread) const {
164 return new GeomVertexArrayDataHandle(this, current_thread);
165}
166
167/**
168 * Returns an object that can be used to read or write the actual data bytes
169 * stored in the array. Calling this method locks the data, and will block
170 * any other threads attempting to read or write the data, until the returned
171 * object destructs.
172 */
173INLINE PT(GeomVertexArrayDataHandle) GeomVertexArrayData::
174modify_handle(Thread *current_thread) {
175 return new GeomVertexArrayDataHandle(PT(GeomVertexArrayData)(this), current_thread);
176}
177
178/**
179 * Returns a pointer to the global LRU object that manages the
180 * GeomVertexArrayData's that have not (yet) been paged out.
181 */
182INLINE SimpleLru *GeomVertexArrayData::
183 get_independent_lru() {
184 return &_independent_lru;
185}
186
187/**
188 * Returns a pointer to the global LRU object that manages the
189 * GeomVertexArrayData's that are deemed too small to be paged out.
190 */
191INLINE SimpleLru *GeomVertexArrayData::
192 get_small_lru() {
193 return &_small_lru;
194}
195
196/**
197 * Returns the global VertexDataBook that will be used to allocate vertex data
198 * buffers.
199 */
200INLINE VertexDataBook &GeomVertexArrayData::
201 get_book() {
202 return _book;
203}
204
205/**
206 * Should be called when the size of the buffer changes.
207 */
208INLINE void GeomVertexArrayData::
209set_lru_size(size_t lru_size) {
210 SimpleLruPage::set_lru_size(lru_size);
211
212 if ((int)lru_size <= vertex_data_small_size) {
213 SimpleLruPage::mark_used_lru(&_small_lru);
214 } else {
215 SimpleLruPage::mark_used_lru(&_independent_lru);
216 }
217}
218
219/**
220 */
221INLINE void GeomVertexArrayData::
222mark_used() {
223 if ((int)get_lru_size() <= vertex_data_small_size) {
224 SimpleLruPage::mark_used_lru(&_small_lru);
225 } else {
226 SimpleLruPage::mark_used_lru(&_independent_lru);
227 }
228}
229
230/**
231 *
232 */
233INLINE GeomVertexArrayData::CData::
234CData(UsageHint usage_hint) :
235 _usage_hint(usage_hint),
236 _rw_lock("GeomVertexArrayData::CData::_rw_lock")
237{
238}
239
240/**
241 *
242 */
243INLINE GeomVertexArrayData::CData::
244CData(GeomVertexArrayData::CData &&from) noexcept :
245 _usage_hint(std::move(from._usage_hint)),
246 _buffer(std::move(from._buffer)),
247 _modified(std::move(from._modified)),
248 _rw_lock("GeomVertexArrayData::CData::_rw_lock")
249{
250}
251
252/**
253 *
254 */
255INLINE GeomVertexArrayData::CData::
256CData(const GeomVertexArrayData::CData &copy) :
257 _usage_hint(copy._usage_hint),
258 _buffer(copy._buffer),
259 _modified(copy._modified),
260 _rw_lock("GeomVertexArrayData::CData::_rw_lock")
261{
262}
263
264/**
265 *
266 */
267INLINE void GeomVertexArrayData::CData::
268operator = (const GeomVertexArrayData::CData &copy) {
269 _usage_hint = copy._usage_hint;
270 _buffer = copy._buffer;
271 _modified = copy._modified;
272}
273
274/**
275 *
276 */
277INLINE GeomVertexArrayDataHandle::
278GeomVertexArrayDataHandle(CPT(GeomVertexArrayData) object,
279 Thread *current_thread) :
280 _current_thread(current_thread),
281 _cdata((GeomVertexArrayData::CData *)object->_cycler.read_unlocked(current_thread)),
282 _writable(false)
283{
284 _object.swap(object);
285
286#ifdef _DEBUG
287 nassertv(_object->test_ref_count_nonzero());
288#endif // _DEBUG
289#ifdef DO_PIPELINING
290 _cdata->ref();
291#endif // DO_PIPELINING
292 // We must grab the lock *after* we have incremented the reference count,
293 // above.
294 _cdata->_rw_lock.acquire();
295#ifdef DO_MEMORY_USAGE
296 MemoryUsage::update_type(this, get_class_type());
297#endif
298}
299
300/**
301 *
302 */
303INLINE GeomVertexArrayDataHandle::
304GeomVertexArrayDataHandle(const GeomVertexArrayData *object,
305 Thread *current_thread) :
306 _object((GeomVertexArrayData *)object),
307 _current_thread(current_thread),
308 _cdata((GeomVertexArrayData::CData *)object->_cycler.read_unlocked(current_thread)),
309 _writable(false)
310{
311#ifdef _DEBUG
312 nassertv(_object->test_ref_count_nonzero());
313#endif // _DEBUG
314#ifdef DO_PIPELINING
315 _cdata->ref();
316#endif // DO_PIPELINING
317 // We must grab the lock *after* we have incremented the reference count,
318 // above.
319 _cdata->_rw_lock.acquire();
320#ifdef DO_MEMORY_USAGE
321 MemoryUsage::update_type(this, get_class_type());
322#endif
323}
324
325/**
326 *
327 */
328INLINE GeomVertexArrayDataHandle::
329GeomVertexArrayDataHandle(PT(GeomVertexArrayData) object,
330 Thread *current_thread) :
331 _current_thread(current_thread),
332 _cdata(object->_cycler.write_upstream(true, current_thread)),
333 _writable(true)
334{
335 _object.swap(object);
336
337#ifdef _DEBUG
338 nassertv(_object->test_ref_count_nonzero());
339#endif // _DEBUG
340#ifdef DO_PIPELINING
341 _cdata->ref();
342#endif // DO_PIPELINING
343 // We must grab the lock *after* we have incremented the reference count,
344 // above.
345 _cdata->_rw_lock.acquire();
346#ifdef DO_MEMORY_USAGE
347 MemoryUsage::update_type(this, get_class_type());
348#endif
349}
350
351/**
352 *
353 */
354INLINE GeomVertexArrayDataHandle::
355GeomVertexArrayDataHandle(GeomVertexArrayData *object,
356 Thread *current_thread) :
357 _object(object),
358 _current_thread(current_thread),
359 _cdata(object->_cycler.write_upstream(true, current_thread)),
360 _writable(true)
361{
362#ifdef _DEBUG
363 nassertv(_object->test_ref_count_nonzero());
364#endif // _DEBUG
365#ifdef DO_PIPELINING
366 _cdata->ref();
367#endif // DO_PIPELINING
368 // We must grab the lock *after* we have incremented the reference count,
369 // above.
370 _cdata->_rw_lock.acquire();
371#ifdef DO_MEMORY_USAGE
372 MemoryUsage::update_type(this, get_class_type());
373#endif
374}
375
376/**
377 *
378 */
379INLINE GeomVertexArrayDataHandle::
380~GeomVertexArrayDataHandle() {
381#ifdef _DEBUG
382 nassertv(_object->test_ref_count_nonzero());
383#endif // _DEBUG
384
385 if (_writable) {
386 _object->_cycler.release_write(_cdata);
387 }
388
389 // We must release the lock *before* we decrement the reference count,
390 // below.
391 _cdata->_rw_lock.release();
392
393#ifdef DO_PIPELINING
394 unref_delete((CycleData *)_cdata);
395#endif // DO_PIPELINING
396
397#ifdef _DEBUG
398 _object = nullptr;
399 _cdata = nullptr;
400#endif // _DEBUG
401}
402
403/**
404 *
405 */
406INLINE Thread *GeomVertexArrayDataHandle::
407get_current_thread() const {
408 return _current_thread;
409}
410
411/**
412 * Returns a readable pointer to the beginning of the actual data stream, or
413 * NULL if the data is not currently resident. If the data is not currently
414 * resident, this will implicitly request it to become resident soon.
415 *
416 * If force is true, this method will never return NULL, but may block until
417 * the data is available.
418 */
419INLINE const unsigned char *GeomVertexArrayDataHandle::
420 get_read_pointer(bool force) const {
421 mark_used();
422 return _cdata->_buffer.get_read_pointer(force);
423}
424
425/**
426 *
427 */
428INLINE const GeomVertexArrayData *GeomVertexArrayDataHandle::
429get_object() const {
430 return _object;
431}
432
433/**
434 *
435 */
436INLINE GeomVertexArrayData *GeomVertexArrayDataHandle::
437get_object() {
438 return _object;
439}
440
441/**
442 *
443 */
444INLINE const GeomVertexArrayFormat *GeomVertexArrayDataHandle::
445get_array_format() const {
446 return _object->_array_format;
447}
448
449/**
450 *
451 */
452INLINE GeomVertexArrayDataHandle::UsageHint GeomVertexArrayDataHandle::
453get_usage_hint() const {
454 return _cdata->_usage_hint;
455}
456
457/**
458 *
459 */
460INLINE int GeomVertexArrayDataHandle::
461get_num_rows() const {
462 nassertr(_object->_array_format->get_stride() != 0, 0);
463 return get_data_size_bytes() / _object->_array_format->get_stride();
464}
465
466/**
467 *
468 */
469INLINE void GeomVertexArrayDataHandle::
470clear_rows() {
471 set_num_rows(0);
472}
473
474/**
475 *
476 */
477INLINE size_t GeomVertexArrayDataHandle::
478get_data_size_bytes() const {
479 return _cdata->_buffer.get_size();
480}
481
482/**
483 *
484 */
485INLINE UpdateSeq GeomVertexArrayDataHandle::
486get_modified() const {
487 return _cdata->_modified;
488}
489
490/**
491 * Returns true if the vertex data is currently resident in memory. If this
492 * returns true, the next call to get_handle()->get_read_pointer() will
493 * probably not block. If this returns false, the vertex data will be brought
494 * back into memory shortly; try again later.
495 */
496INLINE bool GeomVertexArrayDataHandle::
497 request_resident() const {
498 return (get_read_pointer(false) != nullptr);
499}
500
501/**
502 * Creates a context for the data on the particular GSG, if it does not
503 * already exist. Returns the new (or old) VertexBufferContext. This assumes
504 * that the GraphicsStateGuardian is the currently active rendering context
505 * and that it is ready to accept new datas. If this is not necessarily the
506 * case, you should use prepare() instead.
507 *
508 * Normally, this is not called directly except by the GraphicsStateGuardian;
509 * a data does not need to be explicitly prepared by the user before it may be
510 * rendered.
511 */
512INLINE VertexBufferContext *GeomVertexArrayDataHandle::
513 prepare_now(PreparedGraphicsObjects *prepared_objects,
514 GraphicsStateGuardianBase *gsg) const {
515 return _object->prepare_now(prepared_objects, gsg);
516}
517
518/**
519 * Returns the entire raw data of the GeomVertexArrayData object, formatted as
520 * a string. This is primarily for the benefit of high-level languages such
521 * as Python.
522 */
523INLINE vector_uchar GeomVertexArrayDataHandle::
524 get_data() const {
525 mark_used();
526 const unsigned char *ptr = _cdata->_buffer.get_read_pointer(true);
527 return vector_uchar(ptr, ptr + _cdata->_buffer.get_size());
528}
529
530/**
531 * Returns a subset of the raw data of the GeomVertexArrayData object,
532 * formatted as a string. This is primarily for the benefit of high-level
533 * languages such as Python.
534 */
535INLINE vector_uchar GeomVertexArrayDataHandle::
536 get_subdata(size_t start, size_t size) const {
537 mark_used();
538 start = (std::min)(start, _cdata->_buffer.get_size());
539 size = (std::min)(size, _cdata->_buffer.get_size() - start);
540 const unsigned char *ptr = _cdata->_buffer.get_read_pointer(true) + start;
541 return vector_uchar(ptr, ptr + size);
542}
543
544/**
545 * Marks the array data recently-used.
546 */
547 void GeomVertexArrayDataHandle::
548 mark_used() const {
549 _object->mark_used();
550}
551
552INLINE std::ostream &
553operator << (std::ostream &out, const GeomVertexArrayData &obj) {
554 obj.output(out);
555 return out;
556}
CycleData
A single page of data maintained by a PipelineCycler.
Definition cycleData.h:50
GeomVertexArrayDataHandle
This data object is returned by GeomVertexArrayData::get_handle() or modify_handle().
Definition geomVertexArrayData.h:250
GeomVertexArrayDataHandle::get_subdata
vector_uchar get_subdata(size_t start, size_t size) const
Returns a subset of the raw data of the GeomVertexArrayData object, formatted as a string.
Definition geomVertexArrayData.I:536
GeomVertexArrayDataHandle::prepare_now
VertexBufferContext * prepare_now(PreparedGraphicsObjects *prepared_objects, GraphicsStateGuardianBase *gsg) const
Creates a context for the data on the particular GSG, if it does not already exist.
Definition geomVertexArrayData.I:513
GeomVertexArrayDataHandle::get_read_pointer
const unsigned char * get_read_pointer(bool force) const
Returns a readable pointer to the beginning of the actual data stream, or NULL if the data is not cur...
Definition geomVertexArrayData.I:420
GeomVertexArrayDataHandle::get_data
vector_uchar get_data() const
Returns the entire raw data of the GeomVertexArrayData object, formatted as a string.
Definition geomVertexArrayData.I:524
GeomVertexArrayDataHandle::request_resident
bool request_resident() const
Returns true if the vertex data is currently resident in memory.
Definition geomVertexArrayData.I:497
GeomVertexArrayDataHandle::mark_used
void mark_used() const
Marks the array data recently-used.
Definition geomVertexArrayData.I:548
GeomVertexArrayData
This is the data for one array of a GeomVertexData structure.
Definition geomVertexArrayData.h:58
GeomVertexArrayData::get_usage_hint
get_usage_hint
Returns the usage hint that describes to the rendering backend how often the vertex data will be modi...
Definition geomVertexArrayData.h:80
GeomVertexArrayData::get_data_size_bytes
get_data_size_bytes
Returns the number of bytes stored in the array.
Definition geomVertexArrayData.h:92
GeomVertexArrayData::get_modified
get_modified
Returns a sequence number which is guaranteed to change at least every time the array vertex data is ...
Definition geomVertexArrayData.h:93
GeomVertexArrayData::get_book
static VertexDataBook & get_book()
Returns the global VertexDataBook that will be used to allocate vertex data buffers.
Definition geomVertexArrayData.I:201
GeomVertexArrayData::request_resident
bool request_resident(Thread *current_thread=Thread::get_current_thread()) const
Returns true if the vertex data is currently resident in memory.
Definition geomVertexArrayData.I:135
GeomVertexArrayData::get_small_lru
static SimpleLru * get_small_lru()
Returns a pointer to the global LRU object that manages the GeomVertexArrayData's that are deemed too...
Definition geomVertexArrayData.I:192
GeomVertexArrayData::set_num_rows
bool set_num_rows(int n)
Sets the length of the array to n rows.
Definition geomVertexArrayData.I:70
GeomVertexArrayData::clear_rows
void clear_rows()
Removes all of the rows in the array.
Definition geomVertexArrayData.I:105
GeomVertexArrayData::get_array_format
get_array_format
Returns the format object that describes this array.
Definition geomVertexArrayData.h:76
GeomVertexArrayData::get_num_rows
int get_num_rows() const
Returns the number of rows stored in the array, based on the number of bytes and the stride.
Definition geomVertexArrayData.I:47
GeomVertexArrayData::get_independent_lru
static SimpleLru * get_independent_lru()
Returns a pointer to the global LRU object that manages the GeomVertexArrayData's that have not (yet)...
Definition geomVertexArrayData.I:183
GeomVertexArrayData::reserve_num_rows
bool reserve_num_rows(int n)
This ensures that enough memory space for n rows is allocated, so that you may increase the number of...
Definition geomVertexArrayData.I:96
GeomVertexArrayData::has_column
bool has_column(const InternalName *name) const
Returns true if the array has the named column, false otherwise.
Definition geomVertexArrayData.I:37
GeomVertexArrayData::unclean_set_num_rows
bool unclean_set_num_rows(int n)
This method behaves like set_num_rows(), except the new data is not initialized.
Definition geomVertexArrayData.I:84
GeomVertexArrayFormat
This describes the structure of a single array within a Geom data.
Definition geomVertexArrayFormat.h:47
GraphicsStateGuardianBase
This is a base class for the GraphicsStateGuardian class, which is itself a base class for the variou...
Definition graphicsStateGuardianBase.h:110
InternalName
Encodes a string name in a hash table, mapping it to a pointer.
Definition internalName.h:38
MemoryUsage::update_type
static void update_type(ReferenceCount *ptr, TypeHandle type)
Associates the indicated type with the given pointer.
Definition memoryUsage.I:55
PreparedGraphicsObjects
A table of objects that are saved within the graphics context for reference by handle later.
Definition preparedGraphicsObjects.h:58
ReMutexDirect::acquire
void acquire() const
Grabs the reMutex if it is available.
Definition reMutexDirect.I:82
ReMutexDirect::release
void release() const
Releases the reMutex.
Definition reMutexDirect.I:161
SimpleLruPage::get_lru_size
size_t get_lru_size() const
Returns the size of this page as reported to the LRU, presumably in bytes.
Definition simpleLru.I:171
SimpleLruPage::mark_used_lru
void mark_used_lru() const
To be called when the page is used; this will move it to the tail of the SimpleLru queue it is alread...
Definition simpleLru.I:152
SimpleLruPage::set_lru_size
void set_lru_size(size_t lru_size)
Specifies the size of this page, presumably in bytes, although any unit is possible.
Definition simpleLru.I:180
Thread
A thread; that is, a lightweight process.
Definition thread.h:46
UpdateSeq
This is a sequence number that increments monotonically.
Definition updateSeq.h:37
VertexBufferContext
This is a special class object that holds all the information returned by a particular GSG to indicat...
Definition vertexBufferContext.h:33
VertexDataBook
A collection of VertexDataPages, which can be used to allocate new VertexDataBlock objects.
Definition vertexDataBook.h:30
VertexDataBuffer::get_read_pointer
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.
Definition vertexDataBuffer.I:67
VertexDataBuffer::get_size
size_t get_size() const
Returns the number of bytes in the buffer.
Definition vertexDataBuffer.I:109
unref_delete
void unref_delete(RefCountType *ptr)
This global helper function will unref the given ReferenceCount object, and if the reference count re...
Definition referenceCount.I:344