Panda3D
|
00001 // Filename: geomCacheManager.cxx 00002 // Created by: drose (11Mar05) 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 "geomCacheManager.h" 00016 #include "geomCacheEntry.h" 00017 #include "lightMutexHolder.h" 00018 00019 GeomCacheManager *GeomCacheManager::_global_ptr = NULL; 00020 00021 PStatCollector GeomCacheManager::_geom_cache_size_pcollector("Geom cache size"); 00022 PStatCollector GeomCacheManager::_geom_cache_active_pcollector("Geom cache size:Active"); 00023 PStatCollector GeomCacheManager::_geom_cache_record_pcollector("Geom cache operations:record"); 00024 PStatCollector GeomCacheManager::_geom_cache_erase_pcollector("Geom cache operations:erase"); 00025 PStatCollector GeomCacheManager::_geom_cache_evict_pcollector("Geom cache operations:evict"); 00026 00027 //////////////////////////////////////////////////////////////////// 00028 // Function: GeomCacheManager::Constructor 00029 // Access: Protected 00030 // Description: 00031 //////////////////////////////////////////////////////////////////// 00032 GeomCacheManager:: 00033 GeomCacheManager() : 00034 _lock("GeomCacheManager"), 00035 _total_size(0) 00036 { 00037 // We deliberately hang on to this pointer forever. 00038 _list = new GeomCacheEntry; 00039 _list->ref(); 00040 _list->_next = _list; 00041 _list->_prev = _list; 00042 } 00043 00044 //////////////////////////////////////////////////////////////////// 00045 // Function: GeomCacheManager::Destructor 00046 // Access: Protected 00047 // Description: 00048 //////////////////////////////////////////////////////////////////// 00049 GeomCacheManager:: 00050 ~GeomCacheManager() { 00051 // Shouldn't be deleting this global object. 00052 nassertv(false); 00053 } 00054 00055 //////////////////////////////////////////////////////////////////// 00056 // Function: GeomCacheManager::flush 00057 // Access: Published 00058 // Description: Immediately empties all elements in the cache. 00059 //////////////////////////////////////////////////////////////////// 00060 void GeomCacheManager:: 00061 flush() { 00062 LightMutexHolder holder(_lock); 00063 evict_old_entries(0, false); 00064 } 00065 00066 //////////////////////////////////////////////////////////////////// 00067 // Function: GeomCacheManager::get_global_ptr 00068 // Access: Published, Static 00069 // Description: Returns the global cache manager pointer. 00070 //////////////////////////////////////////////////////////////////// 00071 GeomCacheManager *GeomCacheManager:: 00072 get_global_ptr() { 00073 if (_global_ptr == (GeomCacheManager *)NULL) { 00074 _global_ptr = new GeomCacheManager; 00075 } 00076 return _global_ptr; 00077 } 00078 00079 //////////////////////////////////////////////////////////////////// 00080 // Function: GeomCacheManager::evict_old_entries 00081 // Access: Public 00082 // Description: Trims the cache size down to the specified size by 00083 // evicting old cache entries as needed. It is assumed 00084 // that you already hold the lock before calling this 00085 // method. 00086 //////////////////////////////////////////////////////////////////// 00087 void GeomCacheManager:: 00088 evict_old_entries(int max_size, bool keep_current) { 00089 int current_frame = ClockObject::get_global_clock()->get_frame_count(); 00090 int min_frames = geom_cache_min_frames; 00091 00092 while (_total_size > max_size) { 00093 PT(GeomCacheEntry) entry = _list->_next; 00094 nassertv(entry != _list); 00095 00096 if (keep_current && current_frame - entry->_last_frame_used < min_frames) { 00097 // Never mind, this one is too new. 00098 if (gobj_cat.is_debug()) { 00099 gobj_cat.debug() 00100 << "Oldest element in cache is " 00101 << current_frame - entry->_last_frame_used 00102 << " frames; keeping cache at " << _total_size << " entries.\n"; 00103 } 00104 break; 00105 } 00106 00107 entry->unref(); 00108 00109 if (gobj_cat.is_debug()) { 00110 gobj_cat.debug() 00111 << "cache total_size = " << _total_size << " entries, max_size = " 00112 << max_size << ", removing " << *entry << "\n"; 00113 } 00114 00115 entry->evict_callback(); 00116 00117 if (PStatClient::is_connected()) { 00118 if (entry->_last_frame_used == current_frame) { 00119 GeomCacheManager::_geom_cache_active_pcollector.sub_level(1); 00120 } 00121 } 00122 00123 --_total_size; 00124 entry->remove_from_list(); 00125 _geom_cache_evict_pcollector.add_level(1); 00126 } 00127 _geom_cache_size_pcollector.set_level(_total_size); 00128 }