Thorsten Renk's fix for tile manager problems
Locking tiles in cache keeps tiles from mysteriously disappearing.
This commit is contained in:
@@ -98,6 +98,11 @@ long TileCache::get_oldest_tile() {
|
|||||||
for ( ; current != end; ++current ) {
|
for ( ; current != end; ++current ) {
|
||||||
long index = current->first;
|
long index = current->first;
|
||||||
TileEntry *e = current->second;
|
TileEntry *e = current->second;
|
||||||
|
if (e->get_cache_lock())
|
||||||
|
{
|
||||||
|
// tile locked to cache => must not be dropped
|
||||||
|
}
|
||||||
|
else
|
||||||
if ( e->is_loaded() ) {
|
if ( e->is_loaded() ) {
|
||||||
timestamp = e->get_timestamp();
|
timestamp = e->get_timestamp();
|
||||||
if ( timestamp < min_time ) {
|
if ( timestamp < min_time ) {
|
||||||
@@ -125,8 +130,27 @@ void TileCache::clear_inner_ring_flags() {
|
|||||||
|
|
||||||
for ( ; current != end; ++current ) {
|
for ( ; current != end; ++current ) {
|
||||||
TileEntry *e = current->second;
|
TileEntry *e = current->second;
|
||||||
if ( e->is_loaded() ) {
|
//if ( e->is_loaded() ) {
|
||||||
e->set_inner_ring( false );
|
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 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,6 +80,11 @@ public:
|
|||||||
// the external tile scheduler can flag the inner ring correctly.
|
// the external tile scheduler can flag the inner ring correctly.
|
||||||
void clear_inner_ring_flags();
|
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
|
// Clear a cache entry, note that the cache only holds pointers
|
||||||
// and this does not free the object which is pointed to.
|
// and this does not free the object which is pointed to.
|
||||||
void clear_entry( long cache_entry );
|
void clear_entry( long cache_entry );
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ osgDB::RegisterReaderWriterProxy<ReaderWriterSTG> g_readerWriterSTGProxy;
|
|||||||
ModelRegistryCallbackProxy<LoadOnlyCallback> g_stgCallbackProxy("stg");
|
ModelRegistryCallbackProxy<LoadOnlyCallback> g_stgCallbackProxy("stg");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_CULLCALLBACK_TS
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
// Update the timestamp on a tile whenever it is in view.
|
// 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();
|
_timeStamp = nv->getFrameStamp()->getReferenceTime();
|
||||||
traverse(node, nv);
|
traverse(node, nv);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
double TileEntry::get_timestamp() const
|
double TileEntry::get_timestamp() const
|
||||||
{
|
{
|
||||||
|
#ifdef USE_CULLCALLBACK_TS
|
||||||
if (_node.valid()) {
|
if (_node.valid()) {
|
||||||
return (dynamic_cast<TileCullCallback*>(_node->getCullCallback()))
|
return (dynamic_cast<TileCullCallback*>(_node->getCullCallback()))
|
||||||
->getTimeStamp();
|
->getTimeStamp();
|
||||||
} else
|
} else
|
||||||
return DBL_MAX;
|
return DBL_MAX;
|
||||||
|
#else
|
||||||
|
return timestamp;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void TileEntry::set_timestamp(double time_ms)
|
void TileEntry::set_timestamp(double time_ms)
|
||||||
{
|
{
|
||||||
|
#ifdef USE_CULLCALLBACK_TS
|
||||||
if (_node.valid()) {
|
if (_node.valid()) {
|
||||||
TileCullCallback* cb
|
TileCullCallback* cb
|
||||||
= dynamic_cast<TileCullCallback*>(_node->getCullCallback());
|
= dynamic_cast<TileCullCallback*>(_node->getCullCallback());
|
||||||
if (cb)
|
if (cb)
|
||||||
cb->setTimeStamp(time_ms);
|
cb->setTimeStamp(time_ms);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
timestamp = time_ms;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
@@ -117,8 +127,14 @@ TileEntry::TileEntry ( const SGBucket& b )
|
|||||||
tileFileName(b.gen_index_str()),
|
tileFileName(b.gen_index_str()),
|
||||||
_node( new osg::LOD ),
|
_node( new osg::LOD ),
|
||||||
is_inner_ring(false)
|
is_inner_ring(false)
|
||||||
|
,is_cache_locked(false)
|
||||||
|
#ifndef USE_CULLCALLBACK_TS
|
||||||
|
,timestamp(0.0)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
|
#ifdef USE_CULLCALLBACK_TS
|
||||||
_node->setCullCallback(new TileCullCallback);
|
_node->setCullCallback(new TileCullCallback);
|
||||||
|
#endif
|
||||||
tileFileName += ".stg";
|
tileFileName += ".stg";
|
||||||
_node->setName(tileFileName);
|
_node->setName(tileFileName);
|
||||||
// Give a default LOD range so that traversals that traverse
|
// Give a default LOD range so that traversals that traverse
|
||||||
|
|||||||
@@ -81,6 +81,8 @@ private:
|
|||||||
* inner ring. (For instance vasi color updating)
|
* inner ring. (For instance vasi color updating)
|
||||||
*/
|
*/
|
||||||
bool is_inner_ring;
|
bool is_inner_ring;
|
||||||
|
bool is_cache_locked;
|
||||||
|
double timestamp;
|
||||||
|
|
||||||
static ModelLoadHelper *_modelLoader;
|
static ModelLoadHelper *_modelLoader;
|
||||||
|
|
||||||
@@ -139,6 +141,8 @@ public:
|
|||||||
|
|
||||||
inline bool get_inner_ring() const { return is_inner_ring; }
|
inline bool get_inner_ring() const { return is_inner_ring; }
|
||||||
inline void set_inner_ring( bool val ) { is_inner_ring = val; }
|
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
|
// Get the ref_ptr to the DatabaseRequest object, in order to pass
|
||||||
// this to the pager.
|
// this to the pager.
|
||||||
|
|||||||
Reference in New Issue
Block a user