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