~uriboni/qt-halide/copyright-headers

« back to all changes in this revision

Viewing changes to backend/modules/QtHalide/halide_transform.cpp

  • Committer: Florian Boucault
  • Author(s): Florian Boucault
  • Date: 2015-04-02 12:36:12 UTC
  • mfrom: (268.4.33 async)
  • Revision ID: florian_boucault-20150402123612-7yfcsif9syv5e1cc
HalideTransform: apply Halide functions in a background thread.

Show diffs side-by-side

added added

removed removed

Lines of Context:
7
7
#include <QtCore/QDebug>
8
8
#include <QtCore/QStandardPaths>
9
9
#include <QtQuick/QQuickItem>
 
10
#include <QtConcurrent/QtConcurrent>
10
11
 
11
12
HalideTransform::HalideTransform(QObject *parent) :
12
13
    QObject(parent),
17
18
    m_input(0),
18
19
    m_output(new HalideImage(this)),
19
20
    m_window(0),
20
 
    m_parent(parent)
 
21
    m_parent(parent),
 
22
    m_updateInProgress(false),
 
23
    m_pendingUpdate(false),
 
24
    m_pendingRequiresImage(false)
21
25
{
22
26
    connect(m_functionsModel, SIGNAL(rowsInserted(QModelIndex,int,int)),
23
27
            this, SLOT(onFunctionsInserted(QModelIndex,int,int)));
33
37
        m_worker = new HalideTransformCpu(this);
34
38
    }
35
39
    connect(m_worker, SIGNAL(updateRequired()), this, SLOT(scheduleUpdate()), Qt::QueuedConnection);
 
40
    connect(m_worker, SIGNAL(computeFinished(QSharedPointer<HalideImageData>)),
 
41
            this, SLOT(onWorkedComputeFinished(QSharedPointer<HalideImageData>)), Qt::QueuedConnection);
36
42
    setupOpenGLContextMonitoring();
37
43
}
38
44
 
39
45
HalideTransform::~HalideTransform()
40
46
{
41
47
    if (m_worker) {
42
 
        delete m_worker;
 
48
        m_worker->deleteLater();
43
49
        m_worker = 0;
44
50
    }
45
51
    delete m_functionsModel;
229
235
        return;
230
236
    }
231
237
 
232
 
    QStringList functionsNames;
233
 
    Q_FOREACH(HalideFunction* function, m_functionsModel->toList()) {
234
 
        functionsNames.append(function->name());
 
238
    if (!m_updateInProgress) {
 
239
        m_updateFunctionNames.clear();
 
240
        Q_FOREACH(HalideFunction* function, m_functionsModel->toList()) {
 
241
            m_updateFunctionNames.append(function->name());
 
242
        }
 
243
        m_updateInProgress = true;
 
244
        m_updateTimer.start();
 
245
        Q_EMIT updatingChanged();
 
246
        m_worker->compute(m_input, m_functionsModel->toList(), outputImageRequired);
 
247
    } else {
 
248
        m_pendingUpdate = true;
 
249
        m_pendingRequiresImage = outputImageRequired;
235
250
    }
 
251
}
236
252
 
237
 
    m_updateTimer.start();
238
 
    Q_EMIT updatingChanged();
239
 
    m_worker->compute(m_input, m_functionsModel->toList(), m_output, outputImageRequired);
 
253
void HalideTransform::onWorkedComputeFinished(QSharedPointer<HalideImageData> result)
 
254
{
 
255
    m_output->setData(result);
240
256
 
241
257
    qDebug() << QString("\"%1\" applied in %2 ms (%3x%4)")
242
 
                .arg(functionsNames.join(" + "))
 
258
                .arg(m_updateFunctionNames.join(" + "))
243
259
                .arg(m_updateTimer.elapsed())
244
260
                .arg(m_output->size().width())
245
261
                .arg(m_output->size().height()).toLocal8Bit().constData();
246
262
    m_updateTimer.invalidate();
247
263
    Q_EMIT updatingChanged();
 
264
    m_updateInProgress = false;
 
265
 
 
266
    if (!m_pendingSaveFiles.isEmpty()) {
 
267
        QtConcurrent::run(this, &HalideTransform::saveImageToFiles, m_output->data()->image, m_pendingSaveFiles);
 
268
        m_pendingSaveFiles.clear();
 
269
    }
 
270
 
 
271
    if (m_pendingUpdate) {
 
272
        m_pendingUpdate = false;
 
273
        m_pendingRequiresImage = false;
 
274
        doUpdate(m_pendingRequiresImage);
 
275
    }
248
276
}
249
277
 
250
278
bool HalideTransform::saveToFile(QString fileName)
251
279
{
252
 
    doUpdate(true);
253
280
    QString directory = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation);
254
281
    QString filePath = directory + "/" + fileName;
255
 
    bool success = m_output->data()->image.save(filePath);
256
 
    if (!success) {
257
 
        qWarning() << "Failed to save image to file:" << filePath;
258
 
    }
259
 
 
260
 
    return success;
 
282
 
 
283
    if (fileName.isEmpty()) {
 
284
        qWarning() << "Empty file name to passed to HalideTransform::saveToFile";
 
285
        return false;
 
286
    }
 
287
 
 
288
    if (m_output->data()->image.isNull() || !m_live) {
 
289
        m_pendingSaveFiles.append(filePath);
 
290
        doUpdate(true);
 
291
        return true;
 
292
    } else {
 
293
        QtConcurrent::run(this, &HalideTransform::saveImageToFiles, m_output->data()->image, QStringList(filePath));
 
294
        return true;
 
295
    }
 
296
}
 
297
 
 
298
void HalideTransform::saveImageToFiles(QImage image, QStringList filePaths)
 
299
{
 
300
    bool success;
 
301
    Q_FOREACH(QString filePath, filePaths) {
 
302
        success = image.save(filePath);
 
303
        if (!success) {
 
304
            qWarning() << "Failed to save image to file:" << filePath;
 
305
        }
 
306
    }
261
307
}
262
308
 
263
309
QVariant HalideTransform::functions() const