Thorsten Renk's fix for tile manager problems

Locking tiles in cache keeps tiles from mysteriously disappearing.
This commit is contained in:
Tim Moore
2010-10-02 23:00:59 +02:00
parent 82dc6c32ec
commit b5f3978b8a
4 changed files with 50 additions and 1 deletions

View File

@@ -98,6 +98,11 @@ long TileCache::get_oldest_tile() {
for ( ; current != end; ++current ) {
long index = current->first;
TileEntry *e = current->second;
if (e->get_cache_lock())
{
// tile locked to cache => must not be dropped
}
else
if ( e->is_loaded() ) {
timestamp = e->get_timestamp();
if ( timestamp < min_time ) {
@@ -125,8 +130,27 @@ void TileCache::clear_inner_ring_flags() {
for ( ; current != end; ++current ) {
TileEntry *e = current->second;
if ( e->is_loaded() ) {
//if ( e->is_loaded() ) {
e->set_inner_ring( false );
//}
}
}
// Clear all locked flags for all tiles in the cache.
// (Tiles belonging to the current position are locked to
// the cache to prevent them from being dropped).
void TileCache::clear_cache_lock_flags()
{
tile_map_iterator current = tile_cache.begin();
tile_map_iterator end = tile_cache.end();
for ( ; current != end; ++current ) {
TileEntry *e = current->second;
if (e->get_cache_lock())
{
// update timestamps for tiles belonging to most recent position
e->set_timestamp( current_time );
e->set_cache_lock( false );
}
}
}

View File

@@ -80,6 +80,11 @@ public:
// the external tile scheduler can flag the inner ring correctly.
void clear_inner_ring_flags();
// Clear all locked flags for all tiles in the cache.
// (Tiles belonging to the current position are locked to
// the cache to prevent them from being dropped).
void clear_cache_lock_flags();
// Clear a cache entry, note that the cache only holds pointers
// and this does not free the object which is pointed to.
void clear_entry( long cache_entry );

View File

@@ -64,6 +64,7 @@ osgDB::RegisterReaderWriterProxy<ReaderWriterSTG> g_readerWriterSTGProxy;
ModelRegistryCallbackProxy<LoadOnlyCallback> g_stgCallbackProxy("stg");
}
#ifdef USE_CULLCALLBACK_TS
namespace
{
// Update the timestamp on a tile whenever it is in view.
@@ -91,24 +92,33 @@ void TileCullCallback::operator()(osg::Node* node, osg::NodeVisitor* nv)
_timeStamp = nv->getFrameStamp()->getReferenceTime();
traverse(node, nv);
}
#endif
double TileEntry::get_timestamp() const
{
#ifdef USE_CULLCALLBACK_TS
if (_node.valid()) {
return (dynamic_cast<TileCullCallback*>(_node->getCullCallback()))
->getTimeStamp();
} else
return DBL_MAX;
#else
return timestamp;
#endif
}
void TileEntry::set_timestamp(double time_ms)
{
#ifdef USE_CULLCALLBACK_TS
if (_node.valid()) {
TileCullCallback* cb
= dynamic_cast<TileCullCallback*>(_node->getCullCallback());
if (cb)
cb->setTimeStamp(time_ms);
}
#else
timestamp = time_ms;
#endif
}
// Constructor
@@ -117,8 +127,14 @@ TileEntry::TileEntry ( const SGBucket& b )
tileFileName(b.gen_index_str()),
_node( new osg::LOD ),
is_inner_ring(false)
,is_cache_locked(false)
#ifndef USE_CULLCALLBACK_TS
,timestamp(0.0)
#endif
{
#ifdef USE_CULLCALLBACK_TS
_node->setCullCallback(new TileCullCallback);
#endif
tileFileName += ".stg";
_node->setName(tileFileName);
// Give a default LOD range so that traversals that traverse

View File

@@ -81,6 +81,8 @@ private:
* inner ring. (For instance vasi color updating)
*/
bool is_inner_ring;
bool is_cache_locked;
double timestamp;
static ModelLoadHelper *_modelLoader;
@@ -139,6 +141,8 @@ public:
inline bool get_inner_ring() const { return is_inner_ring; }
inline void set_inner_ring( bool val ) { is_inner_ring = val; }
inline void set_cache_lock( bool val ) { is_cache_locked = val; }
inline bool get_cache_lock() const { return is_cache_locked; }
// Get the ref_ptr to the DatabaseRequest object, in order to pass
// this to the pager.