Panda3D
|
00001 // Filename: vertexDataBuffer.cxx 00002 // Created by: drose (14May07) 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 #include "vertexDataBuffer.h" 00016 #include "pStatTimer.h" 00017 00018 TypeHandle VertexDataBuffer::_type_handle; 00019 00020 //////////////////////////////////////////////////////////////////// 00021 // Function: VertexDataBuffer::Copy Assignment Operator 00022 // Access: Public 00023 // Description: 00024 //////////////////////////////////////////////////////////////////// 00025 void VertexDataBuffer:: 00026 operator = (const VertexDataBuffer ©) { 00027 LightMutexHolder holder(_lock); 00028 LightMutexHolder holder2(copy._lock); 00029 00030 if (_resident_data != (unsigned char *)NULL) { 00031 nassertv(_size != 0); 00032 get_class_type().dec_memory_usage(TypeHandle::MC_array, (int)_size); 00033 PANDA_FREE_ARRAY(_resident_data); 00034 _resident_data = NULL; 00035 } 00036 if (copy._resident_data != (unsigned char *)NULL) { 00037 nassertv(copy._size != 0); 00038 get_class_type().inc_memory_usage(TypeHandle::MC_array, (int)copy._size); 00039 _resident_data = (unsigned char *)PANDA_MALLOC_ARRAY(copy._size); 00040 memcpy(_resident_data, copy._resident_data, copy._size); 00041 } 00042 _size = copy._size; 00043 _block = copy._block; 00044 } 00045 00046 //////////////////////////////////////////////////////////////////// 00047 // Function: VertexDataBuffer::do_clean_realloc 00048 // Access: Private 00049 // Description: Changes the size of the buffer, preserving its data 00050 // (except for any data beyond the new end of the 00051 // buffer, if the buffer is being reduced). If the 00052 // buffer is expanded, the new data is uninitialized. 00053 // 00054 // Assumes the lock is already held. 00055 //////////////////////////////////////////////////////////////////// 00056 void VertexDataBuffer:: 00057 do_clean_realloc(size_t size) { 00058 if (size != _size) { 00059 if (size == 0) { 00060 do_unclean_realloc(size); 00061 return; 00062 } 00063 00064 // Page in if we're currently paged out. 00065 if (_size != 0 && _resident_data == (unsigned char *)NULL) { 00066 do_page_in(); 00067 } 00068 00069 get_class_type().inc_memory_usage(TypeHandle::MC_array, (int)size - (int)_size); 00070 if (_size == 0) { 00071 nassertv(_resident_data == (unsigned char *)NULL); 00072 _resident_data = (unsigned char *)PANDA_MALLOC_ARRAY(size); 00073 } else { 00074 nassertv(_resident_data != (unsigned char *)NULL); 00075 _resident_data = (unsigned char *)PANDA_REALLOC_ARRAY(_resident_data, size); 00076 } 00077 nassertv(_resident_data != (unsigned char *)NULL); 00078 _size = size; 00079 } 00080 } 00081 00082 //////////////////////////////////////////////////////////////////// 00083 // Function: VertexDataBuffer::do_unclean_realloc 00084 // Access: Private 00085 // Description: Changes the size of the buffer, without regard to 00086 // preserving its data. The buffer may contain random 00087 // data after this call. 00088 // 00089 // Assumes the lock is already held. 00090 //////////////////////////////////////////////////////////////////// 00091 void VertexDataBuffer:: 00092 do_unclean_realloc(size_t size) { 00093 if (size != _size || _resident_data == (unsigned char *)NULL) { 00094 // If we're paged out, discard the page. 00095 _block = NULL; 00096 00097 if (_resident_data != (unsigned char *)NULL) { 00098 nassertv(_size != 0); 00099 00100 get_class_type().dec_memory_usage(TypeHandle::MC_array, (int)_size); 00101 PANDA_FREE_ARRAY(_resident_data); 00102 _resident_data = NULL; 00103 _size = 0; 00104 } 00105 00106 if (size != 0) { 00107 get_class_type().inc_memory_usage(TypeHandle::MC_array, (int)size); 00108 nassertv(_resident_data == (unsigned char *)NULL); 00109 _resident_data = (unsigned char *)PANDA_MALLOC_ARRAY(size); 00110 } 00111 00112 _size = size; 00113 } 00114 } 00115 00116 //////////////////////////////////////////////////////////////////// 00117 // Function: VertexDataBuffer::do_page_out 00118 // Access: Private 00119 // Description: Moves the buffer out of independent memory and puts 00120 // it on a page in the indicated book. The buffer may 00121 // still be directly accessible as long as its page 00122 // remains resident. Any subsequent attempt to rewrite 00123 // the buffer will implicitly move it off of the page 00124 // and back into independent memory. 00125 // 00126 // Assumes the lock is already held. 00127 //////////////////////////////////////////////////////////////////// 00128 void VertexDataBuffer:: 00129 do_page_out(VertexDataBook &book) { 00130 if (_block != (VertexDataBlock *)NULL || _size == 0) { 00131 // We're already paged out. 00132 return; 00133 } 00134 nassertv(_resident_data != (unsigned char *)NULL); 00135 00136 _block = book.alloc(_size); 00137 nassertv(_block != (VertexDataBlock *)NULL); 00138 unsigned char *pointer = _block->get_pointer(true); 00139 nassertv(pointer != (unsigned char *)NULL); 00140 memcpy(pointer, _resident_data, _size); 00141 00142 get_class_type().dec_memory_usage(TypeHandle::MC_array, (int)_size); 00143 PANDA_FREE_ARRAY(_resident_data); 00144 _resident_data = NULL; 00145 } 00146 00147 //////////////////////////////////////////////////////////////////// 00148 // Function: VertexDataBuffer::do_page_in 00149 // Access: Private 00150 // Description: Moves the buffer off of its current page and into 00151 // independent memory. If the page is not already 00152 // resident, it is forced resident first. 00153 // 00154 // Assumes the lock is already held. 00155 //////////////////////////////////////////////////////////////////// 00156 void VertexDataBuffer:: 00157 do_page_in() { 00158 if (_resident_data != (unsigned char *)NULL || _size == 0) { 00159 // We're already paged in. 00160 return; 00161 } 00162 00163 nassertv(_block != (VertexDataBlock *)NULL); 00164 00165 get_class_type().inc_memory_usage(TypeHandle::MC_array, (int)_size); 00166 _resident_data = (unsigned char *)PANDA_MALLOC_ARRAY(_size); 00167 nassertv(_resident_data != (unsigned char *)NULL); 00168 00169 memcpy(_resident_data, _block->get_pointer(true), _size); 00170 }