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 --- src/ImageViewer.cpp | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) (limited to 'src/ImageViewer.cpp') diff --git a/src/ImageViewer.cpp b/src/ImageViewer.cpp index 86e7138..97ef7c9 100644 --- a/src/ImageViewer.cpp +++ b/src/ImageViewer.cpp @@ -34,22 +34,18 @@ namespace QuickMedia { has_size_vertical_cursor = size_vertical_cursor.loadFromSystem(sf::Cursor::SizeVertical); } - void ImageViewer::load_image_async(const Path &path, std::shared_ptr image_data, int page) { + void ImageViewer::load_image_async(const Path &path, std::shared_ptr image_data) { image_data->image_status = ImageStatus::LOADING; image_data->texture.setSmooth(true); assert(!loading_image); loading_image = true; - image_loader_thread = std::thread([this, image_data, path, page]() { - std::string image_data_str; - if(file_get_content(path, image_data_str) == 0) { - if(image_data->texture.loadFromMemory(image_data_str.data(), image_data_str.size())) { - image_data->sprite.setTexture(image_data->texture, true); - page_size[page].size = get_page_size(page); - page_size[page].loaded = true; - image_data->image_status = ImageStatus::LOADED; - } else { - image_data->image_status = ImageStatus::FAILED_TO_LOAD; - } + image_loader_thread = std::thread([this, image_data, path]() { + auto image_data_str = std::make_unique(); + if(file_get_content(path, *image_data_str) == 0) { + image_data->image_data_str = std::move(image_data_str); + image_data->image_status = ImageStatus::LOADED; + } else { + image_data->image_status = ImageStatus::FAILED_TO_LOAD; } loading_image = false; }); @@ -60,8 +56,20 @@ namespace QuickMedia { if(page < 0 || page >= (int)image_data.size()) return false; - const sf::Vector2 image_size = get_page_size(page); std::shared_ptr &page_image_data = image_data[page]; + if(page_image_data && page_image_data->image_status == ImageStatus::LOADED) { + if(page_image_data->texture.loadFromMemory(page_image_data->image_data_str->data(), page_image_data->image_data_str->size())) { + page_image_data->sprite.setTexture(page_image_data->texture, true); + page_size[page].size = get_page_size(page); + page_size[page].loaded = true; + page_image_data->image_status = ImageStatus::APPLIED_TO_TEXTURE; + } else { + page_image_data->image_status = ImageStatus::FAILED_TO_LOAD; + page_image_data->image_data_str.reset(); + } + } + + const sf::Vector2 image_size = get_page_size(page); sf::Vector2 render_pos(std::floor(window_size.x * 0.5 - image_size.x * 0.5), - image_size.y * 0.5 + scroll + offset_y); if(render_pos.y + image_size.y <= 0.0 || render_pos.y >= window_size.y) { if(page_image_data) @@ -80,7 +88,7 @@ namespace QuickMedia { } if(page_image_data) { - if(page_image_data->image_status == ImageStatus::LOADED) { + if(page_image_data->image_status == ImageStatus::APPLIED_TO_TEXTURE) { page_image_data->sprite.setPosition(render_pos.x, render_pos.y); window.draw(page_image_data->sprite); } else { @@ -90,7 +98,7 @@ namespace QuickMedia { if(!loading_image) { Path image_path = chapter_cache_dir; image_path.join(page_str); - load_image_async(image_path, page_image_data, page); + load_image_async(image_path, page_image_data); } msg = "Loading image for page " + page_str; } else if(page_image_data->image_status == ImageStatus::LOADING) { @@ -320,7 +328,7 @@ namespace QuickMedia { for(auto &page_data : image_data) { if(page_data && !page_data->visible_on_screen) { fprintf(stderr, "ImageViewer: Unloaded page %d\n", 1 + i); - page_data = nullptr; + page_data.reset(); } ++i; } -- cgit v1.2.3