feat: make image loading async

This commit is contained in:
2026-10-24 02:03:10 +02:00
parent aa3eef259c
commit 355dfa7851
11 changed files with 696 additions and 361 deletions
+45
View File
@@ -5,7 +5,9 @@
#include <stdexcept>
#include <thread>
#include <vector>
#include <cstring>
#include <destrum/Graphics/imageLoader.h>
#include <destrum/Serialization/SceneSerializer.h>
#include <destrum/Threading/JobSystem.h>
@@ -161,6 +163,47 @@ namespace {
Jobs().Shutdown();
}
void testAsyncHighPriority()
{
Jobs().Init(2);
auto future = Jobs().Async([] { return std::this_thread::get_id(); }, JobPriority::High);
check(future.get() != std::this_thread::get_id(), "high priority Async should run on a worker");
Jobs().Shutdown();
}
void testImageDecodeOnWorkersMatchesSerial()
{
const std::filesystem::path root = DESTRUM_ENGINE_ASSETS_SRC_DIR;
const std::vector<std::filesystem::path> paths{
root / "238882.png",
root / "char.jpg",
root / "flight-helmet" / "FlightHelmet_Materials_GlassPlasticMat_Normal.png",
root / "does_not_exist.png",
};
Jobs().Init(4);
std::vector<std::future<ImageData>> decoded;
for (const auto& path : paths) {
decoded.push_back(Jobs().Async([path] { return util::loadImage(path, TextureIntent::ColorSrgb); },
JobPriority::High));
}
for (std::size_t i = 0; i < paths.size(); ++i) {
const ImageData parallel = decoded[i].get();
const ImageData serial = util::loadImage(paths[i], TextureIntent::ColorSrgb);
check(parallel.vkFormat == serial.vkFormat && parallel.width == serial.width &&
parallel.height == serial.height && parallel.byteSize == serial.byteSize,
"decoding on a worker should give the same image layout");
if (serial.pixels != nullptr) {
check(parallel.pixels != nullptr &&
std::memcmp(parallel.pixels, serial.pixels, serial.byteSize) == 0,
"decoding on a worker should give the same pixels");
}
}
check(decoded.size() == 4, "every image should be decoded");
Jobs().Shutdown();
}
void testRunsInlineWhenStopped()
{
check(!Jobs().IsRunning(), "job system should start stopped");
@@ -183,4 +226,6 @@ void RunJobsTests()
testMainThreadQueue();
testShutdownDrainsPendingJobs();
testLoadSceneFileAsync();
testAsyncHighPriority();
testImageDecodeOnWorkersMatchesSerial();
}