emilib
texture_mngr.hpp
1 // By Emil Ernerfeldt 2014-2016
2 // LICENSE:
3 // This software is dual-licensed to the public domain and under the following
4 // license: you are granted a perpetual, irrevocable license to copy, modify,
5 // publish, and distribute this file as you see fit.
6 // HISTORY:
7 // Created in 2012-10-07 for Ghostel
8 // Cleaned up as separate library 2016-02
9 
10 #pragma once
11 
12 #include <functional>
13 #include <memory>
14 #include <string>
15 #include <unordered_map>
16 
17 #include <emilib/gl_lib_fwd.hpp>
18 
19 namespace emilib {
20 
21 class DelayedDirWatcher;
22 using DelayedDirWatcher_UP = std::unique_ptr<DelayedDirWatcher>;
23 
24 using ImageData = std::unique_ptr<void, std::function<void(void*)>>;
25 
34 using ImageLoader = std::function<ImageData(const char* path, int* width, int* height, int* comp, int req_comp)>;
35 
38 ImageData load_image_rgba(const ImageLoader& image_loader, const char* path, size_t* out_width, size_t* out_height);
39 
43 {
44 public:
45  using Recorder = std::function<void(const std::string& name)>;
46 
48  TextureMngr(const std::string& gfx_dir, ImageLoader image_loader);
49  ~TextureMngr();
50 
52  void update();
53 
55  gl::Texture_SP prefetch_retain(const std::string& name, const gl::TexParams& params);
56  gl::Texture_SP get_retain(const std::string& name, const gl::TexParams& params);
57  gl::Texture_SP get_retain(const std::string& name) { return get_retain(name, default_params()); }
58 
60  gl::Texture* get(const std::string& name, const gl::TexParams& params);
61  gl::Texture* get(const std::string& name) { return get(name, default_params()); }
62 
64  gl::Texture* prefetch(const std::string& name, const gl::TexParams& params);
65  gl::Texture* prefetch(const std::string& name) { return prefetch(name, default_params()); }
66 
68  void prefetch_all(const std::string& sub_folder = "");
69 
77  void prepare_eviction();
78  void finalize_eviction();
79 
80 #if 0
81  const Texture* store(Texture_UP&& tex);
82 #endif
83  const gl::Texture* black() const;
84  const gl::Texture* white() const;
85 
86  gl::TexParams default_params() const
87  {
88 #if TARGET_OS_IPHONE
89  return gl::TexParams::clamped_linear(); // No need for mipmaps
90 #else
91  return gl::TexParams::clamped();
92 #endif
93  }
94 
96  size_t memory_usage(unsigned* out_tex_count) const;
97 
98  void print_memory_usage(const char* prefix="") const;
99 
102  void start_recording(Recorder recorder);
103  void stop_recording();
104 
105 private:
106  struct TexInfo
107  {
108  std::string name;
109  std::string abs_path;
110  gl::Texture_SP texture;
111  bool used = false;
112  };
113 
114  void reload(const std::string& name);
115  TexInfo* prefetch_tex_info(const std::string& name, const gl::TexParams& params);
116 
117 private:
118  using FileMap = std::unordered_map<std::string, TexInfo>;
119 
120  std::string _gfx_dir;
121  ImageLoader _image_loader;
122  DelayedDirWatcher_UP _dir_watcher;
123  FileMap _file_map;
124  bool _is_evicting = false;
125  Recorder _recorder;
126 };
127 
128 } // namespace emilib
void prefetch_all(const std::string &sub_folder="")
Recursively prefetch all textures in gfx_dir/sub_folder.
void start_recording(Recorder recorder)
gl::Texture_SP prefetch_retain(const std::string &name, const gl::TexParams &params)
While holding on to this shared_ptr handle, the texture won&#39;t get evicted.
Definition: gl_lib_fwd.hpp:151
TextureMngr(const std::string &gfx_dir, ImageLoader image_loader)
Look for textures relative to gfx_dir.
size_t memory_usage(unsigned *out_tex_count) const
Bytes.
Definition: gl_lib.hpp:48
void update()
Call frequently (once a frame) for hot-reloading of textures.
Definition: texture_mngr.hpp:42
gl::Texture * prefetch(const std::string &name, const gl::TexParams &params)
Get a handle to a texture which will be loaded by finalize_eviction.
Definition: coroutine.hpp:18