Nicolas Winkler 5 years ago
parent
commit
a626ee553a

+ 1 - 0
Almond.cpp

@@ -16,6 +16,7 @@ Almond::Almond(QWidget* parent) :
     mw = std::make_unique<MandelWidget>(mandelContext, currentGenerator, ui.centralWidget);
     ui.mainContainer->addWidget(mw.get());
     ui.maxIterations->setValidator(new QIntValidator(1, 1000000000, this));
+    ui.backgroundProgress->setVisible(false);
     //ui.verticalLayout_left->addWidget(new MyGLWidget(ui.centralWidget));
     //mw->show();
 }

+ 2 - 0
Almond.pro

@@ -27,6 +27,7 @@ CONFIG += c++17
 
 SOURCES += \
         Almond.cpp \
+        BackgroundTask.cpp \
         Bitmap.cpp \
         Color.cpp \
         CubicSpline.cpp \
@@ -42,6 +43,7 @@ SOURCES += \
 
 HEADERS += \
         Almond.h \
+        BackgroundTask.h \
         Bitmap.h \
         Color.h \
         CubicSpline.h \

+ 25 - 0
Almond.ui

@@ -186,6 +186,31 @@
          </property>
         </widget>
        </item>
+       <item>
+        <widget class="QProgressBar" name="backgroundProgress">
+         <property name="enabled">
+          <bool>true</bool>
+         </property>
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="maximum">
+          <number>1</number>
+         </property>
+         <property name="value">
+          <number>0</number>
+         </property>
+         <property name="alignment">
+          <set>Qt::AlignCenter</set>
+         </property>
+         <property name="format">
+          <string>Background Tasks</string>
+         </property>
+        </widget>
+       </item>
       </layout>
      </item>
     </layout>

+ 6 - 0
BackgroundTask.cpp

@@ -0,0 +1,6 @@
+#include "BackgroundTask.h"
+
+BackgroundTask::BackgroundTask()
+{
+
+}

+ 12 - 0
BackgroundTask.h

@@ -0,0 +1,12 @@
+#ifndef BACKGROUNDTASK_H
+#define BACKGROUNDTASK_H
+
+#include <QRunnable>
+
+class BackgroundTask
+{
+public:
+    BackgroundTask(QRunnable* task);
+};
+
+#endif // BACKGROUNDTASK_H

+ 6 - 6
MandelVideoGenerator.cpp

@@ -18,7 +18,7 @@ void MandelVideoGenerator::generate(void)
     mi.bHeight = evi.height * 2;
     mi.maxIter = evi.maxIterations;
 
-    VideoStream vs(evi.width, evi.height, evi.path, evi.bitrate, evi.preset.c_str());
+    VideoStream vs(evi.width, evi.height, evi.path, evi.bitrate, evi.fps, evi.preset.c_str());
 
     mnd::Real x = evi.end.x + evi.end.width / 2;
     mnd::Real y = evi.end.y + evi.end.height / 2;
@@ -36,9 +36,9 @@ void MandelVideoGenerator::generate(void)
         if (bigW > 2 * w) {
             Bitmap<float> raw{ evi.width * 2, evi.height * 2 };
             gen.generate(mi, raw.pixels.get());
-            auto before = std::chrono::high_resolution_clock::now();
+            //auto before = std::chrono::high_resolution_clock::now();
             big = raw.map<RGBColor>([&mi, this] (float i) {
-                return i >= mi.maxIter ? RGBColor{ 0,0,0 } : evi.gradient.get(i);
+                return i >= mi.maxIter ? RGBColor{ 0, 0, 0 } : evi.gradient.get(i);
             });
             /*mi.view.zoomCenter(0.5);
             gen.generate(mi, raw.pixels.get());
@@ -51,9 +51,9 @@ void MandelVideoGenerator::generate(void)
 
         vs.addFrame(overlay(big, small, bigFac));
 
-        w *= 0.99;
-        h *= 0.99;
-        bigFac *= 0.99;
+        w *= ::pow(0.99, evi.zoomSpeed);
+        h *= ::pow(0.99, evi.zoomSpeed);
+        bigFac *= ::pow(0.99, evi.zoomSpeed);
     }
 }
 

+ 2 - 0
MandelVideoGenerator.h

@@ -14,6 +14,8 @@ struct ExportVideoInfo
     int width;
     int height;
     int maxIterations;
+    int fps;
+    double zoomSpeed;
 
     std::string path;
 

+ 3 - 3
VideoStream.cpp

@@ -15,7 +15,7 @@
 const uint8_t VideoStream::endcode[] = { 0, 0, 1, 0xb7 };
 
 
-VideoStream::VideoStream(int width, int height, const std::string& filename, int bitrate, const char* preset) :
+VideoStream::VideoStream(int width, int height, const std::string& filename, int bitrate, int fps, const char* preset) :
     width{ width & (~1) }, height{ height & (~1) }
 {
     // only needed with ffmpeg version < 4
@@ -42,8 +42,8 @@ VideoStream::VideoStream(int width, int height, const std::string& filename, int
     codecContext->bit_rate = bitrate * 1000;
     codecContext->width = width;
     codecContext->height = height;
-    codecContext->time_base = AVRational{ 1, 60 };
-    codecContext->framerate = AVRational{ 60, 1 };
+    codecContext->time_base = AVRational{ 1, fps };
+    codecContext->framerate = AVRational{ fps, 1 };
 
     codecContext->gop_size = 5; /* emit one intra frame every five frames */
     codecContext->max_b_frames = 1;

+ 1 - 1
VideoStream.h

@@ -37,7 +37,7 @@ class VideoStream
 
     int64_t frameIndex = 0;
 public:
-    VideoStream(int width, int height, const std::string& filename, int bitrate, const char* preset);
+    VideoStream(int width, int height, const std::string& filename, int bitrate, int fps, const char* preset);
     ~VideoStream(void);
 
     void encode(AVFrame* frame);

+ 22 - 32
choosegenerators.cpp

@@ -124,30 +124,18 @@ ChooseGenerators::ChooseGenerators(mnd::MandelContext& mndCtxt, QWidget *parent)
     QRegExp floatingpoint{ "^[-+]?(\\d*\\.?\\d+|\\d+\\.?\\d*)([eE][-+]\\d+)?$" };
     floatValidator = std::make_unique<QRegExpValidator>(floatingpoint, this);
 
-    auto genName = [] (mnd::GeneratorType type) {
-        static const std::map<mnd::GeneratorType, QString> names {
-            { mnd::GeneratorType::FLOAT, "float" },
-            { mnd::GeneratorType::FLOAT_SSE2, "float SSE2" },
-            { mnd::GeneratorType::FLOAT_AVX, "float AVX" },
-            { mnd::GeneratorType::FLOAT_AVX512, "float AVX512" },
-            { mnd::GeneratorType::FLOAT_NEON, "float Neon" },
-            { mnd::GeneratorType::DOUBLE, "double" },
-            { mnd::GeneratorType::DOUBLE_SSE2, "double SSE2" },
-            { mnd::GeneratorType::DOUBLE_AVX, "double AVX" },
-            { mnd::GeneratorType::DOUBLE_AVX512, "double AVX512" },
-            { mnd::GeneratorType::DOUBLE_NEON, "double Neon" },
-            { mnd::GeneratorType::DOUBLE_DOUBLE, "double double" },
-            { mnd::GeneratorType::DOUBLE_DOUBLE_AVX, "double double AVX" },
-            { mnd::GeneratorType::QUAD_DOUBLE, "quad double" },
-            { mnd::GeneratorType::FLOAT128, "float128" },
-            { mnd::GeneratorType::FLOAT256, "float256" },
-            { mnd::GeneratorType::FIXED512, "fixed512" },
-        };
-
-        return names.at(type);
-    };
+    for (auto genType : mndCtxt.getSupportedTypes()) {
+        const std::string& typeName = mnd::getGeneratorName(genType);
+        generators.insert({ QString::fromStdString(typeName), mndCtxt.getCpuGenerator(genType) });
+    }
+    for (auto& device : mndCtxt.getDevices()) {
+        for (auto genType : device.getSupportedTypes()) {
+            const std::string& typeName = mnd::getGeneratorName(genType) + " [" + device.getName() + "]";
+            generators.insert({ QString::fromStdString(typeName), device.getGenerator(genType) });
+        }
+    }
 
-    generators = std::map<QString, mnd::Generator*> {
+    /*generators = std::map<QString, mnd::Generator*> {
         { "float", mndCtxt.getCpuGenerator(mnd::GeneratorType::FLOAT) },
         { "double", mndCtxt.getCpuGenerator(mnd::GeneratorType::DOUBLE) },
         { "double double", mndCtxt.getCpuGenerator(mnd::GeneratorType::DOUBLE_DOUBLE) },
@@ -184,7 +172,7 @@ ChooseGenerators::ChooseGenerators(mnd::MandelContext& mndCtxt, QWidget *parent)
             generators.insert({ QString("double double ") + QString::fromStdString(device.getName()),
                                 gen });
         }
-    }
+    }*/
 
     auto& defGen = mndCtxt.getDefaultGenerator();
     for (auto it = defGen.getGenerators().rbegin(); it != defGen.getGenerators().rend(); it++) {
@@ -210,18 +198,22 @@ ChooseGenerators::ChooseGenerators(mnd::MandelContext& mndCtxt, QWidget *parent)
 
     std::vector<mnd::GeneratorType> generatorTypes = mndCtxt.getSupportedTypes();
     for (size_t i = 0; i < generatorTypes.size(); i++) {
-        ui->generatorTable->insertRow(ui->generatorTable->rowCount());
-        ui->generatorTable->setItem(ui->generatorTable->rowCount() - 1, 0, new QTableWidgetItem);
-        ui->generatorTable->item(ui->generatorTable->rowCount() - 1, 0)->setText(genName(generatorTypes[i]));
+        int rowCount = ui->generatorTable->rowCount();
+        ui->generatorTable->insertRow(rowCount);
+        ui->generatorTable->setItem(rowCount, 0, new QTableWidgetItem);
+        const std::string& genName = mnd::getGeneratorName(generatorTypes[i]);
+        ui->generatorTable->item(rowCount, 0)->setText(QString::fromStdString(genName));
         actualGenerators.push_back(mndCtxt.getCpuGenerator(generatorTypes[i]));
     }
 
     for (auto& device : mndCtxt.getDevices()) {
         std::vector<mnd::GeneratorType> generatorTypes = device.getSupportedTypes();
         for (size_t i = 0; i < generatorTypes.size(); i++) {
-            ui->generatorTable->insertRow(ui->generatorTable->rowCount());
-            ui->generatorTable->setItem(ui->generatorTable->rowCount() - 1, 0, new QTableWidgetItem);
-            ui->generatorTable->item(ui->generatorTable->rowCount() - 1, 0)->setText(genName(generatorTypes[i]) + " [" + QString::fromStdString(device.getName()) + "]");
+            int rowCount = ui->generatorTable->rowCount();
+            ui->generatorTable->insertRow(rowCount);
+            ui->generatorTable->setItem(rowCount, 0, new QTableWidgetItem);
+            const std::string& genName = mnd::getGeneratorName(generatorTypes[i]) + " [" + device.getName() + "]";
+            ui->generatorTable->item(rowCount, 0)->setText(QString::fromStdString(genName));
             actualGenerators.push_back(device.getGenerator(generatorTypes[i]));
         }
     }
@@ -272,8 +264,6 @@ void ChooseGenerators::on_buttonBox_accepted()
     createdGenerator->clear();
     try {
         for (size_t i = 0; i < tableContent.size(); i++) {
-            //std::cout << tableContent.at(i).first << std::endl;
-            //std::cout << tableContent.at(i).second << std::endl;
             QString precString = tableContent.at(i).first->text();
             QString genString = tableContent.at(i).second->currentText();
 

+ 4 - 0
exportdialogs.cpp

@@ -80,6 +80,8 @@ ExportVideoDialog::ExportVideoDialog(QWidget* parent, const ExportVideoInfo& evi
     evd.vidWidth->setValidator(new QIntValidator(1, 10000000, this));
     evd.vidHeight->setValidator(new QIntValidator(1, 10000000, this));
     evd.bitrate->setValidator(new QIntValidator(1, 10000000, this));
+    evd.fps->setValidator(new QIntValidator(1, 8000, this));
+    evd.zoomSpeed->setValidator(new QDoubleValidator(0.0, 100.0, -1, this));
 
 #ifdef WITH_BOOST
     evd.startX->setText(QString::fromStdString(evi.start.x.str()));
@@ -140,6 +142,8 @@ void ExportVideoDialog::on_buttonBox_accepted()
 
     evi.bitrate = evd.bitrate->text().toInt();
     evi.preset = evd.encodingPresetBox->currentText().toStdString();
+    evi.fps = evd.fps->text().toInt();
+    evi.zoomSpeed = QLocale::system().toDouble(evd.zoomSpeed->text());
     /*evi.start = mnd::MandelViewport {
         evd.startX->text().toDouble(),
         evd.startY->text().toDouble(),

+ 30 - 2
exportvideodialog.ui

@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>1263</width>
-    <height>454</height>
+    <width>1215</width>
+    <height>437</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -213,6 +213,34 @@
          </property>
         </widget>
        </item>
+       <item row="2" column="0">
+        <widget class="QLabel" name="label_8">
+         <property name="text">
+          <string>Fps</string>
+         </property>
+        </widget>
+       </item>
+       <item row="2" column="1">
+        <widget class="QLineEdit" name="fps">
+         <property name="text">
+          <string>60</string>
+         </property>
+        </widget>
+       </item>
+       <item row="3" column="0">
+        <widget class="QLabel" name="label_9">
+         <property name="text">
+          <string>Zoom Speed</string>
+         </property>
+        </widget>
+       </item>
+       <item row="3" column="1">
+        <widget class="QLineEdit" name="zoomSpeed">
+         <property name="text">
+          <string>1</string>
+         </property>
+        </widget>
+       </item>
       </layout>
      </item>
     </layout>

+ 3 - 0
libmandel/include/Mandel.h

@@ -20,6 +20,9 @@ namespace mnd
     class MandelDevice;
 
     extern MandelContext initializeContext(void);
+
+    const std::string& getGeneratorName(mnd::GeneratorType);
+    GeneratorType getTypeFromName(const std::string& name);
 }
 
 

+ 55 - 3
libmandel/src/Mandel.cpp

@@ -4,11 +4,63 @@
 #include "CpuGenerators.h"
 #include "ClGenerators.h"
 
+#include <map>
+
 using mnd::MandelDevice;
 using mnd::MandelContext;
 using mnd::Generator;
 using mnd::AdaptiveGenerator;
 
+template<typename T, typename U>
+static std::map<U, T> invertMap(const std::map<T, U>& m)
+{
+    std::map<U, T> res;
+    std::transform(m.begin(), m.end(), std::inserter(res, res.end()), [](auto& pair) {
+        return std::pair{ pair.second, pair.first };
+    });
+    return res;
+}
+
+
+static const std::map<mnd::GeneratorType, std::string> typeNames =
+{
+    { mnd::GeneratorType::FLOAT, "float" },
+    { mnd::GeneratorType::FLOAT_SSE2, "float SSE2" },
+    { mnd::GeneratorType::FLOAT_AVX, "float AVX" },
+    { mnd::GeneratorType::FLOAT_AVX512, "float AVX512" },
+    { mnd::GeneratorType::FLOAT_NEON, "float Neon" },
+    { mnd::GeneratorType::DOUBLE, "double" },
+    { mnd::GeneratorType::DOUBLE_SSE2, "double SSE2" },
+    { mnd::GeneratorType::DOUBLE_AVX, "double AVX" },
+    { mnd::GeneratorType::DOUBLE_AVX512, "double AVX512" },
+    { mnd::GeneratorType::DOUBLE_NEON, "double Neon" },
+    { mnd::GeneratorType::DOUBLE_DOUBLE, "double double" },
+    { mnd::GeneratorType::DOUBLE_DOUBLE_AVX, "double double AVX" },
+    { mnd::GeneratorType::QUAD_DOUBLE, "quad double" },
+    { mnd::GeneratorType::FLOAT128, "float128" },
+    { mnd::GeneratorType::FLOAT256, "float256" },
+    { mnd::GeneratorType::FIXED512, "fixed512" },
+};
+
+
+static const std::map<std::string, mnd::GeneratorType> nameTypes = invertMap(typeNames);
+
+
+namespace mnd
+{
+
+    const std::string& getGeneratorName(mnd::GeneratorType type)
+    {
+        return typeNames.at(type);
+    }
+
+
+    mnd::GeneratorType getTypeFromName(const std::string& name)
+    {
+        return nameTypes.at(name);
+    }
+
+}
 
 
 MandelContext mnd::initializeContext(void)
@@ -157,14 +209,14 @@ std::vector<MandelDevice> MandelContext::createDevices(void)
         std::string name = platform.getInfo<CL_PLATFORM_NAME>();
         std::string profile = platform.getInfo<CL_PLATFORM_PROFILE>();
 
-        printf("using opencl platform: %s\n", name.c_str());
+        //printf("using opencl platform: %s\n", name.c_str());
 
         //std::string ext = platform.getInfo<CL_PLATFORM_EXTENSIONS>();
         //printf("Platform extensions: %s\n", ext.c_str());
         //printf("Platform: %s, %s\n", name.c_str(), profile.c_str());
 
         std::vector<cl::Device> devices;
-        platform.getDevices(CL_DEVICE_TYPE_GPU | CL_DEVICE_TYPE_CPU, &devices);
+        platform.getDevices(CL_DEVICE_TYPE_GPU, &devices);
         for (auto& device : devices) {
             //printf("Device: %s\n", device.getInfo<CL_DEVICE_NAME>().c_str());
             //printf("preferred float width: %d\n", device.getInfo<CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT>());
@@ -180,7 +232,7 @@ std::vector<MandelDevice> MandelContext::createDevices(void)
 
             md.name = device.getInfo<CL_DEVICE_NAME>();
             md.vendor = device.getInfo<CL_DEVICE_VENDOR>();
-            printf("    using opencl device: %s\n", md.name.c_str());
+            //printf("    using opencl device: %s\n", md.name.c_str());
             try {
                 md.generators.insert({ GeneratorType::FLOAT, std::make_unique<ClGeneratorFloat>(device) });
             }