From 27cc01c085dd952eab3fe49200b39d23ce115f84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= <morten.sorvig@qt.io> Date: Wed, 26 Jun 2019 14:14:34 +0200 Subject: [PATCH] Apply some fixes: - tile size calculation - work around QTBUG-75793 --- mandelbrot/main.cpp | 2 +- mandelbrot/renderthread.cpp | 50 +++++++++++++++++++++---------------- mandelbrot/renderthread.h | 4 +-- 3 files changed, 31 insertions(+), 25 deletions(-) diff --git a/mandelbrot/main.cpp b/mandelbrot/main.cpp index 572bf59..c733000 100644 --- a/mandelbrot/main.cpp +++ b/mandelbrot/main.cpp @@ -57,7 +57,7 @@ int main(int argc, char *argv[]) { QApplication app(argc, argv); - // we're managing the number of threads elsewhere; set the global + // We're managing the number of threads elsewhere; set the global // thread limit to a large value so it won't interfere. QThreadPool::globalInstance()->setMaxThreadCount(1024); diff --git a/mandelbrot/renderthread.cpp b/mandelbrot/renderthread.cpp index dee40fc..a949fc9 100644 --- a/mandelbrot/renderthread.cpp +++ b/mandelbrot/renderthread.cpp @@ -55,6 +55,10 @@ #include <QThreadPool> #include <cmath> +#ifdef Q_OS_WASM +#include <emscripten.h> +#endif + // runs function on a thread from the global QThreadPool, returns a // function that can be called to vait for the function to finish. std::function<void()> runOnThread(std::function<void()> fn) @@ -157,14 +161,21 @@ MandelbrotRenderer::RenderPassResult MandelbrotRenderer::renderTile(int tile, in QSize imageSize = image->size(); int halfWidth = imageSize.width() / 2; int halfHeight = imageSize.height() / 2; + this->tileSize = (imageSize.height() + this->tileCount - 1) / this->tileCount; const int MaxIterations = (1 << (2 * pass + 6)) + 32; const int Limit = 4; bool allBlack = true; int beginY = tileBegin(tile, imageSize.height()) - halfHeight; int endY = tileEnd(tile, imageSize.height()) - halfHeight; - - // qDebug() << "redner tile" << tile << tileBegin(tile, imageSize.height()) << beginY << endY << imageSize.height() << (beginY + halfHeight) << (endY -1 + halfHeight) << QThread::currentThread(); + +#if 0 + qDebug() << "render tile" << tile + << "tileBegin" << tileBegin(tile, imageSize.height()) << "tileEnd" << tileEnd(tile, imageSize.height()) + << "beginY" << beginY << "endY" << endY + << "lines" << beginY + halfHeight << endY + halfHeight + << "image height" << imageSize.height(); +#endif for (int y = beginY; y < endY; ++y) { if (shouldAbort()) @@ -300,14 +311,13 @@ uint MandelbrotRenderer::rgbFromWaveLength(double wave) int MandelbrotRenderer::tileBegin(int tileIndex, int totalSize) { - int tileSize = (totalSize / (tileCount -1)); - return tileIndex * tileSize; + Q_UNUSED(totalSize); + return tileIndex * this->tileSize; } int MandelbrotRenderer::tileEnd(int tileIndex, int totalSize) { - int tileSize = (totalSize / (tileCount -1)); - return (tileIndex * tileSize + tileSize) % (totalSize); + return qMin(tileIndex * this->tileSize + this->tileSize, totalSize); } RenderThread::RenderThread(int threadCount, QObject *parent) @@ -315,21 +325,19 @@ RenderThread::RenderThread(int threadCount, QObject *parent) { restart = false; abort = false; - - int threadAndTileCount = threadCount; - - renderer = new MandelbrotRenderer( - threadAndTileCount * 2, - threadAndTileCount, - [this]()-> bool { - QMutexLocker locker(&mutex); - return abort || restart; - }, - [this](const QImage &image, double scaleFactor) { - qDebug() << "emit renderedImage"; - emit renderedImage(image.copy(), scaleFactor); - } - ); + int tileCount = threadCount * 2; + auto shouldAbort = [this]()-> bool { + QMutexLocker locker(&mutex); + return abort || restart; + }; + auto imageReady = [this](const QImage &image, double scaleFactor) { + emit renderedImage(image.copy(), scaleFactor); + +#ifdef Q_OS_WASM + MAIN_THREAD_ASYNC_EM_ASM("Browser.mainLoop.resume();"); +#endif + }; + renderer = new MandelbrotRenderer(tileCount, threadCount, shouldAbort, imageReady); } RenderThread::~RenderThread() diff --git a/mandelbrot/renderthread.h b/mandelbrot/renderthread.h index cb7187e..2107085 100644 --- a/mandelbrot/renderthread.h +++ b/mandelbrot/renderthread.h @@ -80,6 +80,7 @@ public: private: int tileCount; + int tileSize; int threadCount; std::function<bool()> shouldAbort; std::function<void(const QImage &, double scaleFactor)> imageReady; @@ -92,11 +93,8 @@ class ThreadPack { public: ThreadPack(int threadCount); - template <typename T> - T pforeach(int begin, int end, std::function<T(int)>); private: void threadFunction(); - int threadCount; }; -- GitLab