Panda3D

vertexDataPage.I

00001 // Filename: vertexDataPage.I
00002 // Created by:  drose (04Jun07)
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: VertexDataPage::get_ram_class
00018 //       Access: Published
00019 //  Description: Returns the current ram class of the array.  If this
00020 //               is other than RC_resident, the array data is not
00021 //               resident in memory.
00022 ////////////////////////////////////////////////////////////////////
00023 INLINE VertexDataPage::RamClass VertexDataPage::
00024 get_ram_class() const {
00025   MutexHolder holder(_lock);
00026   return _ram_class;
00027 }
00028 
00029 ////////////////////////////////////////////////////////////////////
00030 //     Function: VertexDataPage::get_pending_ram_class
00031 //       Access: Published
00032 //  Description: Returns the pending ram class of the array.  If this
00033 //               is different from get_ram_class(), this page has been
00034 //               queued to be processed by the thread.  Eventually the
00035 //               page will be set to this ram class.
00036 ////////////////////////////////////////////////////////////////////
00037 INLINE VertexDataPage::RamClass VertexDataPage::
00038 get_pending_ram_class() const {
00039   MutexHolder holder(_lock);
00040   return _pending_ram_class;
00041 }
00042 
00043 ////////////////////////////////////////////////////////////////////
00044 //     Function: VertexDataPage::request_resident
00045 //       Access: Published
00046 //  Description: Ensures that the page will become resident soon.
00047 //               Future calls to get_page_data() will eventually
00048 //               return non-NULL.
00049 ////////////////////////////////////////////////////////////////////
00050 INLINE void VertexDataPage::
00051 request_resident() {
00052   MutexHolder holder(_lock);
00053   if (_ram_class != RC_resident) {
00054     request_ram_class(RC_resident);
00055   }
00056 }
00057 
00058 ////////////////////////////////////////////////////////////////////
00059 //     Function: VertexDataPage::alloc
00060 //       Access: Published
00061 //  Description: Allocates a new block.  Returns NULL if a block of the
00062 //               requested size cannot be allocated.
00063 //
00064 //               To free the allocated block, call block->free(), or
00065 //               simply delete the block pointer.
00066 ////////////////////////////////////////////////////////////////////
00067 INLINE VertexDataBlock *VertexDataPage::
00068 alloc(size_t size) {
00069   MutexHolder holder(_lock);
00070   return do_alloc(size);
00071 }
00072 
00073 ////////////////////////////////////////////////////////////////////
00074 //     Function: VertexDataPage::get_first_block
00075 //       Access: Published
00076 //  Description: Returns a pointer to the first allocated block, or
00077 //               NULL if there are no allocated blocks.
00078 ////////////////////////////////////////////////////////////////////
00079 INLINE VertexDataBlock *VertexDataPage::
00080 get_first_block() const {
00081   MutexHolder holder(_lock);
00082   return (VertexDataBlock *)SimpleAllocator::get_first_block();
00083 }
00084 
00085 ////////////////////////////////////////////////////////////////////
00086 //     Function: VertexDataPage::get_book
00087 //       Access: Published
00088 //  Description: Returns a pointer to the book that owns this page.
00089 ////////////////////////////////////////////////////////////////////
00090 INLINE VertexDataBook *VertexDataPage::
00091 get_book() const {
00092   return _book;
00093 }
00094 
00095 ////////////////////////////////////////////////////////////////////
00096 //     Function: VertexDataPage::get_global_lru
00097 //       Access: Published, Static
00098 //  Description: Returns a pointer to the global LRU object that
00099 //               manages the VertexDataPage's with the indicated
00100 //               RamClass.
00101 ////////////////////////////////////////////////////////////////////
00102 INLINE SimpleLru *VertexDataPage::
00103 get_global_lru(RamClass rclass) {
00104   nassertr(rclass >= 0 && rclass < RC_end_of_list, NULL);
00105   return _global_lru[rclass];
00106 }
00107 
00108 ////////////////////////////////////////////////////////////////////
00109 //     Function: VertexDataPage::get_pending_lru
00110 //       Access: Published, Static
00111 //  Description: Returns a pointer to the global LRU object that
00112 //               manages the VertexDataPage's that are pending
00113 //               processing by the thread.
00114 ////////////////////////////////////////////////////////////////////
00115 INLINE SimpleLru *VertexDataPage::
00116 get_pending_lru() {
00117   return &_pending_lru;
00118 }
00119 
00120 ////////////////////////////////////////////////////////////////////
00121 //     Function: VertexDataPage::get_save_file
00122 //       Access: Published, Static
00123 //  Description: Returns the global VertexDataSaveFile that will be
00124 //               used to save vertex data buffers to disk when
00125 //               necessary.
00126 ////////////////////////////////////////////////////////////////////
00127 INLINE VertexDataSaveFile *VertexDataPage::
00128 get_save_file() {
00129   if (_save_file == (VertexDataSaveFile *)NULL) {
00130     make_save_file();
00131   }
00132   return _save_file;
00133 }
00134 
00135 ////////////////////////////////////////////////////////////////////
00136 //     Function: VertexDataPage::save_to_disk
00137 //       Access: Published
00138 //  Description: Writes the page to disk, but does not evict it from
00139 //               memory or affect its LRU status.  If it gets evicted
00140 //               later without having been modified, it will not need
00141 //               to write itself to disk again.
00142 ////////////////////////////////////////////////////////////////////
00143 INLINE bool VertexDataPage::
00144 save_to_disk() {
00145   MutexHolder holder(_lock);
00146   return do_save_to_disk();
00147 }
00148 
00149 ////////////////////////////////////////////////////////////////////
00150 //     Function: VertexDataPage::get_num_threads
00151 //       Access: Published, Static
00152 //  Description: Returns the number of threads that have been spawned
00153 //               to service vertex paging requests, or 0 if no threads
00154 //               have been spawned (which may mean either that all
00155 //               paging requests will be handled by the main thread,
00156 //               or simply that no paging requests have yet been
00157 //               issued).
00158 ////////////////////////////////////////////////////////////////////
00159 INLINE int VertexDataPage::
00160 get_num_threads() {
00161   MutexHolder holder(_tlock);
00162   if (_thread_mgr == (PageThreadManager *)NULL) {
00163     return 0;
00164   }
00165   return _thread_mgr->get_num_threads();
00166 }
00167 
00168 ////////////////////////////////////////////////////////////////////
00169 //     Function: VertexDataPage::get_num_pending_reads
00170 //       Access: Published, Static
00171 //  Description: Returns the number of read requests that are waiting
00172 //               to be serviced by a thread.
00173 ////////////////////////////////////////////////////////////////////
00174 INLINE int VertexDataPage::
00175 get_num_pending_reads() {
00176   MutexHolder holder(_tlock);
00177   if (_thread_mgr == (PageThreadManager *)NULL) {
00178     return 0;
00179   }
00180   return _thread_mgr->get_num_pending_reads();
00181 }
00182 
00183 ////////////////////////////////////////////////////////////////////
00184 //     Function: VertexDataPage::get_num_pending_writes
00185 //       Access: Published, Static
00186 //  Description: Returns the number of write requests that are waiting
00187 //               to be serviced by a thread.
00188 ////////////////////////////////////////////////////////////////////
00189 INLINE int VertexDataPage::
00190 get_num_pending_writes() {
00191   MutexHolder holder(_tlock);
00192   if (_thread_mgr == (PageThreadManager *)NULL) {
00193     return 0;
00194   }
00195   return _thread_mgr->get_num_pending_writes();
00196 }
00197 
00198 ////////////////////////////////////////////////////////////////////
00199 //     Function: VertexDataPage::get_page_data
00200 //       Access: Public
00201 //  Description: Returns a pointer to the page's data area, or NULL if
00202 //               the page is not currently resident.  If the page is
00203 //               not currently resident, this will implicitly request
00204 //               it to become resident soon.
00205 //
00206 //               If force is true, this method will never return NULL,
00207 //               but may block until the page is available.
00208 ////////////////////////////////////////////////////////////////////
00209 INLINE unsigned char *VertexDataPage::
00210 get_page_data(bool force) {
00211   MutexHolder holder(_lock);
00212   if (_ram_class != RC_resident || _pending_ram_class != RC_resident) {
00213     if (force) {
00214       make_resident_now();
00215     } else {
00216       request_ram_class(RC_resident);
00217       if (_ram_class != RC_resident) {
00218         return NULL;
00219       }
00220     }
00221   }
00222 
00223   mark_used_lru();
00224   nassertr(_size == _uncompressed_size, _page_data);
00225   return _page_data;
00226 }
00227 
00228 ////////////////////////////////////////////////////////////////////
00229 //     Function: VertexDataPage::operator
00230 //       Access: Public
00231 //  Description: This comparison method is used to order pages within
00232 //               a book.
00233 ////////////////////////////////////////////////////////////////////
00234 INLINE bool VertexDataPage::
00235 operator < (const VertexDataPage &other) const {
00236   // We sort pages so that the pages with the smallest number of
00237   // available contiguous bytes come up first.  We store our best
00238   // estimate of continguous bytes here.
00239   if (_book_size != other._book_size) {
00240     return _book_size < other._book_size;
00241   }
00242 
00243   // For pages of equal size, we sort based on pointers, to make it
00244   // easy to quickly find a specific page.
00245   return this < &other;
00246 }
00247 
00248 ////////////////////////////////////////////////////////////////////
00249 //     Function: VertexDataPage::set_ram_class
00250 //       Access: Private
00251 //  Description: Puts the data in a new ram class.  Assumes the page
00252 //               lock is already held.
00253 ////////////////////////////////////////////////////////////////////
00254 INLINE void VertexDataPage::
00255 set_ram_class(RamClass rclass) {
00256   _ram_class = rclass;
00257   mark_used_lru(_global_lru[rclass]);
00258 
00259   // Changing the ram class might make our effective available space 0
00260   // and thereby change the placement within the book.
00261   adjust_book_size();
00262 }
00263 
00264 ////////////////////////////////////////////////////////////////////
00265 //     Function: VertexDataPage::round_up
00266 //       Access: Private
00267 //  Description: Round page_size up to the next multiple of
00268 //               _block_size.
00269 ////////////////////////////////////////////////////////////////////
00270 INLINE size_t VertexDataPage::
00271 round_up(size_t page_size) const {
00272   return ((page_size + _block_size - 1) / _block_size) * _block_size;
00273 }
 All Classes Functions Variables Enumerations