diff options
author | Keuin <[email protected]> | 2022-04-13 16:25:17 +0800 |
---|---|---|
committer | Keuin <[email protected]> | 2022-04-13 16:25:17 +0800 |
commit | 25ee3cfafea166f2dd155c07b5d43ba90d5bd994 (patch) | |
tree | 431ada7108b58e1c1a21ac276f18f3aadd43345f /aa.h | |
parent | 2036ad08bfae6bc14ab3285d73fdccd382c1f1e8 (diff) |
Threaded antialiasing.
Diffstat (limited to 'aa.h')
-rw-r--r-- | aa.h | 48 |
1 files changed, 35 insertions, 13 deletions
@@ -9,33 +9,55 @@ #include "viewport.h" #include <vector> #include <thread> - +#include <algorithm> // Antialiasing viewport template<typename T> class aa_viewport : public viewport<T> { unsigned samples; - std::vector<basic_viewport<T>> subviews; + std::vector<basic_viewport<T>> *subviews; public: aa_viewport(double width, double height, vec3d viewport_center, unsigned samples) : samples(samples) { assert(samples >= 1); - subviews = std::vector<basic_viewport<T>>{samples, {width, height, viewport_center}}; + subviews = new std::vector<basic_viewport<T>>{samples, {width, height, viewport_center}}; + } + + ~aa_viewport() { + delete subviews; } virtual bitmap<T> render(const hitlist<T> &world, vec3d viewpoint, uint16_t image_width, uint16_t image_height) { -// // TODO threaded rendering -// std::vector<std::thread> workers{samples}; -// for (size_t i = 0; i < samples; ++i) { -// const auto &th = workers[i]; -// const auto &vw = subviews[i]; -// } + const unsigned hwcc = std::thread::hardware_concurrency(); + std::cerr << "Rendering with " << hwcc << " thread(s)." << std::endl; + const auto seed = 123456789012345678ULL; std::mt19937_64 seedgen{seed}; // generates seeds for workers - std::vector<bitmap<T>> images{}; - for (const auto &view: subviews) { - bias_ctx bc{seedgen()}; - images.push_back(view.render(world, viewpoint, image_width, image_height, bc)); + std::vector<bitmap<T>> images{samples, {1, 1}}; + std::thread t; + + std::vector<std::thread> workers; + unsigned remaining = samples; // tasks remaining + size_t base = 0; + while (remaining > 0) { + const unsigned n = std::min(hwcc, remaining); // threads in current batch + remaining -= n; + for (unsigned i = 0; i < n; ++i) { + workers.emplace_back(std::thread{ + [&](int tid, uint64_t seed, std::vector<basic_viewport<T>> *subs, vec3d viewpoint, + uint16_t image_width, uint16_t image_height) { + bias_ctx bc{seed}; + auto image = (*subs)[tid].render(world, viewpoint, image_width, image_height, bc); + images[base + tid] = image; + }, + i, seedgen(), subviews, viewpoint, image_width, image_height + }); + } + for (auto &th: workers) { + th.join(); + } + workers.clear(); + base += n; } return bitmap<T>::average(images); } |