Panda3D
 All Classes Functions Variables Enumerations
geomCacheManager.cxx
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 }
 All Classes Functions Variables Enumerations