From 8ea50f3202252681b68bb5e491a3ff986535f3af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matt=C3=A9o=20Delabre?= Date: Thu, 28 Apr 2016 22:40:05 +0200 Subject: [PATCH] =?UTF-8?q?S=C3=A9paration=20entre=20images=20et=20texture?= =?UTF-8?q?s=20pour=20optimisation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Les images (chargées en RAM) sont séparées des textures (chargées en GPU) dans les dossiers et le gestionnaire de ressources. Le cache d'images est constitué de pointeurs faibles pour ne pas entrer en conflit avec la gestion de mémoire de SFGUI. On évite ainsi de recharger trop souvent les textures, mais on évite aussi des images qui resteraient indéfiniment en mémoire, affichées à l'écran. Ceci évite d'avoir des textures à la fois chargées en RAM et GPU et réduit donc l'impact mémoire inutile. Ceci pourrait résoudre le problème de l'invite "Ne répond pas" qui s'affiche de manière intempestive sans affecter le déroulement du programme. --- include/resource_manager.hpp | 15 +++++-- .../arrow_down.tga} | Bin .../icon_arrow_up.tga => images/arrow_up.tga} | Bin .../toolbar/icon_back.tga => images/back.tga} | Bin res/{textures/toolbar => images}/block.tga | Bin .../toolbar => images}/finish_block.tga | Bin .../toolbar/icon_gear.tga => images/gear.tga} | Bin .../toolbar => images}/gravity_block_east.tga | Bin .../gravity_block_north.tga | Bin .../gravity_block_south.tga | Bin .../toolbar => images}/gravity_block_west.tga | Bin .../toolbar => images}/kill_block.tga | Bin .../toolbar => images}/movable_block.tga | Bin .../icon_music.tga => images/music.tga} | Bin .../icon_no_music.tga => images/no_music.tga} | Bin .../icon_pause.tga => images/pause.tga} | Bin res/{textures/toolbar => images}/player.tga | Bin .../icon_restart.tga => images/restart.tga} | Bin .../toolbar/icon_save.tga => images/save.tga} | Bin .../toolbar => images}/switch_block.tga | Bin .../toolbar/icon_test.tga => images/test.tga} | Bin src/gui/action_toolbar.cpp | 4 +- src/gui/object_toolbar.cpp | 4 +- src/manager.cpp | 15 +++++-- src/resource_manager.cpp | 42 +++++++++++------- src/states/level.cpp | 8 ++-- 26 files changed, 55 insertions(+), 33 deletions(-) rename res/{textures/toolbar/icon_arrow_down.tga => images/arrow_down.tga} (100%) rename res/{textures/toolbar/icon_arrow_up.tga => images/arrow_up.tga} (100%) rename res/{textures/toolbar/icon_back.tga => images/back.tga} (100%) rename res/{textures/toolbar => images}/block.tga (100%) rename res/{textures/toolbar => images}/finish_block.tga (100%) rename res/{textures/toolbar/icon_gear.tga => images/gear.tga} (100%) rename res/{textures/toolbar => images}/gravity_block_east.tga (100%) rename res/{textures/toolbar => images}/gravity_block_north.tga (100%) rename res/{textures/toolbar => images}/gravity_block_south.tga (100%) rename res/{textures/toolbar => images}/gravity_block_west.tga (100%) rename res/{textures/toolbar => images}/kill_block.tga (100%) rename res/{textures/toolbar => images}/movable_block.tga (100%) rename res/{textures/toolbar/icon_music.tga => images/music.tga} (100%) rename res/{textures/toolbar/icon_no_music.tga => images/no_music.tga} (100%) rename res/{textures/toolbar/icon_pause.tga => images/pause.tga} (100%) rename res/{textures/toolbar => images}/player.tga (100%) rename res/{textures/toolbar/icon_restart.tga => images/restart.tga} (100%) rename res/{textures/toolbar/icon_save.tga => images/save.tga} (100%) rename res/{textures/toolbar => images}/switch_block.tga (100%) rename res/{textures/toolbar/icon_test.tga => images/test.tga} (100%) diff --git a/include/resource_manager.hpp b/include/resource_manager.hpp index 6d06549..75c0ed9 100644 --- a/include/resource_manager.hpp +++ b/include/resource_manager.hpp @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -18,6 +19,7 @@ private: /** * Chemins vers les différents dossiers de ressources */ + boost::filesystem::path images_path; boost::filesystem::path textures_path; boost::filesystem::path fonts_path; boost::filesystem::path levels_path; @@ -25,7 +27,7 @@ private: std::unordered_map< std::string, - std::shared_ptr + std::weak_ptr > images_cache; std::unordered_map< @@ -55,6 +57,11 @@ public: */ std::vector getFiles(boost::filesystem::path path) const; + /** + * Récupère le chemin vers le dossier des images + */ + const boost::filesystem::path& getImagesPath() const; + /** * Récupère le chemin vers le dossier des textures */ @@ -78,9 +85,9 @@ public: /** * Charge l'image dont le chemin est donné en paramètre */ - std::shared_ptr getImage(boost::filesystem::path path); - std::shared_ptr getImage(std::string name); - std::shared_ptr getImage(const char* name); + sfg::Image::Ptr getImage(boost::filesystem::path path); + sfg::Image::Ptr getImage(std::string name); + sfg::Image::Ptr getImage(const char* name); /** * Charge l'image dont le chemin est donné en paramètre diff --git a/res/textures/toolbar/icon_arrow_down.tga b/res/images/arrow_down.tga similarity index 100% rename from res/textures/toolbar/icon_arrow_down.tga rename to res/images/arrow_down.tga diff --git a/res/textures/toolbar/icon_arrow_up.tga b/res/images/arrow_up.tga similarity index 100% rename from res/textures/toolbar/icon_arrow_up.tga rename to res/images/arrow_up.tga diff --git a/res/textures/toolbar/icon_back.tga b/res/images/back.tga similarity index 100% rename from res/textures/toolbar/icon_back.tga rename to res/images/back.tga diff --git a/res/textures/toolbar/block.tga b/res/images/block.tga similarity index 100% rename from res/textures/toolbar/block.tga rename to res/images/block.tga diff --git a/res/textures/toolbar/finish_block.tga b/res/images/finish_block.tga similarity index 100% rename from res/textures/toolbar/finish_block.tga rename to res/images/finish_block.tga diff --git a/res/textures/toolbar/icon_gear.tga b/res/images/gear.tga similarity index 100% rename from res/textures/toolbar/icon_gear.tga rename to res/images/gear.tga diff --git a/res/textures/toolbar/gravity_block_east.tga b/res/images/gravity_block_east.tga similarity index 100% rename from res/textures/toolbar/gravity_block_east.tga rename to res/images/gravity_block_east.tga diff --git a/res/textures/toolbar/gravity_block_north.tga b/res/images/gravity_block_north.tga similarity index 100% rename from res/textures/toolbar/gravity_block_north.tga rename to res/images/gravity_block_north.tga diff --git a/res/textures/toolbar/gravity_block_south.tga b/res/images/gravity_block_south.tga similarity index 100% rename from res/textures/toolbar/gravity_block_south.tga rename to res/images/gravity_block_south.tga diff --git a/res/textures/toolbar/gravity_block_west.tga b/res/images/gravity_block_west.tga similarity index 100% rename from res/textures/toolbar/gravity_block_west.tga rename to res/images/gravity_block_west.tga diff --git a/res/textures/toolbar/kill_block.tga b/res/images/kill_block.tga similarity index 100% rename from res/textures/toolbar/kill_block.tga rename to res/images/kill_block.tga diff --git a/res/textures/toolbar/movable_block.tga b/res/images/movable_block.tga similarity index 100% rename from res/textures/toolbar/movable_block.tga rename to res/images/movable_block.tga diff --git a/res/textures/toolbar/icon_music.tga b/res/images/music.tga similarity index 100% rename from res/textures/toolbar/icon_music.tga rename to res/images/music.tga diff --git a/res/textures/toolbar/icon_no_music.tga b/res/images/no_music.tga similarity index 100% rename from res/textures/toolbar/icon_no_music.tga rename to res/images/no_music.tga diff --git a/res/textures/toolbar/icon_pause.tga b/res/images/pause.tga similarity index 100% rename from res/textures/toolbar/icon_pause.tga rename to res/images/pause.tga diff --git a/res/textures/toolbar/player.tga b/res/images/player.tga similarity index 100% rename from res/textures/toolbar/player.tga rename to res/images/player.tga diff --git a/res/textures/toolbar/icon_restart.tga b/res/images/restart.tga similarity index 100% rename from res/textures/toolbar/icon_restart.tga rename to res/images/restart.tga diff --git a/res/textures/toolbar/icon_save.tga b/res/images/save.tga similarity index 100% rename from res/textures/toolbar/icon_save.tga rename to res/images/save.tga diff --git a/res/textures/toolbar/switch_block.tga b/res/images/switch_block.tga similarity index 100% rename from res/textures/toolbar/switch_block.tga rename to res/images/switch_block.tga diff --git a/res/textures/toolbar/icon_test.tga b/res/images/test.tga similarity index 100% rename from res/textures/toolbar/icon_test.tga rename to res/images/test.tga diff --git a/src/gui/action_toolbar.cpp b/src/gui/action_toolbar.cpp index f1432ce..26566ac 100644 --- a/src/gui/action_toolbar.cpp +++ b/src/gui/action_toolbar.cpp @@ -39,9 +39,7 @@ sfg::Button::Ptr ActionToolbar::createButton(std::string name) { // création d'un bouton avec pour image l'image passée sfg::Button::Ptr button = sfg::Button::Create(""); button->SetClass("icon"); - button->SetImage(sfg::Image::Create( - *ResourceManager::get().getImage("toolbar/icon_" + name + ".tga") - )); + button->SetImage(ResourceManager::get().getImage(name + ".tga")); return button; } diff --git a/src/gui/object_toolbar.cpp b/src/gui/object_toolbar.cpp index e290cf5..46d1c0c 100644 --- a/src/gui/object_toolbar.cpp +++ b/src/gui/object_toolbar.cpp @@ -69,9 +69,7 @@ ObjectToolbar::ObjectToolbar() { void ObjectToolbar::addCreator(std::string path, std::function creator) { // on crée un bouton d'objet correspondant au créateur donné ObjectButton::Ptr button = ObjectButton::Create( - sfg::Image::Create( - *ResourceManager::get().getImage("toolbar/" + path + ".tga") - ), creators_group + ResourceManager::get().getImage(path + ".tga") ); creators[button] = creator; diff --git a/src/manager.cpp b/src/manager.cpp index b8dce8e..dcc1f80 100644 --- a/src/manager.cpp +++ b/src/manager.cpp @@ -11,6 +11,8 @@ const float Manager::GRID = 32; Manager::Manager() : title(sf::String(L"")), previous_time(sf::seconds(0)), previous_state(nullptr) { + ResourceManager& res = ResourceManager::get(); + // ajout des polices dans le gestionnaire de ressources // de la librairie pour l'interface desktop.GetEngine().GetResourceManager().AddFont( @@ -28,9 +30,7 @@ Manager::Manager() : title(sf::String(L"")), previous_time(sf::seconds(0)), // chargement du thème de l'interface desktop.LoadThemeFromFile("res/gui.theme"); - // chargement des textures - ResourceManager& res = ResourceManager::get(); - + // préchargement des textures dans le GPU for (const auto &texture : res.getFiles(res.getTexturesPath())) { res.getTexture(texture); @@ -41,6 +41,15 @@ Manager::Manager() : title(sf::String(L"")), previous_time(sf::seconds(0)), while (window.pollEvent(event)) {} } + // préchargement des images dans la RAM + for (const auto &image : res.getFiles(res.getImagesPath())) { + res.getImage(image); + + // mêmes raisons que ci-dessus + sf::Event event; + while (window.pollEvent(event)) {} + } + // création de la fenêtre du jeu window.create( sf::VideoMode(704, 480), "Skizzle", sf::Style::Default, diff --git a/src/resource_manager.cpp b/src/resource_manager.cpp index ac66cdb..710920a 100644 --- a/src/resource_manager.cpp +++ b/src/resource_manager.cpp @@ -14,6 +14,7 @@ ResourceManager::ResourceManager() : is_playing(false), is_muted(false) { // mise en mémoire des chemins vers les dossiers de ressources fs::path res_path = fs::current_path() / "res"; + images_path = res_path / "images"; textures_path = res_path / "textures"; fonts_path = res_path / "fonts"; levels_path = res_path / "levels"; @@ -40,6 +41,10 @@ std::vector ResourceManager::getFiles(fs::path path) const { return result; } +const fs::path& ResourceManager::getImagesPath() const { + return images_path; +} + const fs::path& ResourceManager::getTexturesPath() const { return textures_path; } @@ -56,34 +61,42 @@ const fs::path& ResourceManager::getMusicsPath() const { return musics_path; } -std::shared_ptr ResourceManager::getImage(fs::path path) { +sfg::Image::Ptr ResourceManager::getImage(fs::path path) { std::string path_str = path.string(); // si l'image a déjà été chargée, on retourne la // version en cache mémoire if (images_cache.count(path_str) > 0) { - return images_cache[path_str]; + // le cache d'images est constitué de pointeurs "faibles", càd + // que dès que la ressource n'est plus utilisée, le pointeur + // s'invalide. Ceci parce que SFGUI maintient son propre cache. + // on doit donc d'abord vérifier que le pointeur est toujours valide + if (!images_cache[path_str].expired()) { + return images_cache[path_str].lock(); + } } // on tente de charger l'image depuis son emplacement - auto image = std::shared_ptr(new sf::Image); + sf::Image image; - if (!image->loadFromFile(path_str)) { + if (!image.loadFromFile(path_str)) { std::cerr << "Impossible de charger l'image :" << std::endl; std::cerr << path_str << std::endl << std::endl; } - // on met en cache l'image pour les requêtes suivantes - // puis on la renvoie - images_cache[path_str] = std::move(image); - return images_cache[path_str]; + // création d'une nouvelle image SFGUI avec les infos chargées + // et mise en cache du résultat + sfg::Image::Ptr sfg_image = sfg::Image::Create(image); + images_cache[path_str] = sfg_image; + + return sfg_image; } -std::shared_ptr ResourceManager::getImage(std::string name) { - return getImage(textures_path / name); +sfg::Image::Ptr ResourceManager::getImage(std::string name) { + return getImage(images_path / name); } -std::shared_ptr ResourceManager::getImage(const char* name) { +sfg::Image::Ptr ResourceManager::getImage(const char* name) { return getImage(std::string(name)); } @@ -95,14 +108,11 @@ std::shared_ptr ResourceManager::getTexture(fs::path path) { return textures_cache[path_str]; } - // on récupère l'image depuis le disque - std::shared_ptr image = getImage(path); - - // on transfère l'image vers le GPU + // on tente de charger la texture depuis le disque vers le GPU auto texture = std::shared_ptr(new sf::Texture); texture->setSmooth(true); - if (!texture->loadFromImage(*image)) { + if (!texture->loadFromFile(path_str)) { std::cerr << "Impossible de créer la texture :" << std::endl; std::cerr << path_str << std::endl << std::endl; } diff --git a/src/states/level.cpp b/src/states/level.cpp index c63b8e2..1f17780 100644 --- a/src/states/level.cpp +++ b/src/states/level.cpp @@ -282,15 +282,15 @@ void Level::frame() { sf::Vector2i window_size = (sf::Vector2i) window.getSize(); // mise à jour de l'icône du mute en fonction de l'état - sf::Image image; + sfg::Image::Ptr image; if (ResourceManager::get().isMuted()) { - image = *ResourceManager::get().getImage("toolbar/icon_no_music.tga"); + image = ResourceManager::get().getImage("no_music.tga"); } else { - image = *ResourceManager::get().getImage("toolbar/icon_music.tga"); + image = ResourceManager::get().getImage("music.tga"); } - mute_button->SetImage(sfg::Image::Create(image)); + mute_button->SetImage(image); // positionnement de la barre d'actions action_toolbar.getWindow()->SetAllocation(sf::FloatRect(