]> git.tdb.fi Git - libs/gl.git/commitdiff
Cache the total data size in ResourceManager
authorMikko Rasa <tdb@tdb.fi>
Fri, 4 Dec 2015 11:11:50 +0000 (13:11 +0200)
committerMikko Rasa <tdb@tdb.fi>
Fri, 4 Dec 2015 12:13:32 +0000 (14:13 +0200)
Calculating it again every frame turned out to be a fairly large
performance hit in applications with many different resources.

source/resource.h
source/resourcemanager.cpp
source/resourcemanager.h

index 01c604c3f6d41cf70bd7cf5bf20de501f3ec70ed..571d1ea56c54e61ab10c43ef0f10cce766f19bb3 100644 (file)
@@ -38,7 +38,11 @@ public:
        virtual int get_load_priority() const { return 0; }
        virtual AsyncLoader *load(IO::Seekable &, const Resources * = 0) = 0;
        virtual bool is_loaded() const;
+
+       /** Returns the amount of graphics memory used by this resource.  The
+       returned value must not change while the resource is loaded. */
        virtual UInt64 get_data_size() const = 0;
+
        virtual void unload() = 0;
 };
 
index 52e5866a6aa887ce536d704f528dfbc5051f06cf..6d383de4012dee79193a145c8bd0643ed0165bca 100644 (file)
@@ -126,6 +126,7 @@ void ResourceManager::load_resource(Resource &r)
                managed.start_loading();
                while(!managed.loader->process()) ;
                managed.finish_loading(true);
+               total_data_size += managed.data_size;
        }
 }
 
@@ -181,7 +182,10 @@ void ResourceManager::tick()
 
        bool do_unload = (frame>=next_unload);
        if(thread.sync())
+       {
+               total_data_size += thread.get_and_reset_loaded_data_size();
                do_unload = true;
+       }
 
        if(thread.needs_work() && !queue.empty())
                dispatch_work();
@@ -231,14 +235,17 @@ void ResourceManager::unload_by_age()
 
        for(ResourceMap::iterator i=resources.begin(); i!=resources.end(); ++i)
                if(i->second.state==ManagedResource::LOADED && i->second.last_used<unload_limit)
+               {
                        i->second.unload();
+                       total_data_size -= i->second.data_size;
+               }
 }
 
 void ResourceManager::unload_by_size()
 {
        unsigned unload_limit = frame-min_retain_frames;
 
-       while(get_total_data_size_()>size_limit)
+       while(total_data_size>size_limit)
        {
                ManagedResource *best = 0;
                UInt64 best_impact = 0;
@@ -257,24 +264,10 @@ void ResourceManager::unload_by_size()
                        break;
 
                best->unload();
+               total_data_size -= best->data_size;
        }
 }
 
-UInt64 ResourceManager::get_total_data_size_() const
-{
-       UInt64 total = 0;
-       for(ResourceMap::const_iterator i=resources.begin(); i!=resources.end(); ++i)
-               if(i->second.state==ManagedResource::LOADED)
-                       total += i->second.data_size;
-       return total;
-}
-
-UInt64 ResourceManager::get_total_data_size() const
-{
-       MutexLock lock(map_mutex);
-       return get_total_data_size_();
-}
-
 bool ResourceManager::age_order(ManagedResource *mr1, ManagedResource *mr2)
 {
        return mr1->last_used>mr2->last_used;
@@ -449,6 +442,11 @@ void ResourceManager::LoadingThread::remove_resource(ManagedResource &r)
                Time::sleep(Time::msec);
 
        r.finish_loading();
+       if(r.state==ManagedResource::LOADED)
+       {
+               MutexLock lock(data_size_mutex);
+               loaded_data_size += r.data_size;
+       }
 }
 
 bool ResourceManager::LoadingThread::try_remove_resource(ManagedResource &r)
@@ -501,6 +499,11 @@ bool ResourceManager::LoadingThread::sync()
                if(managed->state==ManagedResource::LOAD_ERROR || managed->process(true))
                {
                        managed->finish_loading();
+                       if(managed->state==ManagedResource::LOADED)
+                       {
+                               MutexLock lock(data_size_mutex);
+                               loaded_data_size += managed->data_size;
+                       }
                        any_finished = true;
                        --size;
 
@@ -520,6 +523,14 @@ bool ResourceManager::LoadingThread::sync()
        return any_finished;
 }
 
+UInt64 ResourceManager::LoadingThread::get_and_reset_loaded_data_size()
+{
+       MutexLock lock(data_size_mutex);
+       UInt64 result = loaded_data_size;
+       loaded_data_size = 0;
+       return result;
+}
+
 void ResourceManager::LoadingThread::terminate()
 {
        done = true;
index 9378d920c9671743daafddfec70def0acee39e68..afa2c2d073e45b32b25332a91a3be9c7c8568461 100644 (file)
@@ -88,6 +88,8 @@ private:
                unsigned capacity;
                unsigned size;
                std::list<resource_load_error> error_queue;
+               Mutex data_size_mutex;
+               UInt64 loaded_data_size;
                volatile bool done;
 
        public:
@@ -106,6 +108,7 @@ private:
        public:
                bool sync();
                bool needs_work() const { return size<capacity; }
+               UInt64 get_and_reset_loaded_data_size();
 
                void terminate();
        };
@@ -117,6 +120,7 @@ private:
        mutable Mutex map_mutex;
        ResourceMap resources;
        LoadQueue queue;
+       UInt64 total_data_size;
        UInt64 size_limit;
        unsigned frame;
        unsigned min_retain_frames;
@@ -156,9 +160,8 @@ private:
        void dispatch_work();
        void unload_by_age();
        void unload_by_size();
-       UInt64 get_total_data_size_() const;
 public:
-       UInt64 get_total_data_size() const;
+       UInt64 get_total_data_size() const { return total_data_size; }
 
 private:
        static bool age_order(ManagedResource *, ManagedResource *);