From 06a83491627c5024c374f98a70da81a4e2a473c9 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Sat, 12 Aug 2023 13:47:08 +1000 Subject: [PATCH] dep/libchdr: Re-add progress precaching --- dep/libchdr/include/libchdr/chd.h | 1 + dep/libchdr/src/libchdr_chd.c | 71 ++++++++++++++++++++++--------- src/util/cd_image_chd.cpp | 3 +- 3 files changed, 53 insertions(+), 22 deletions(-) diff --git a/dep/libchdr/include/libchdr/chd.h b/dep/libchdr/include/libchdr/chd.h index 160fcb735..e152cf0d3 100644 --- a/dep/libchdr/include/libchdr/chd.h +++ b/dep/libchdr/include/libchdr/chd.h @@ -379,6 +379,7 @@ CHD_EXPORT chd_error chd_open(const char *filename, int mode, chd_file *parent, /* precache underlying file */ CHD_EXPORT chd_error chd_precache(chd_file *chd); +CHD_EXPORT chd_error chd_precache_progress(chd_file* chd, void(*progress)(size_t pos, size_t total, void* param), void* param); /* close a CHD file */ CHD_EXPORT void chd_close(chd_file *chd); diff --git a/dep/libchdr/src/libchdr_chd.c b/dep/libchdr/src/libchdr_chd.c index d2bf4d04e..6d50884a3 100644 --- a/dep/libchdr/src/libchdr_chd.c +++ b/dep/libchdr/src/libchdr_chd.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -1733,30 +1734,60 @@ cleanup: memory -------------------------------------------------*/ -CHD_EXPORT chd_error chd_precache(chd_file *chd) +CHD_EXPORT chd_error chd_precache(chd_file* chd) { - INT64 count; - UINT64 size; + return chd_precache_progress(chd, NULL, NULL); +} - if (chd->file_cache == NULL) - { - size = core_fsize(chd->file); - if ((INT64)size <= 0) - return CHDERR_INVALID_DATA; - chd->file_cache = malloc(size); - if (chd->file_cache == NULL) +CHD_EXPORT chd_error chd_precache_progress(chd_file* chd, void(*progress)(size_t pos, size_t total, void* param), void* param) +{ +#define PRECACHE_CHUNK_SIZE 16 * 1024 * 1024 + + size_t count; + UINT64 size, done, req_count, last_update_done, update_interval; + + if (chd->file_cache == NULL) + { + size = core_fsize(chd->file); + if ((INT64)size <= 0) + return CHDERR_INVALID_DATA; + + if (size > SIZE_MAX) return CHDERR_OUT_OF_MEMORY; - core_fseek(chd->file, 0, SEEK_SET); - count = core_fread(chd->file, chd->file_cache, size); - if (count != size) - { - free(chd->file_cache); - chd->file_cache = NULL; - return CHDERR_READ_ERROR; - } - } - return CHDERR_NONE; + chd->file_cache = malloc(size); + if (chd->file_cache == NULL) + return CHDERR_OUT_OF_MEMORY; + core_fseek(chd->file, 0, SEEK_SET); + + done = 0; + last_update_done = 0; + update_interval = ((size + 99) / 100); + + while (done < size) + { + req_count = size - done; + if (req_count > PRECACHE_CHUNK_SIZE) + req_count = PRECACHE_CHUNK_SIZE; + + count = core_fread(chd->file, chd->file_cache + (size_t)done, (size_t)req_count); + if (count != (size_t)req_count) + { + free(chd->file_cache); + chd->file_cache = NULL; + return CHDERR_READ_ERROR; + } + + done += req_count; + if (progress != NULL && (done - last_update_done) >= update_interval && done != size) + { + last_update_done = done; + progress(done, size, param); + } + } + } + + return CHDERR_NONE; } /*------------------------------------------------- diff --git a/src/util/cd_image_chd.cpp b/src/util/cd_image_chd.cpp index bf33b6aea..adbfa61bc 100644 --- a/src/util/cd_image_chd.cpp +++ b/src/util/cd_image_chd.cpp @@ -320,8 +320,7 @@ CDImage::PrecacheResult CDImageCHD::Precache(ProgressCallback* progress) static_cast(param)->SetProgressValue(std::min(percent, 100)); }; - //if (chd_precache_progress(m_chd, callback, progress) != CHDERR_NONE) - if (chd_precache(m_chd) != CHDERR_NONE) + if (chd_precache_progress(m_chd, callback, progress) != CHDERR_NONE) return CDImage::PrecacheResult::ReadError; m_precached = true;