1 //  SuperTuxKart - a fun racing game with go-kart
2 //  Copyright (C) 2018 SuperTuxKart-Team
3 //
4 //  This program is free software; you can redistribute it and/or
5 //  modify it under the terms of the GNU General Public License
6 //  as published by the Free Software Foundation; either version 3
7 //  of the License, or (at your option) any later version.
8 //
9 //  This program is distributed in the hope that it will be useful,
10 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 //  GNU General Public License for more details.
13 //
14 //  You should have received a copy of the GNU General Public License
15 //  along with this program; if not, write to the Free Software
16 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17 
18 #ifndef HEADER_SP_TEXTURE_MANAGER_HPP
19 #define HEADER_SP_TEXTURE_MANAGER_HPP
20 
21 #ifndef SERVER_ONLY
22 
23 #include "graphics/gl_headers.hpp"
24 #include "utils/log.hpp"
25 #include "utils/no_copy.hpp"
26 
27 #include <algorithm>
28 #include <atomic>
29 #include <condition_variable>
30 #include <functional>
31 #include <list>
32 #include <map>
33 #include <memory>
34 #include <mutex>
35 #include <string>
36 #include <thread>
37 
38 #include "irrString.h"
39 
40 class Material;
41 
42 namespace SP
43 {
44 class SPTexture;
45 
46 class SPTextureManager : public NoCopy
47 {
48 private:
49     static SPTextureManager* m_sptm;
50 
51     std::map<std::string, std::shared_ptr<SPTexture> > m_textures;
52 
53     std::atomic_uint m_max_threaded_load_obj;
54 
55     std::atomic_int m_gl_cmd_function_count;
56 
57     std::list<std::function<bool()> > m_threaded_functions;
58 
59     std::list<std::function<bool()> > m_gl_cmd_functions;
60 
61     std::mutex m_thread_obj_mutex, m_gl_cmd_mutex;
62 
63     std::condition_variable m_thread_obj_cv;
64 
65     std::list<std::thread> m_threaded_load_obj;
66 
67 public:
68     // ------------------------------------------------------------------------
get()69     static SPTextureManager* get()
70     {
71         if (m_sptm == NULL)
72         {
73             m_sptm = new SPTextureManager();
74         }
75         return m_sptm;
76     }
77     // ------------------------------------------------------------------------
destroy()78     static void destroy()
79     {
80         delete m_sptm;
81         m_sptm = NULL;
82     }
83     // ------------------------------------------------------------------------
84     SPTextureManager();
85     // ------------------------------------------------------------------------
86     ~SPTextureManager();
87     // ------------------------------------------------------------------------
stopThreads()88     void stopThreads()
89     {
90         m_max_threaded_load_obj.store(0);
91         std::unique_lock<std::mutex> ul(m_thread_obj_mutex);
92         m_threaded_functions.push_back([](){ return true; });
93         m_thread_obj_cv.notify_all();
94         ul.unlock();
95         for (std::thread& t : m_threaded_load_obj)
96         {
97             t.join();
98         }
99         m_threaded_load_obj.clear();
100     }
101     // ------------------------------------------------------------------------
102     void removeUnusedTextures();
103     // ------------------------------------------------------------------------
addThreadedFunction(std::function<bool ()> threaded_function)104     void addThreadedFunction(std::function<bool()> threaded_function)
105     {
106         std::lock_guard<std::mutex> lock(m_thread_obj_mutex);
107         m_threaded_functions.push_back(threaded_function);
108         m_thread_obj_cv.notify_one();
109     }
110     // ------------------------------------------------------------------------
addGLCommandFunction(std::function<bool ()> function)111     void addGLCommandFunction(std::function<bool()> function)
112     {
113         std::lock_guard<std::mutex> lock(m_gl_cmd_mutex);
114         m_gl_cmd_functions.push_back(function);
115     }
116     // ------------------------------------------------------------------------
increaseGLCommandFunctionCount(int count)117     void increaseGLCommandFunctionCount(int count)
118                                   { m_gl_cmd_function_count.fetch_add(count); }
119     // ------------------------------------------------------------------------
120     void checkForGLCommand(bool before_scene = false);
121     // ------------------------------------------------------------------------
122     std::shared_ptr<SPTexture> getTexture(const std::string& p,
123                                           Material* m, bool undo_srgb,
124                                           const std::string& container_id);
125     // ------------------------------------------------------------------------
126     void dumpAllTextures();
127     // ------------------------------------------------------------------------
128     irr::core::stringw reloadTexture(const irr::core::stringw& name);
129 
130 };
131 
132 }
133 
134 #endif
135 
136 #endif
137