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