~verzegnassi-stefano/+junk/reboot-thumbnailer

« back to all changes in this revision

Viewing changes to src/app/renderengine.cpp

  • Committer: Stefano Verzegnassi
  • Date: 2016-01-07 22:12:07 UTC
  • mfrom: (176.2.82 lo-viewer)
  • Revision ID: stefano92.100@gmail.com-20160107221207-ybfpq4h5733jzen0
Merged parent branch

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "renderengine.h"
 
2
#include <QtConcurrent/QtConcurrent>
 
3
#include <QThread>
 
4
 
 
5
RenderEngine* RenderEngine::s_instance = nullptr;
 
6
 
 
7
RenderEngine::RenderEngine():
 
8
    QObject(nullptr)
 
9
    ,m_activeTaskCount(0)
 
10
    ,m_lastTask(nullptr)
 
11
{
 
12
    int itc = QThread::idealThreadCount();
 
13
    m_idealThreadCount = itc == -1 ? DefaultIdealThreadCount : itc;
 
14
 
 
15
    // For QMetaObject::invoke.
 
16
    qRegisterMetaType<AbstractRenderTask*>();
 
17
}
 
18
 
 
19
void RenderEngine::enqueueTask(AbstractRenderTask *task)
 
20
{
 
21
    m_queue.enqueue(task);
 
22
    doNextTask();
 
23
}
 
24
 
 
25
void RenderEngine::dequeueTask(int id)
 
26
{
 
27
    for (int i = 0; i < m_queue.size(); i++) {
 
28
        auto task = m_queue.at(i);
 
29
        if (task->id() == id) {
 
30
            m_queue.removeAt(i);
 
31
            disposeLater(task);
 
32
            break;
 
33
        }
 
34
    }
 
35
}
 
36
 
 
37
void RenderEngine::internalRenderCallback(AbstractRenderTask* task, QImage img)
 
38
{
 
39
    m_activeTaskCount--;
 
40
 
 
41
    if (!m_activeTaskCount) {
 
42
        m_lastTask = nullptr;
 
43
        doDispose();
 
44
    }
 
45
 
 
46
    // Notify about result.
 
47
    emit taskRenderFinished(task, img);
 
48
 
 
49
    doNextTask();
 
50
    disposeLater(task);
 
51
}
 
52
 
 
53
void RenderEngine::disposeLater(AbstractRenderTask *task)
 
54
{
 
55
    m_disposedTasks.append(task);
 
56
}
 
57
 
 
58
void RenderEngine::doDispose()
 
59
{
 
60
    for (int i = 0; i < m_disposedTasks.size(); ++i)
 
61
        delete m_disposedTasks.at(i);
 
62
    m_disposedTasks.clear();
 
63
}
 
64
 
 
65
void RenderEngine::doNextTask()
 
66
{
 
67
#ifdef DEBUG_VERBOSE
 
68
    qDebug() << " ---- doNextTask" << m_activeTaskCount << m_queue.count();
 
69
#endif
 
70
 
 
71
    // Check for too much threads or empty queue.
 
72
    if (m_activeTaskCount >= m_idealThreadCount || !m_queue.count())
 
73
        return;
 
74
 
 
75
    AbstractRenderTask* task = m_queue.head();
 
76
 
 
77
    // If some tasks already in progress, we should ask task about
 
78
    // compatibility of parallel execution with last the task.
 
79
    if (m_activeTaskCount && !task->canBeRunInParallel(m_lastTask))
 
80
        return;
 
81
 
 
82
    task->prepare();
 
83
 
 
84
    m_activeTaskCount++;
 
85
    m_lastTask = m_queue.dequeue();
 
86
 
 
87
    QtConcurrent::run( [=] {
 
88
        QImage img = task->doWork();
 
89
        QMetaObject::invokeMethod(this, "internalRenderCallback",
 
90
                                  Q_ARG(AbstractRenderTask*, task), Q_ARG(QImage, img));
 
91
    });
 
92
}