From 9866713ba916f9768edca02c61ed5ec580bd9557 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sun, 27 Sep 2020 01:08:34 +0200 Subject: Reduce scroll cpu usage from 10% to 1-2% by load image files in another thread but load the texture in the main thread --- include/Body.hpp | 20 +++++++++++++++----- include/ImageViewer.hpp | 6 ++++-- 2 files changed, 19 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/include/Body.hpp b/include/Body.hpp index 008aa70..9f7c2d8 100644 --- a/include/Body.hpp +++ b/include/Body.hpp @@ -10,6 +10,7 @@ #include "../external/RoundedRectangleShape.hpp" #include #include +#include namespace QuickMedia { class Program; @@ -82,6 +83,7 @@ namespace QuickMedia { class Body { public: Body(Program *program, sf::Font *font, sf::Font *bold_font, sf::Font *cjk_font); + ~Body(); // Select previous item, ignoring invisible items. Returns true if the item was changed. This can be used to check if the top was hit when wrap_around is set to false bool select_previous_item(); @@ -123,7 +125,6 @@ namespace QuickMedia { sf::Text progress_text; sf::Text replies_text; BodyItems items; - std::thread thumbnail_load_thread; bool draw_thumbnails; bool wrap_around; // Set to {0, 0} to disable resizing @@ -134,14 +135,22 @@ namespace QuickMedia { void draw_item(sf::RenderWindow &window, BodyItem *item, const sf::Vector2f &pos, const sf::Vector2f &size, const float item_height, const int item_index, const Json::Value &content_progress); float get_item_height(BodyItem *item); private: + enum class LoadingState { + NOT_LOADED, + LOADING, + FINISHED_LOADING, + APPLIED_TO_TEXTURE + }; + struct ThumbnailData { bool referenced = false; - std::shared_ptr texture; - bool loaded = false; + LoadingState loading_state = LoadingState::NOT_LOADED; + sf::Texture texture; + std::unique_ptr image; // Set in another thread, and then reset after loading it into |texture| }; Program *program; - std::shared_ptr load_thumbnail_from_url(const std::string &url, bool local, sf::Vector2i thumbnail_resize_target_size); - std::unordered_map item_thumbnail_textures; + void load_thumbnail_from_url(const std::string &url, bool local, sf::Vector2i thumbnail_resize_target_size, std::shared_ptr thumbnail_data); + std::unordered_map> item_thumbnail_textures; bool loading_thumbnail; int selected_item; int prev_selected_item; @@ -151,5 +160,6 @@ namespace QuickMedia { sf::RectangleShape item_background_shadow; sf::RoundedRectangleShape item_background; sf::Sprite image; + std::future load_thumbnail_future; }; } \ No newline at end of file diff --git a/include/ImageViewer.hpp b/include/ImageViewer.hpp index 93e7d7c..0ca64e9 100644 --- a/include/ImageViewer.hpp +++ b/include/ImageViewer.hpp @@ -18,13 +18,15 @@ namespace QuickMedia { WAITING, LOADING, FAILED_TO_LOAD, - LOADED + LOADED, + APPLIED_TO_TEXTURE }; struct ImageData { sf::Texture texture; sf::Sprite sprite; ImageStatus image_status; + std::unique_ptr image_data_str; bool visible_on_screen; }; @@ -47,7 +49,7 @@ namespace QuickMedia { int get_focused_page() const; int get_num_pages() const { return num_pages; } private: - void load_image_async(const Path &path, std::shared_ptr image_data, int page); + void load_image_async(const Path &path, std::shared_ptr image_data); bool render_page(sf::RenderWindow &window, int page, double offset_y); sf::Vector2 get_page_size(int page); private: -- cgit v1.2.3