Panda3D

vertexDataBuffer.cxx

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 &copy) {
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 }
 All Classes Functions Variables Enumerations