Panda3D
|
00001 // Filename: vertexDataBook.cxx 00002 // Created by: drose (16May07) 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 "vertexDataBook.h" 00016 #include "mutexHolder.h" 00017 00018 //////////////////////////////////////////////////////////////////// 00019 // Function: VertexDataBook::Constructor 00020 // Access: Published 00021 // Description: 00022 //////////////////////////////////////////////////////////////////// 00023 VertexDataBook:: 00024 VertexDataBook(size_t block_size) { 00025 // Make sure the block_size is an integer multiple of the system's 00026 // page size. 00027 _block_size = memory_hook->round_up_to_page_size(block_size); 00028 } 00029 00030 //////////////////////////////////////////////////////////////////// 00031 // Function: VertexDataBook::Destructor 00032 // Access: Published 00033 // Description: 00034 //////////////////////////////////////////////////////////////////// 00035 VertexDataBook:: 00036 ~VertexDataBook() { 00037 } 00038 00039 //////////////////////////////////////////////////////////////////// 00040 // Function: VertexDataBook::count_total_page_size 00041 // Access: Published 00042 // Description: Returns the total size of all bytes owned by all 00043 // pages owned by this book. 00044 //////////////////////////////////////////////////////////////////// 00045 size_t VertexDataBook:: 00046 count_total_page_size() const { 00047 MutexHolder holder(_lock); 00048 00049 size_t total = 0; 00050 Pages::const_iterator pi; 00051 for (pi = _pages.begin(); pi != _pages.end(); ++pi) { 00052 total += (*pi)->get_max_size(); 00053 } 00054 return total; 00055 } 00056 00057 //////////////////////////////////////////////////////////////////// 00058 // Function: VertexDataBook::count_total_page_size 00059 // Access: Published 00060 // Description: Returns the total size of all bytes owned by all 00061 // pages owned by this book that have the indicated ram 00062 // class. 00063 //////////////////////////////////////////////////////////////////// 00064 size_t VertexDataBook:: 00065 count_total_page_size(VertexDataPage::RamClass ram_class) const { 00066 MutexHolder holder(_lock); 00067 00068 size_t total = 0; 00069 Pages::const_iterator pi; 00070 for (pi = _pages.begin(); pi != _pages.end(); ++pi) { 00071 if ((*pi)->get_ram_class() == ram_class) { 00072 total += (*pi)->get_max_size(); 00073 } 00074 } 00075 return total; 00076 } 00077 00078 //////////////////////////////////////////////////////////////////// 00079 // Function: VertexDataBook::count_allocated_size 00080 // Access: Published 00081 // Description: Returns the total size of all bytes allocated within 00082 // pages owned by this book. 00083 //////////////////////////////////////////////////////////////////// 00084 size_t VertexDataBook:: 00085 count_allocated_size() const { 00086 MutexHolder holder(_lock); 00087 00088 size_t total = 0; 00089 Pages::const_iterator pi; 00090 for (pi = _pages.begin(); pi != _pages.end(); ++pi) { 00091 total += (*pi)->get_total_size(); 00092 } 00093 return total; 00094 } 00095 00096 //////////////////////////////////////////////////////////////////// 00097 // Function: VertexDataBook::count_allocated_size 00098 // Access: Published 00099 // Description: Returns the total size of all bytes allocated within 00100 // pages owned by this book that have the indicated ram 00101 // class. 00102 //////////////////////////////////////////////////////////////////// 00103 size_t VertexDataBook:: 00104 count_allocated_size(VertexDataPage::RamClass ram_class) const { 00105 MutexHolder holder(_lock); 00106 00107 size_t total = 0; 00108 Pages::const_iterator pi; 00109 for (pi = _pages.begin(); pi != _pages.end(); ++pi) { 00110 if ((*pi)->get_ram_class() == ram_class) { 00111 total += (*pi)->get_total_size(); 00112 } 00113 } 00114 return total; 00115 } 00116 00117 //////////////////////////////////////////////////////////////////// 00118 // Function: VertexDataBook::save_to_disk 00119 // Access: Published 00120 // Description: Writes all pages to disk immediately, just in case 00121 // they get evicted later. It makes sense to make this 00122 // call just before taking down a loading screen, to 00123 // minimize chugs from saving pages inadvertently later. 00124 //////////////////////////////////////////////////////////////////// 00125 void VertexDataBook:: 00126 save_to_disk() { 00127 MutexHolder holder(_lock); 00128 00129 Pages::iterator pi; 00130 for (pi = _pages.begin(); pi != _pages.end(); ++pi) { 00131 (*pi)->save_to_disk(); 00132 } 00133 } 00134 00135 00136 //////////////////////////////////////////////////////////////////// 00137 // Function: VertexDataBook::do_alloc 00138 // Access: Private 00139 // Description: Allocates and returns a new VertexDataBuffer of the 00140 // requested size. 00141 // 00142 // Assumes the lock is already held. 00143 //////////////////////////////////////////////////////////////////// 00144 VertexDataBlock *VertexDataBook:: 00145 do_alloc(size_t size) { 00146 // Look for an empty page of the appropriate size. The _pages set 00147 // is sorted so that the pages with the smallest available blocks 00148 // are at the front. 00149 00150 // Create a dummy page to use to search the set. 00151 VertexDataPage size_page(size); 00152 Pages::iterator pi = _pages.lower_bound(&size_page); 00153 00154 // Now we can start from the first element of the set that is 00155 // possibly large enough to contain this block, and work up from 00156 // there. 00157 while (pi != _pages.end()) { 00158 Pages::iterator pnext = pi; 00159 ++pnext; 00160 00161 VertexDataPage *page = (*pi); 00162 00163 // Allocating a block may change the page's available contiguous 00164 // size, and thereby change its position in the set, invalidating 00165 // the iterator pi. This is why we've already computed pnext. 00166 VertexDataBlock *block = page->do_alloc(size); 00167 00168 if (block != (VertexDataBlock *)NULL) { 00169 // This page worked. 00170 return block; 00171 } 00172 00173 // Try the next page. 00174 pi = pnext; 00175 } 00176 00177 // No page was good enough. Create a new page. Make it at least 00178 // large enough to hold this requested block. 00179 VertexDataPage *page = create_new_page(size); 00180 _pages.insert(page); 00181 00182 VertexDataBlock *block = page->do_alloc(size); 00183 return block; 00184 }