]> git.mxchange.org Git - simgear.git/commitdiff
Thorsten Renk's fix for tile manager problems
authorTim Moore <timoore33@gmail.com>
Sat, 2 Oct 2010 21:00:59 +0000 (23:00 +0200)
committerTim Moore <timoore33@gmail.com>
Sat, 2 Oct 2010 21:05:52 +0000 (23:05 +0200)
Locking tiles in cache keeps tiles from mysteriously disappearing.

simgear/scene/tgdb/TileCache.cxx
simgear/scene/tgdb/TileCache.hxx
simgear/scene/tgdb/TileEntry.cxx
simgear/scene/tgdb/TileEntry.hxx

index 1d34fd8df06ff04ebfa457ff1a02b42dca2aff80..390e52d5c87aa27aaa7c62807f4ee46f15a7ab62 100644 (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 );
         }
     }
 }
index adcaacf7ddb28922be73452f0af59b99cf11e841..f427c2bfd5ba8b68c6dd090976038d6c1c47d3e0 100644 (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 );
index dae9ed26f53b25f519af7a30c1284e06a37744ed..ffe5935229aa44d75a31ea34b44cd3110e85f889 100644 (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
index e22ae643f67362af7d3d07f173bd164d9e40d895..924b566624075bd08007647e7436634839f61f53 100644 (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.