aboutsummaryrefslogtreecommitdiff
path: root/app/rendercoord.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'app/rendercoord.cpp')
-rw-r--r--app/rendercoord.cpp220
1 files changed, 0 insertions, 220 deletions
diff --git a/app/rendercoord.cpp b/app/rendercoord.cpp
deleted file mode 100644
index 00a6437..0000000
--- a/app/rendercoord.cpp
+++ /dev/null
@@ -1,220 +0,0 @@
-#include "rendercoord.hpp"
-#include <algorithm>
-#include <qobject.h>
-#include <iostream>
-#include <qrgb.h>
-
-#include <qsemaphore.h>
-#include <render.hpp>
-#include <sstream>
-
-uint32_t colorToUint32(const Color &c) {
- Color cnew = Color(c);
- cnew.clamp();
- return (0xFF << 24) +
- (cnew.r() << 16) +
- (cnew.g() << 8) +
- cnew.b();
-}
-
-// Run by main thread
-RenderThread::RenderThread(Renderer r, unsigned threads, const Config &conf, QObject *parent, unsigned id)
- : QThread(parent),
- m_lock(1),
- m_render(r),
- m_conf(conf),
- m_pause(1)
-{
- m_id = id;
- m_workers = threads;
-}
-
-// Run on new thread
-void RenderThread::run() {
- while (1) {
- // Wait for work
- m_work.acquire();
-
- // Very expensive, but necesary to get live rendering
- Color *sum = new Color[m_render.m_width * m_render.m_height];
-
- m_current_samples = 0;
-
- for (int sample = 0; sample < m_samples; sample++) {
- m_current_samples = sample;
- // Probably not that smart
- m_pause.acquire();
- m_pause.release();
-
- for (unsigned y = m_id; y < m_render.m_height; y += m_workers) {
- for (unsigned x = 0; x < m_render.m_width; x++) {
- auto index = x + y * m_render.m_width;
- sum[index] += m_render.render(m_render.m_width - x, m_render.m_height - y, 1);
-
- m_writebuffer[index] = colorToUint32(sum[index] / (sample+1));
- }
- }
-
- }
-
- // Signal done
- m_lock.release();
- emit done(m_id);
- }
-}
-
-void RenderThread::pause() {
- m_pause.acquire();
-}
-
-void RenderThread::resume() {
- m_pause.release();
-}
-
-int RenderThread::render(QRgb *buffer, unsigned samples) {
- // Check if already running
- if (!m_lock.tryAcquire()) {
- return 1;
- }
- m_writebuffer = buffer;
- m_samples = samples;
- m_work.release();
- std::cout << samples << std::endl;
-
- return 0;
-}
-
-unsigned RenderThread::stop() {
- stopAt(m_current_samples);
- return m_current_samples;
-}
-
-void RenderThread::stopAt(int at) {
- m_samples = at;
-}
-
-// Running on main thread
-unsigned RenderThread::current_samples() {
- // No sync should not be a problem here.
- return m_current_samples;
-}
-
-RenderCoordinator::RenderCoordinator(QObject *parent, DrawWidget &target, Renderer r, const Config &conf, QLabel *status)
- : QObject(parent),
- m_target(target),
- m_renderer(r),
- m_timer(this),
- m_conf(conf)
-{
- m_status = status;
-
- // Create and start workers
- for (unsigned i = 0; i < conf.m_workers; i++) {
- auto thread = new RenderThread(m_renderer, conf.m_workers, conf, this, i);
-
- thread->start();
- QObject::connect(thread, &RenderThread::done, this, &RenderCoordinator::workerDone);
-
- m_workers.push_back(thread);
- }
-
- render();
-
-}
-
-void RenderCoordinator::render() {
- m_started = 0;
- for (auto thd : m_workers) {
- thd->render(m_target.m_drawbuffer, m_conf.m_samples);
- m_started++;
- }
-
- m_state = running;
- updateUi();
-
- QObject::connect(&m_timer, &QTimer::timeout, this, &RenderCoordinator::updateUi);
-
- m_timer.start(1000.0 / m_conf.m_framerate);
-}
-
-void RenderCoordinator::stop() {
- unsigned max = 0;
- for (auto thd : m_workers) {
- thd->pause();
-
- auto val = thd->current_samples();
- if (val>max) {
- max = val;
- }
- }
-
- std::cout << max << std::endl;
-
- for (auto thd : m_workers) {
- thd->stopAt(max+1);
- thd->resume();
- }
-
- m_state = stopping;
- updateUi();
-}
-
-void RenderCoordinator::workerDone(unsigned workerid) {
- std::cout << "Worker " << workerid << " done!" << std::endl;
- if (--m_started) {
- return;
- }
- std::cout << "All done :-)" << std::endl;
-
- // All workers are done
- m_state = stopped;
- m_timer.stop();
- updateUi();
-}
-
-unsigned RenderCoordinator::calcStats(unsigned *max, unsigned *min, double *avg) {
- unsigned count = 0;
- unsigned sum = 0;
- for (auto thd : m_workers) {
- auto val = thd->current_samples();
- if (min && (val < *min || !count)) {
- *min = val;
- }
- if (max && (val > *max || !count)) {
- *max = val;
- }
-
- sum += val;
- count++;
- }
-
- if (avg) {
- *avg = (double)sum / count;
- }
-
- return count;
-}
-
-
-void RenderCoordinator::updateUi() {
- m_target.repaint();
-
- if (!m_status) {
- return;
- }
-
- // Gather statictics from workers
- unsigned max;
- unsigned min;
- double avg;
- unsigned count = calcStats(&max, &min, &avg);
-
- std::ostringstream status;
- status << states[m_state] <<
- " Threads: " << count <<
- " Max: " << max << " samples" <<
- " Min: " << min << " samples" <<
- " Avg: " << avg << " samples";
-
- m_status->setText(QString::fromStdString(status.str()));
-}