1/****************************************************************************
2**
3** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt3D module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "qaspectjobmanager_p.h"
41
42#include <QtCore/QAtomicInt>
43#include <QtCore/QCoreApplication>
44#include <QtCore/QDebug>
45#include <QtCore/QThread>
46#include <QtCore/QFuture>
47#include <Qt3DCore/private/qaspectmanager_p.h>
48#include <Qt3DCore/private/qthreadpooler_p.h>
49#include <Qt3DCore/private/task_p.h>
50
51QT_BEGIN_NAMESPACE
52
53namespace Qt3DCore {
54
55QAspectJobManager::QAspectJobManager(QAspectManager *parent)
56 : QAbstractAspectJobManager(parent)
57 , m_threadPooler(new QThreadPooler(this))
58 , m_aspectManager(parent)
59{
60}
61
62QAspectJobManager::~QAspectJobManager()
63{
64}
65
66void QAspectJobManager::initialize()
67{
68}
69
70// Adds all Aspect Jobs to be processed for a frame
71void QAspectJobManager::enqueueJobs(const QVector<QAspectJobPtr> &jobQueue)
72{
73 auto systemService = m_aspectManager ? m_aspectManager->serviceLocator()->systemInformation() : nullptr;
74 if (systemService)
75 systemService->writePreviousFrameTraces();
76
77 // Convert QJobs to Tasks
78 QHash<QAspectJob *, AspectTaskRunnable *> tasksMap;
79 QVector<RunnableInterface *> taskList;
80 taskList.reserve(asize: jobQueue.size());
81 for (const QAspectJobPtr &job : jobQueue) {
82 AspectTaskRunnable *task = new AspectTaskRunnable(systemService);
83 task->m_job = job;
84 tasksMap.insert(akey: job.data(), avalue: task);
85
86 taskList << task;
87 }
88
89 for (const QAspectJobPtr &job : jobQueue) {
90 const QVector<QWeakPointer<QAspectJob> > &deps = job->dependencies();
91 AspectTaskRunnable *taskDepender = tasksMap.value(akey: job.data());
92
93 int dependerCount = 0;
94 for (const QWeakPointer<QAspectJob> &dep : deps) {
95 AspectTaskRunnable *taskDependee = tasksMap.value(akey: dep.toStrongRef().data());
96 // The dependencies here are not hard requirements, i.e., the dependencies
97 // not in the jobQueue should already have their data ready.
98 if (taskDependee) {
99 taskDependee->m_dependers.append(t: taskDepender);
100 ++dependerCount;
101 }
102 }
103
104 taskDepender->m_dependerCount += dependerCount;
105 }
106
107 m_threadPooler->mapDependables(taskQueue&: taskList);
108}
109
110// Wait for all aspects jobs to be completed
111int QAspectJobManager::waitForAllJobs()
112{
113 return m_threadPooler->waitForAllJobs();
114}
115
116void QAspectJobManager::waitForPerThreadFunction(JobFunction func, void *arg)
117{
118 const int threadCount = m_threadPooler->maxThreadCount();
119 QAtomicInt atomicCount(threadCount);
120
121 QVector<RunnableInterface *> taskList;
122 for (int i = 0; i < threadCount; ++i) {
123 SyncTaskRunnable *syncTask = new SyncTaskRunnable(func, arg, &atomicCount);
124 taskList << syncTask;
125 }
126
127 QFuture<void> future = m_threadPooler->mapDependables(taskQueue&: taskList);
128 future.waitForFinished();
129}
130
131} // namespace Qt3DCore
132
133QT_END_NAMESPACE
134

source code of qt3d/src/core/jobs/qaspectjobmanager.cpp