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/QuickMedia.cpp | 47 ++++++++++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 17 deletions(-) (limited to 'src/QuickMedia.cpp') diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp index 6293e52..05b65ea 100644 --- a/src/QuickMedia.cpp +++ b/src/QuickMedia.cpp @@ -2695,14 +2695,14 @@ namespace QuickMedia { std::future captcha_request_future; std::future captcha_post_solution_future; std::future post_comment_future; - std::future load_image_future; + std::future load_image_future; + bool downloading_image = false; sf::Texture captcha_texture; sf::Sprite captcha_sprite; std::mutex captcha_image_mutex; auto attached_image_texture = std::make_unique(); sf::Sprite attached_image_sprite; - std::mutex attachment_load_mutex; GoogleCaptchaChallengeInfo challenge_info; sf::Text challenge_description_text("", *font, 24); @@ -2726,6 +2726,8 @@ namespace QuickMedia { // TODO: Show a white image with "Loading..." text while the captcha image is downloading + // TODO: Make google captcha images load texture in the main thread, otherwise high cpu usage. I guess its fine right now because of only 1 image? + // TODO: Make this work with other sites than 4chan auto request_google_captcha_image = [this, &captcha_texture, &captcha_image_mutex, &navigation_stage, &captcha_sprite, &challenge_description_text](GoogleCaptchaChallengeInfo &challenge_info) { std::string payload_image_data; @@ -2865,26 +2867,21 @@ namespace QuickMedia { content_url = std::move(prev_content_url); redraw = true; } else { + if(downloading_image && load_image_future.valid()) + load_image_future.get(); + downloading_image = true; navigation_stage = NavigationStage::VIEWING_ATTACHED_IMAGE; - load_image_future = std::async(std::launch::async, [this, &image_board, &attached_image_texture, &attached_image_sprite, &attachment_load_mutex]() -> bool { + load_image_future = std::async(std::launch::async, [this, &image_board]() { + std::string image_data; BodyItem *selected_item = body->get_selected(); if(!selected_item || selected_item->attached_content_url.empty()) { - return false; + return image_data; } - std::string image_data; - if(download_to_string(selected_item->attached_content_url, image_data, {}, image_board->use_tor) != DownloadResult::OK) { + if(download_to_string_cache(selected_item->attached_content_url, image_data, {}, image_board->use_tor) != DownloadResult::OK) { show_notification(image_board->name, "Failed to download image: " + selected_item->attached_content_url, Urgency::CRITICAL); - return false; - } - - std::lock_guard lock(attachment_load_mutex); - if(!attached_image_texture->loadFromMemory(image_data.data(), image_data.size())) { - show_notification(image_board->name, "Failed to load image downloaded from url: " + selected_item->attached_content_url, Urgency::CRITICAL); - return false; + image_data.clear(); } - attached_image_texture->setSmooth(true); - attached_image_sprite.setTexture(*attached_image_texture, true); - return true; + return image_data; }); } } @@ -3050,8 +3047,24 @@ namespace QuickMedia { } else if(navigation_stage == NavigationStage::POSTING_COMMENT) { // TODO: Show "Posting..." when posting comment } else if(navigation_stage == NavigationStage::VIEWING_ATTACHED_IMAGE) { + std::string image_data; + if(downloading_image && load_image_future.valid() && load_image_future.wait_for(std::chrono::seconds(0)) == std::future_status::ready) { + downloading_image = false; + image_data = load_image_future.get(); + + if(attached_image_texture->loadFromMemory(image_data.data(), image_data.size())) { + attached_image_texture->setSmooth(true); + attached_image_sprite.setTexture(*attached_image_texture, true); + } else { + BodyItem *selected_item = body->get_selected(); + std::string selected_item_attached_url; + if(selected_item) + selected_item_attached_url = selected_item->attached_content_url; + show_notification(image_board->name, "Failed to load image downloaded from url: " + selected_item->attached_content_url, Urgency::CRITICAL); + } + } + // TODO: Show a white image with the text "Downloading..." while the image is downloading and loading - std::lock_guard lock(attachment_load_mutex); if(attached_image_texture->getNativeHandle() != 0) { auto content_size = window_size; sf::Vector2u texture_size = attached_image_texture->getSize(); -- cgit v1.2.3