summaryrefslogtreecommitdiff
path: root/aa.h
diff options
context:
space:
mode:
authorKeuin <[email protected]>2022-04-13 16:25:17 +0800
committerKeuin <[email protected]>2022-04-13 16:25:17 +0800
commit25ee3cfafea166f2dd155c07b5d43ba90d5bd994 (patch)
tree431ada7108b58e1c1a21ac276f18f3aadd43345f /aa.h
parent2036ad08bfae6bc14ab3285d73fdccd382c1f1e8 (diff)
Threaded antialiasing.
Diffstat (limited to 'aa.h')
-rw-r--r--aa.h48
1 files changed, 35 insertions, 13 deletions
diff --git a/aa.h b/aa.h
index d226fda..368a14a 100644
--- a/aa.h
+++ b/aa.h
@@ -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);
}