00001 // Filename: geomVertexArrayData.I 00002 // Created by: drose (17Mar05) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 00016 //////////////////////////////////////////////////////////////////// 00017 // Function: GeomVertexArrayData::get_array_format 00018 // Access: Published 00019 // Description: Returns the format object that describes this array. 00020 //////////////////////////////////////////////////////////////////// 00021 INLINE const GeomVertexArrayFormat *GeomVertexArrayData:: 00022 get_array_format() const { 00023 return _array_format; 00024 } 00025 00026 //////////////////////////////////////////////////////////////////// 00027 // Function: GeomVertexArrayData::get_usage_hint 00028 // Access: Published 00029 // Description: Returns the usage hint that describes to the 00030 // rendering backend how often the vertex data will be 00031 // modified and/or rendered. See geomEnums.h. 00032 //////////////////////////////////////////////////////////////////// 00033 INLINE GeomVertexArrayData::UsageHint GeomVertexArrayData:: 00034 get_usage_hint() const { 00035 CDReader cdata(_cycler); 00036 return cdata->_usage_hint; 00037 } 00038 00039 //////////////////////////////////////////////////////////////////// 00040 // Function: GeomVertexArrayData::has_column 00041 // Access: Published 00042 // Description: Returns true if the array has the named column, 00043 // false otherwise. This is really just a shortcut for 00044 // asking the same thing from the format. 00045 //////////////////////////////////////////////////////////////////// 00046 INLINE bool GeomVertexArrayData:: 00047 has_column(const InternalName *name) const { 00048 return _array_format->has_column(name); 00049 } 00050 00051 //////////////////////////////////////////////////////////////////// 00052 // Function: GeomVertexArrayData::get_num_rows 00053 // Access: Published 00054 // Description: Returns the number of rows stored in the array, 00055 // based on the number of bytes and the stride. This 00056 // should be the same for all arrays within a given 00057 // GeomVertexData object. 00058 //////////////////////////////////////////////////////////////////// 00059 INLINE int GeomVertexArrayData:: 00060 get_num_rows() const { 00061 return get_handle()->get_num_rows(); 00062 } 00063 00064 //////////////////////////////////////////////////////////////////// 00065 // Function: GeomVertexArrayData::set_num_rows 00066 // Access: Published 00067 // Description: Sets the length of the array to n rows. 00068 // 00069 // Normally, you would not call this directly, since all 00070 // of the arrays in a particular GeomVertexData must 00071 // have the same number of rows; instead, call 00072 // GeomVertexData::set_num_rows(). 00073 // 00074 // The return value is true if the number of rows 00075 // was changed, false if the object already contained n 00076 // rows (or if there was some error). 00077 // 00078 // The new vertex data is initialized to 0, including 00079 // the "color" column (but see 00080 // GeomVertexData::set_num_rows()). 00081 // 00082 // Don't call this in a downstream thread unless you 00083 // don't mind it blowing away other changes you might 00084 // have recently made in an upstream thread. 00085 //////////////////////////////////////////////////////////////////// 00086 INLINE bool GeomVertexArrayData:: 00087 set_num_rows(int n) { 00088 return modify_handle()->set_num_rows(n); 00089 } 00090 00091 //////////////////////////////////////////////////////////////////// 00092 // Function: GeomVertexArrayData::unclean_set_num_rows 00093 // Access: Published 00094 // Description: This method behaves like set_num_rows(), except the 00095 // new data is not initialized. Furthermore, after this 00096 // call, *any* of the data in the GeomVertexArrayData 00097 // may be uninitialized, including the earlier rows. 00098 // 00099 // Normally, you would not call this directly, since all 00100 // of the arrays in a particular GeomVertexData must 00101 // have the same number of rows; instead, call 00102 // GeomVertexData::unclean_set_num_rows(). 00103 //////////////////////////////////////////////////////////////////// 00104 INLINE bool GeomVertexArrayData:: 00105 unclean_set_num_rows(int n) { 00106 return modify_handle()->unclean_set_num_rows(n); 00107 } 00108 00109 //////////////////////////////////////////////////////////////////// 00110 // Function: GeomVertexArrayData::reserve_num_rows 00111 // Access: Published 00112 // Description: This ensures that enough memory space for n rows is 00113 // allocated, so that you may increase the number of 00114 // rows to n without causing a new memory allocation. 00115 // This is a performance optimization only; it is 00116 // especially useful when you know ahead of time that 00117 // you will be adding n rows to the data. 00118 //////////////////////////////////////////////////////////////////// 00119 INLINE bool GeomVertexArrayData:: 00120 reserve_num_rows(int n) { 00121 return modify_handle()->reserve_num_rows(n); 00122 } 00123 00124 //////////////////////////////////////////////////////////////////// 00125 // Function: GeomVertexArrayData::clear_rows 00126 // Access: Published 00127 // Description: Removes all of the rows in the array. 00128 // Functionally equivalent to set_num_rows(0). 00129 //////////////////////////////////////////////////////////////////// 00130 INLINE void GeomVertexArrayData:: 00131 clear_rows() { 00132 return modify_handle()->clear_rows(); 00133 } 00134 00135 //////////////////////////////////////////////////////////////////// 00136 // Function: GeomVertexArrayData::get_data_size_bytes 00137 // Access: Published 00138 // Description: Returns the number of bytes stored in the array. 00139 //////////////////////////////////////////////////////////////////// 00140 INLINE int GeomVertexArrayData:: 00141 get_data_size_bytes() const { 00142 CDReader cdata(_cycler); 00143 return cdata->_buffer.get_size(); 00144 } 00145 00146 //////////////////////////////////////////////////////////////////// 00147 // Function: GeomVertexArrayData::get_modified 00148 // Access: Published 00149 // Description: Returns a sequence number which is guaranteed to 00150 // change at least every time the array vertex data is 00151 // modified. 00152 //////////////////////////////////////////////////////////////////// 00153 INLINE UpdateSeq GeomVertexArrayData:: 00154 get_modified() const { 00155 CDReader cdata(_cycler); 00156 return cdata->_modified; 00157 } 00158 00159 //////////////////////////////////////////////////////////////////// 00160 // Function: GeomVertexArrayData::request_resident 00161 // Access: Published 00162 // Description: Returns true if the vertex data is currently resident 00163 // in memory. If this returns true, the next call to 00164 // get_handle()->get_read_pointer() will probably not 00165 // block. If this returns false, the vertex data will 00166 // be brought back into memory shortly; try again later. 00167 //////////////////////////////////////////////////////////////////// 00168 INLINE bool GeomVertexArrayData:: 00169 request_resident() const { 00170 CPT(GeomVertexArrayDataHandle) handle = get_handle(); 00171 return handle->request_resident(); 00172 } 00173 00174 //////////////////////////////////////////////////////////////////// 00175 // Function: GeomVertexArrayData::get_handle 00176 // Access: Published 00177 // Description: Returns an object that can be used to read the actual 00178 // data bytes stored in the array. Calling this method 00179 // locks the data, and will block any other threads 00180 // attempting to read or write the data, until the 00181 // returned object destructs. 00182 //////////////////////////////////////////////////////////////////// 00183 INLINE CPT(GeomVertexArrayDataHandle) GeomVertexArrayData:: 00184 get_handle(Thread *current_thread) const { 00185 const CData *cdata = _cycler.read_unlocked(current_thread); 00186 return new GeomVertexArrayDataHandle(this, current_thread, 00187 cdata, false); 00188 } 00189 00190 //////////////////////////////////////////////////////////////////// 00191 // Function: GeomVertexArrayData::modify_handle 00192 // Access: Published 00193 // Description: Returns an object that can be used to read or write 00194 // the actual data bytes stored in the array. Calling 00195 // this method locks the data, and will block any other 00196 // threads attempting to read or write the data, until 00197 // the returned object destructs. 00198 //////////////////////////////////////////////////////////////////// 00199 INLINE PT(GeomVertexArrayDataHandle) GeomVertexArrayData:: 00200 modify_handle(Thread *current_thread) { 00201 CData *cdata = _cycler.write_upstream(true, current_thread); 00202 return new GeomVertexArrayDataHandle(this, current_thread, 00203 cdata, true); 00204 } 00205 00206 //////////////////////////////////////////////////////////////////// 00207 // Function: GeomVertexArrayData::get_independent_lru 00208 // Access: Published, Static 00209 // Description: Returns a pointer to the global LRU object that 00210 // manages the GeomVertexArrayData's that have not (yet) 00211 // been paged out. 00212 //////////////////////////////////////////////////////////////////// 00213 INLINE SimpleLru *GeomVertexArrayData:: 00214 get_independent_lru() { 00215 return &_independent_lru; 00216 } 00217 00218 //////////////////////////////////////////////////////////////////// 00219 // Function: GeomVertexArrayData::get_small_lru 00220 // Access: Published, Static 00221 // Description: Returns a pointer to the global LRU object that 00222 // manages the GeomVertexArrayData's that are deemed too 00223 // small to be paged out. 00224 //////////////////////////////////////////////////////////////////// 00225 INLINE SimpleLru *GeomVertexArrayData:: 00226 get_small_lru() { 00227 return &_small_lru; 00228 } 00229 00230 //////////////////////////////////////////////////////////////////// 00231 // Function: GeomVertexArrayData::get_book 00232 // Access: Published, Static 00233 // Description: Returns the global VertexDataBook that will be 00234 // used to allocate vertex data buffers. 00235 //////////////////////////////////////////////////////////////////// 00236 INLINE VertexDataBook &GeomVertexArrayData:: 00237 get_book() { 00238 return _book; 00239 } 00240 00241 //////////////////////////////////////////////////////////////////// 00242 // Function: GeomVertexArrayData::set_lru_size 00243 // Access: Private 00244 // Description: Should be called when the size of the buffer changes. 00245 //////////////////////////////////////////////////////////////////// 00246 INLINE void GeomVertexArrayData:: 00247 set_lru_size(size_t lru_size) { 00248 SimpleLruPage::set_lru_size(lru_size); 00249 00250 if ((int)lru_size <= vertex_data_small_size) { 00251 SimpleLruPage::mark_used_lru(&_small_lru); 00252 } else { 00253 SimpleLruPage::mark_used_lru(&_independent_lru); 00254 } 00255 } 00256 00257 //////////////////////////////////////////////////////////////////// 00258 // Function: GeomVertexArrayData::CData::Constructor 00259 // Access: Public 00260 // Description: 00261 //////////////////////////////////////////////////////////////////// 00262 INLINE GeomVertexArrayData::CData:: 00263 CData() : 00264 _usage_hint(UH_unspecified), 00265 _rw_lock("GeomVertexArrayData::CData::_rw_lock") 00266 { 00267 } 00268 00269 //////////////////////////////////////////////////////////////////// 00270 // Function: GeomVertexArrayData::CData::Copy Constructor 00271 // Access: Public 00272 // Description: 00273 //////////////////////////////////////////////////////////////////// 00274 INLINE GeomVertexArrayData::CData:: 00275 CData(const GeomVertexArrayData::CData ©) : 00276 _usage_hint(copy._usage_hint), 00277 _buffer(copy._buffer), 00278 _modified(copy._modified), 00279 _rw_lock("GeomVertexArrayData::CData::_rw_lock") 00280 { 00281 } 00282 00283 //////////////////////////////////////////////////////////////////// 00284 // Function: GeomVertexArrayData::CData::Copy Assignment 00285 // Access: Public 00286 // Description: 00287 //////////////////////////////////////////////////////////////////// 00288 INLINE void GeomVertexArrayData::CData:: 00289 operator = (const GeomVertexArrayData::CData ©) { 00290 _usage_hint = copy._usage_hint; 00291 _buffer = copy._buffer; 00292 _modified = copy._modified; 00293 } 00294 00295 //////////////////////////////////////////////////////////////////// 00296 // Function: GeomVertexArrayDataHandle::Constructor 00297 // Access: Private 00298 // Description: 00299 //////////////////////////////////////////////////////////////////// 00300 INLINE GeomVertexArrayDataHandle:: 00301 GeomVertexArrayDataHandle(const GeomVertexArrayData *object, 00302 Thread *current_thread, 00303 const GeomVertexArrayData::CData *cdata, 00304 bool writable) : 00305 _object((GeomVertexArrayData *)object), 00306 _current_thread(current_thread), 00307 _cdata((GeomVertexArrayData::CData *)cdata), 00308 _writable(writable) 00309 { 00310 #ifdef _DEBUG 00311 nassertv(_object->test_ref_count_nonzero()); 00312 #endif // _DEBUG 00313 #ifdef DO_PIPELINING 00314 _cdata->ref(); 00315 #endif // DO_PIPELINING 00316 // We must grab the lock *after* we have incremented the reference 00317 // count, above. 00318 _cdata->_rw_lock.acquire(); 00319 #ifdef DO_MEMORY_USAGE 00320 MemoryUsage::update_type(this, get_class_type()); 00321 #endif 00322 } 00323 00324 //////////////////////////////////////////////////////////////////// 00325 // Function: GeomVertexArrayDataHandle::Copy Constructor 00326 // Access: Private 00327 // Description: Don't attempt to copy these objects. 00328 //////////////////////////////////////////////////////////////////// 00329 INLINE GeomVertexArrayDataHandle:: 00330 GeomVertexArrayDataHandle(const GeomVertexArrayDataHandle ©) { 00331 nassertv(false); 00332 } 00333 00334 //////////////////////////////////////////////////////////////////// 00335 // Function: GeomVertexArrayDataHandle::Copy Assignment Operator 00336 // Access: Private 00337 // Description: Don't attempt to copy these objects. 00338 //////////////////////////////////////////////////////////////////// 00339 INLINE void GeomVertexArrayDataHandle:: 00340 operator = (const GeomVertexArrayDataHandle &) { 00341 nassertv(false); 00342 } 00343 00344 //////////////////////////////////////////////////////////////////// 00345 // Function: GeomVertexArrayDataHandle::Destructor 00346 // Access: Public 00347 // Description: 00348 //////////////////////////////////////////////////////////////////// 00349 INLINE GeomVertexArrayDataHandle:: 00350 ~GeomVertexArrayDataHandle() { 00351 #ifdef _DEBUG 00352 nassertv(_object->test_ref_count_nonzero()); 00353 #endif // _DEBUG 00354 00355 if (_writable) { 00356 _object->_cycler.release_write(_cdata); 00357 } 00358 00359 // We must release the lock *before* we decrement the reference 00360 // count, below. 00361 _cdata->_rw_lock.release(); 00362 00363 #ifdef DO_PIPELINING 00364 unref_delete((CycleData *)_cdata); 00365 #endif // DO_PIPELINING 00366 00367 #ifdef _DEBUG 00368 _object = NULL; 00369 _cdata = NULL; 00370 #endif // _DEBUG 00371 } 00372 00373 //////////////////////////////////////////////////////////////////// 00374 // Function: GeomVertexArrayDataHandle::get_current_thread 00375 // Access: Public 00376 // Description: 00377 //////////////////////////////////////////////////////////////////// 00378 INLINE Thread *GeomVertexArrayDataHandle:: 00379 get_current_thread() const { 00380 return _current_thread; 00381 } 00382 00383 //////////////////////////////////////////////////////////////////// 00384 // Function: GeomVertexArrayDataHandle::get_read_pointer 00385 // Access: Public 00386 // Description: Returns a readable pointer to the beginning of the 00387 // actual data stream, or NULL if the data is not 00388 // currently resident. If the data is not currently 00389 // resident, this will implicitly request it to become 00390 // resident soon. 00391 // 00392 // If force is true, this method will never return NULL, 00393 // but may block until the data is available. 00394 //////////////////////////////////////////////////////////////////// 00395 INLINE const unsigned char *GeomVertexArrayDataHandle:: 00396 get_read_pointer(bool force) const { 00397 mark_used(); 00398 return _cdata->_buffer.get_read_pointer(force); 00399 } 00400 00401 //////////////////////////////////////////////////////////////////// 00402 // Function: GeomVertexArrayDataHandle::get_object 00403 // Access: Published 00404 // Description: 00405 //////////////////////////////////////////////////////////////////// 00406 INLINE const GeomVertexArrayData *GeomVertexArrayDataHandle:: 00407 get_object() const { 00408 return _object; 00409 } 00410 00411 //////////////////////////////////////////////////////////////////// 00412 // Function: GeomVertexArrayDataHandle::get_object 00413 // Access: Published 00414 // Description: 00415 //////////////////////////////////////////////////////////////////// 00416 INLINE GeomVertexArrayData *GeomVertexArrayDataHandle:: 00417 get_object() { 00418 return _object; 00419 } 00420 00421 //////////////////////////////////////////////////////////////////// 00422 // Function: GeomVertexArrayDataHandle::get_array_format 00423 // Access: Published 00424 // Description: 00425 //////////////////////////////////////////////////////////////////// 00426 INLINE const GeomVertexArrayFormat *GeomVertexArrayDataHandle:: 00427 get_array_format() const { 00428 return _object->_array_format; 00429 } 00430 00431 //////////////////////////////////////////////////////////////////// 00432 // Function: GeomVertexArrayDataHandle::get_usage_hint 00433 // Access: Published 00434 // Description: 00435 //////////////////////////////////////////////////////////////////// 00436 INLINE GeomVertexArrayDataHandle::UsageHint GeomVertexArrayDataHandle:: 00437 get_usage_hint() const { 00438 return _cdata->_usage_hint; 00439 } 00440 00441 //////////////////////////////////////////////////////////////////// 00442 // Function: GeomVertexArrayDataHandle::get_num_rows 00443 // Access: Published 00444 // Description: 00445 //////////////////////////////////////////////////////////////////// 00446 INLINE int GeomVertexArrayDataHandle:: 00447 get_num_rows() const { 00448 return get_data_size_bytes() / _object->_array_format->get_stride(); 00449 } 00450 00451 //////////////////////////////////////////////////////////////////// 00452 // Function: GeomVertexArrayDataHandle::clear_rows 00453 // Access: Published 00454 // Description: 00455 //////////////////////////////////////////////////////////////////// 00456 INLINE void GeomVertexArrayDataHandle:: 00457 clear_rows() { 00458 set_num_rows(0); 00459 } 00460 00461 //////////////////////////////////////////////////////////////////// 00462 // Function: GeomVertexArrayDataHandle::get_data_size_bytes 00463 // Access: Published 00464 // Description: 00465 //////////////////////////////////////////////////////////////////// 00466 INLINE int GeomVertexArrayDataHandle:: 00467 get_data_size_bytes() const { 00468 return _cdata->_buffer.get_size(); 00469 } 00470 00471 //////////////////////////////////////////////////////////////////// 00472 // Function: GeomVertexArrayDataHandle::get_modified 00473 // Access: Published 00474 // Description: 00475 //////////////////////////////////////////////////////////////////// 00476 INLINE UpdateSeq GeomVertexArrayDataHandle:: 00477 get_modified() const { 00478 return _cdata->_modified; 00479 } 00480 00481 //////////////////////////////////////////////////////////////////// 00482 // Function: GeomVertexArrayData::request_resident 00483 // Access: Published 00484 // Description: Returns true if the vertex data is currently resident 00485 // in memory. If this returns true, the next call to 00486 // get_handle()->get_read_pointer() will probably not 00487 // block. If this returns false, the vertex data will 00488 // be brought back into memory shortly; try again later. 00489 //////////////////////////////////////////////////////////////////// 00490 INLINE bool GeomVertexArrayDataHandle:: 00491 request_resident() const { 00492 return (get_read_pointer(false) != (const unsigned char *)NULL); 00493 } 00494 00495 //////////////////////////////////////////////////////////////////// 00496 // Function: GeomVertexArrayDataHandle::get_data 00497 // Access: Published 00498 // Description: Returns the entire raw data of the 00499 // GeomVertexArrayData object, formatted as a string. 00500 // This is primarily for the benefit of high-level 00501 // languages such as Python. 00502 //////////////////////////////////////////////////////////////////// 00503 INLINE string GeomVertexArrayDataHandle:: 00504 get_data() const { 00505 mark_used(); 00506 return string((const char *)_cdata->_buffer.get_read_pointer(true), _cdata->_buffer.get_size()); 00507 } 00508 00509 //////////////////////////////////////////////////////////////////// 00510 // Function: GeomVertexArrayDataHandle::get_subdata 00511 // Access: Published 00512 // Description: Returns a subset of the raw data of the 00513 // GeomVertexArrayData object, formatted as a string. 00514 // This is primarily for the benefit of high-level 00515 // languages such as Python. 00516 //////////////////////////////////////////////////////////////////// 00517 INLINE string GeomVertexArrayDataHandle:: 00518 get_subdata(size_t start, size_t size) const { 00519 mark_used(); 00520 start = min(start, _cdata->_buffer.get_size()); 00521 size = min(size, _cdata->_buffer.get_size() - start); 00522 return string((const char *)_cdata->_buffer.get_read_pointer(true) + start, size); 00523 } 00524 00525 //////////////////////////////////////////////////////////////////// 00526 // Function: GeomVertexArrayDataHandle::mark_used 00527 // Access: Published 00528 // Description: Marks the array data recently-used. 00529 //////////////////////////////////////////////////////////////////// 00530 void GeomVertexArrayDataHandle:: 00531 mark_used() const { 00532 _object->set_lru_size(_object->get_lru_size()); 00533 } 00534 00535 INLINE ostream & 00536 operator << (ostream &out, const GeomVertexArrayData &obj) { 00537 obj.output(out); 00538 return out; 00539 }