From cfb6238ad7fe7dd7d2eca64676437bb871802375 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Fri, 18 Feb 2022 17:59:28 +0100 Subject: Faster image loading/thumbnail creation by using multiple threads --- src/AsyncImageLoader.cpp | 66 +++++++++++++++++++++++++----------------------- 1 file changed, 34 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/AsyncImageLoader.cpp b/src/AsyncImageLoader.cpp index e6d0b52..b0efb05 100644 --- a/src/AsyncImageLoader.cpp +++ b/src/AsyncImageLoader.cpp @@ -247,47 +247,29 @@ namespace QuickMedia { } AsyncImageLoader::AsyncImageLoader() { - for(int i = 0; i < NUM_IMAGE_LOAD_PARALLEL; ++i) { + for(int i = 0; i < NUM_IMAGE_DOWNLOAD_PARALLEL; ++i) { downloads[i].read_program.pid = -1; downloads[i].read_program.read_fd = -1; } - load_thread = AsyncTask([this]() mutable { - std::optional thumbnail_load_data_opt; - while(image_thumbnail_create_queue.is_running()) { - thumbnail_load_data_opt = image_thumbnail_create_queue.pop_if_available(); - if(thumbnail_load_data_opt) { + for(int i = 0; i < NUM_IMAGE_LOAD_PARALLEL; ++i) { + load_threads[i] = AsyncTask([this]() mutable { + std::optional thumbnail_load_data_opt; + while(image_thumbnail_create_queue.is_running()) { + thumbnail_load_data_opt = image_thumbnail_create_queue.pop_wait(); + if(!thumbnail_load_data_opt) + break; + // TODO: Do this multithreaded because creating thumbnails is pretty slow single-threaded, // especially video thumbnails. process_thumbnail(thumbnail_load_data_opt.value()); if(thumbnail_load_data_opt.value().thumbnail_data->loading_state == LoadingState::READY_TO_LOAD) load_processed_thumbnail(thumbnail_load_data_opt.value()); - thumbnail_load_data_opt = std::nullopt; - } - for(int i = 0; i < NUM_IMAGE_LOAD_PARALLEL; ++i) { - Download &download = downloads[i]; - if(download.read_program.pid == -1) - continue; - - int status = 0; - if(wait_program_non_blocking(download.read_program.pid, &status)) { - Path tmp_thumbnail_path = download.thumbnail_path; - tmp_thumbnail_path.append(".tmp"); - if(status == 0 && rename_atomic(tmp_thumbnail_path.data.c_str(), download.thumbnail_path.data.c_str()) == 0) { - fprintf(stderr, "Download duration for %s: %ld ms\n", download.url.c_str(), get_boottime_milliseconds() - download.download_start); - ThumbnailLoadData load_data = { std::move(download.url), std::move(download.thumbnail_path), false, download.thumbnail_data, download.resize_target_size }; - image_thumbnail_create_queue.push(std::move(load_data)); - } else { - fprintf(stderr, "Thumbnail download failed for %s\n", download.url.c_str()); - } - reset_download(download); - } + thumbnail_load_data_opt = std::nullopt; } - - std::this_thread::sleep_for(std::chrono::milliseconds(2)); - } - }); + }); + } } AsyncImageLoader::~AsyncImageLoader() { @@ -376,11 +358,31 @@ namespace QuickMedia { } void AsyncImageLoader::update() { + for(int i = 0; i < NUM_IMAGE_DOWNLOAD_PARALLEL; ++i) { + Download &download = downloads[i]; + if(download.read_program.pid == -1) + continue; + + int status = 0; + if(wait_program_non_blocking(download.read_program.pid, &status)) { + Path tmp_thumbnail_path = download.thumbnail_path; + tmp_thumbnail_path.append(".tmp"); + if(status == 0 && rename_atomic(tmp_thumbnail_path.data.c_str(), download.thumbnail_path.data.c_str()) == 0) { + fprintf(stderr, "Download duration for %s: %ld ms\n", download.url.c_str(), get_boottime_milliseconds() - download.download_start); + ThumbnailLoadData load_data = { std::move(download.url), std::move(download.thumbnail_path), false, download.thumbnail_data, download.resize_target_size }; + image_thumbnail_create_queue.push(std::move(load_data)); + } else { + fprintf(stderr, "Thumbnail download failed for %s\n", download.url.c_str()); + } + reset_download(download); + } + } + bool loaded_textures_changed = false; for(auto it = thumbnails.begin(); it != thumbnails.end();) { if(it->second->counter != counter) { { - for(int i = 0; i < NUM_IMAGE_LOAD_PARALLEL; ++i) { + for(int i = 0; i < NUM_IMAGE_DOWNLOAD_PARALLEL; ++i) { Download &download = downloads[i]; if(download.read_program.pid == -1) continue; @@ -409,7 +411,7 @@ namespace QuickMedia { } int AsyncImageLoader::get_free_load_index() const { - for(int i = 0; i < NUM_IMAGE_LOAD_PARALLEL; ++i) { + for(int i = 0; i < NUM_IMAGE_DOWNLOAD_PARALLEL; ++i) { if(downloads[i].read_program.pid == -1) return i; } -- cgit v1.2.3