diff options
author | Sean Harmer <sean.harmer@kdab.com> | 2017-09-12 12:10:03 +0100 |
---|---|---|
committer | Sean Harmer <sean.harmer@kdab.com> | 2017-09-12 12:39:05 +0100 |
commit | 3f03499bf8a7cf3c3f8d19a020179c1205980bde (patch) | |
tree | 518b0ef3fb1b31d3856f43124150ef41acb8c1aa | |
parent | 8a4b9ebadb9e63ae367694f04786c7faf6306f27 (diff) | |
parent | bf5fd7a78c91e29332ce70ad844b756150f32f18 (diff) |
Merge branch '5.9' into 5.10
Change-Id: Id6a3d4ec579a2f2a2e559c22a2293d0e184f0bdf
59 files changed, 543 insertions, 1788 deletions
diff --git a/src/animation/backend/animationclip.cpp b/src/animation/backend/animationclip.cpp index 0f90ff493..daee4008d 100644 --- a/src/animation/backend/animationclip.cpp +++ b/src/animation/backend/animationclip.cpp @@ -40,6 +40,7 @@ #include <Qt3DAnimation/private/qanimationclip_p.h> #include <Qt3DAnimation/private/qanimationcliploader_p.h> #include <Qt3DAnimation/private/animationlogging_p.h> +#include <Qt3DAnimation/private/managers_p.h> #include <Qt3DRender/private/qurlhelper_p.h> #include <Qt3DCore/qpropertyupdatedchange.h> @@ -176,6 +177,24 @@ void AnimationClip::loadAnimation() setStatus(QAnimationClipLoader::Ready); } + // notify all ClipAnimators and BlendedClipAnimators that depend on this clip, + // that the clip has changed and that they are now dirty + { + QMutexLocker lock(&m_mutex); + for (const Qt3DCore::QNodeId id : qAsConst(m_dependingAnimators)) { + ClipAnimator *animator = m_handler->clipAnimatorManager()->lookupResource(id); + if (animator) + animator->animationClipMarkedDirty(); + } + for (const Qt3DCore::QNodeId id : qAsConst(m_dependingBlendedAnimators)) { + BlendedClipAnimator *animator = m_handler->blendedClipAnimatorManager()->lookupResource(id); + if (animator) + animator->animationClipMarkedDirty(); + } + m_dependingAnimators.clear(); + m_dependingBlendedAnimators.clear(); + } + qCDebug(Jobs) << "Loaded animation data:" << *this; } @@ -224,6 +243,18 @@ void AnimationClip::loadAnimationFromData() m_channels[i++].setFromQChannel(frontendChannel); } +void AnimationClip::addDependingClipAnimator(const Qt3DCore::QNodeId &id) +{ + QMutexLocker lock(&m_mutex); + m_dependingAnimators.push_back(id); +} + +void AnimationClip::addDependingBlendedClipAnimator(const Qt3DCore::QNodeId &id) +{ + QMutexLocker lock(&m_mutex); + m_dependingBlendedAnimators.push_back(id); +} + void AnimationClip::setDuration(float duration) { if (qFuzzyCompare(duration, m_duration)) diff --git a/src/animation/backend/animationclip_p.h b/src/animation/backend/animationclip_p.h index 5e5d54ac8..9eb94d45e 100644 --- a/src/animation/backend/animationclip_p.h +++ b/src/animation/backend/animationclip_p.h @@ -53,6 +53,7 @@ #include <Qt3DAnimation/qanimationcliploader.h> #include <Qt3DAnimation/private/fcurve_p.h> #include <QtCore/qurl.h> +#include <QtCore/qmutex.h> QT_BEGIN_NAMESPACE @@ -73,6 +74,9 @@ public: QAnimationClipLoader::Status status() const { return m_status; } void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) Q_DECL_OVERRIDE; + void addDependingClipAnimator(const Qt3DCore::QNodeId &id); + void addDependingBlendedClipAnimator(const Qt3DCore::QNodeId &id); + QString name() const { return m_name; } const QVector<Channel> &channels() const { return m_channels; } @@ -106,6 +110,8 @@ private: float findDuration(); int findChannelComponentCount(); + QMutex m_mutex; + QUrl m_source; QAnimationClipLoader::Status m_status; QAnimationClipData m_clipData; @@ -115,6 +121,9 @@ private: QVector<Channel> m_channels; float m_duration; int m_channelComponentCount; + + Qt3DCore::QNodeIdVector m_dependingAnimators; + Qt3DCore::QNodeIdVector m_dependingBlendedAnimators; }; #ifndef QT_NO_DEBUG_STREAM diff --git a/src/animation/backend/blendedclipanimator_p.h b/src/animation/backend/blendedclipanimator_p.h index e15a892bb..d9f89b5f9 100644 --- a/src/animation/backend/blendedclipanimator_p.h +++ b/src/animation/backend/blendedclipanimator_p.h @@ -94,6 +94,8 @@ public: void sendPropertyChanges(const QVector<Qt3DCore::QSceneChangePtr> &changes); void sendCallbacks(const QVector<AnimationCallbackAndValue> &callbacks); + void animationClipMarkedDirty() { setDirty(Handler::BlendedClipAnimatorDirty); } + private: void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) Q_DECL_FINAL; Qt3DCore::QNodeId m_blendTreeRootId; diff --git a/src/animation/backend/buildblendtreesjob.cpp b/src/animation/backend/buildblendtreesjob.cpp index fe56099a2..f35280cbf 100644 --- a/src/animation/backend/buildblendtreesjob.cpp +++ b/src/animation/backend/buildblendtreesjob.cpp @@ -95,7 +95,7 @@ void BuildBlendTreesJob::run() Q_ASSERT(valueNode); const Qt3DCore::QNodeId clipId = valueNode->clipId(); - const AnimationClip *clip = m_handler->animationClipLoaderManager()->lookupResource(clipId); + AnimationClip *clip = m_handler->animationClipLoaderManager()->lookupResource(clipId); Q_ASSERT(clip); const ComponentIndices formatIndices @@ -103,6 +103,9 @@ void BuildBlendTreesJob::run() channelComponentIndices, clip); valueNode->setFormatIndices(blendClipAnimator->peerId(), formatIndices); + + // this BlendClipAnimator needs to be notified when the clip has been loaded + clip->addDependingBlendedClipAnimator(blendClipAnimator->peerId()); } // Finally, build the mapping data vector for this blended clip animator. This diff --git a/src/animation/backend/clipanimator.cpp b/src/animation/backend/clipanimator.cpp index 9a5cce2e2..2f4dca63f 100644 --- a/src/animation/backend/clipanimator.cpp +++ b/src/animation/backend/clipanimator.cpp @@ -78,6 +78,11 @@ void ClipAnimator::setClipId(Qt3DCore::QNodeId clipId) { m_clipId = clipId; setDirty(Handler::ClipAnimatorDirty); + + // register at the clip to make sure we are marked dirty when the clip finished loading + AnimationClip *clip = m_handler->animationClipLoaderManager()->lookupResource(clipId); + if (clip) + clip->addDependingClipAnimator(peerId()); } void ClipAnimator::setMapperId(Qt3DCore::QNodeId mapperId) diff --git a/src/animation/backend/clipanimator_p.h b/src/animation/backend/clipanimator_p.h index 628a15e24..b3389f8da 100644 --- a/src/animation/backend/clipanimator_p.h +++ b/src/animation/backend/clipanimator_p.h @@ -95,6 +95,8 @@ public: void sendPropertyChanges(const QVector<Qt3DCore::QSceneChangePtr> &changes); void sendCallbacks(const QVector<AnimationCallbackAndValue> &callbacks); + void animationClipMarkedDirty() { setDirty(Handler::ClipAnimatorDirty); } + private: void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) Q_DECL_FINAL; diff --git a/src/animation/backend/handler.cpp b/src/animation/backend/handler.cpp index b8e89703e..071343791 100644 --- a/src/animation/backend/handler.cpp +++ b/src/animation/backend/handler.cpp @@ -77,24 +77,28 @@ void Handler::setDirty(DirtyFlag flag, Qt3DCore::QNodeId nodeId) { switch (flag) { case AnimationClipDirty: { + QMutexLocker lock(&m_mutex); const auto handle = m_animationClipLoaderManager->lookupHandle(nodeId); m_dirtyAnimationClips.push_back(handle); break; } case ChannelMappingsDirty: { + QMutexLocker lock(&m_mutex); const auto handle = m_channelMapperManager->lookupHandle(nodeId); m_dirtyChannelMappers.push_back(handle); break; } case ClipAnimatorDirty: { + QMutexLocker lock(&m_mutex); const auto handle = m_clipAnimatorManager->lookupHandle(nodeId); m_dirtyClipAnimators.push_back(handle); break; } case BlendedClipAnimatorDirty: { + QMutexLocker lock(&m_mutex); const HBlendedClipAnimator handle = m_blendedClipAnimatorManager->lookupHandle(nodeId); m_dirtyBlendedAnimators.push_back(handle); break; @@ -174,6 +178,8 @@ QVector<Qt3DCore::QAspectJobPtr> Handler::jobsToExecute(qint64 time) QVector<Qt3DCore::QAspectJobPtr> jobs; + QMutexLocker lock(&m_mutex); + // If there are any dirty animation clips that need loading, // queue up a job for them if (!m_dirtyAnimationClips.isEmpty()) { diff --git a/src/animation/backend/handler_p.h b/src/animation/backend/handler_p.h index 0dccdae75..d35d5a132 100644 --- a/src/animation/backend/handler_p.h +++ b/src/animation/backend/handler_p.h @@ -53,6 +53,7 @@ #include <Qt3DCore/qaspectjob.h> #include <Qt3DCore/qnodeid.h> #include <QtCore/qscopedpointer.h> +#include <QtCore/qmutex.h> QT_BEGIN_NAMESPACE @@ -124,6 +125,7 @@ public: void cleanupHandleList(QVector<HBlendedClipAnimator> *animators); private: + QMutex m_mutex; QScopedPointer<AnimationClipLoaderManager> m_animationClipLoaderManager; QScopedPointer<ClockManager> m_clockManager; QScopedPointer<ClipAnimatorManager> m_clipAnimatorManager; diff --git a/src/animation/backend/managers_p.h b/src/animation/backend/managers_p.h index c5f3cafba..b88f1b8ae 100644 --- a/src/animation/backend/managers_p.h +++ b/src/animation/backend/managers_p.h @@ -72,8 +72,7 @@ class ClipBlendNode; class AnimationClipLoaderManager : public Qt3DCore::QResourceManager< AnimationClip, Qt3DCore::QNodeId, - 16, - Qt3DCore::ArrayAllocatingPolicy> + 16> { public: AnimationClipLoaderManager() {} @@ -82,8 +81,7 @@ public: class ClockManager : public Qt3DCore::QResourceManager< Clock, Qt3DCore::QNodeId, - 16, - Qt3DCore::ArrayAllocatingPolicy> + 16> { public: ClockManager() {} @@ -92,8 +90,7 @@ public: class ClipAnimatorManager : public Qt3DCore::QResourceManager< ClipAnimator, Qt3DCore::QNodeId, - 16, - Qt3DCore::ArrayAllocatingPolicy> + 16> { public: ClipAnimatorManager() {} @@ -102,8 +99,7 @@ public: class BlendedClipAnimatorManager : public Qt3DCore::QResourceManager< BlendedClipAnimator, Qt3DCore::QNodeId, - 12, - Qt3DCore::ArrayAllocatingPolicy> + 12> { public: BlendedClipAnimatorManager() {} @@ -112,8 +108,7 @@ public: class ChannelMappingManager : public Qt3DCore::QResourceManager< ChannelMapping, Qt3DCore::QNodeId, - 16, - Qt3DCore::ArrayAllocatingPolicy> + 16> { public: ChannelMappingManager() {} @@ -122,8 +117,7 @@ public: class ChannelMapperManager : public Qt3DCore::QResourceManager< ChannelMapper, Qt3DCore::QNodeId, - 16, - Qt3DCore::ArrayAllocatingPolicy> + 16> { public: ChannelMapperManager() {} @@ -147,8 +141,7 @@ private: class SkeletonManager : public Qt3DCore::QResourceManager< Skeleton, Qt3DCore::QNodeId, - 16, - Qt3DCore::ArrayAllocatingPolicy> + 16> { public: SkeletonManager() {} diff --git a/src/core/jobs/dependencyhandler.cpp b/src/core/jobs/dependencyhandler.cpp deleted file mode 100644 index 6a925d037..000000000 --- a/src/core/jobs/dependencyhandler.cpp +++ /dev/null @@ -1,157 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "dependencyhandler_p.h" - -#include <iterator> - -QT_BEGIN_NAMESPACE - -namespace Qt3DCore { - -namespace { - template <template <typename T> class Op> - struct ByDepender { - typedef bool result_type; - - bool operator()(const RunnableInterface *lhs, const RunnableInterface *rhs) const Q_DECL_NOTHROW - { return Op<const RunnableInterface *>()(lhs, rhs); } - - bool operator()(const RunnableInterface *lhs, const Dependency &rhs) const Q_DECL_NOTHROW - { return operator()(lhs, rhs.depender); } - - bool operator()(const Dependency &lhs, const RunnableInterface *rhs) const Q_DECL_NOTHROW - { return operator()(lhs.depender, rhs); } - - bool operator()(const Dependency &lhs, const Dependency &rhs) const Q_DECL_NOTHROW - { return operator()(lhs.depender, rhs.depender); } - }; - - struct DependeeEquals : std::unary_function<Dependency, bool> - { - const RunnableInterface *dependee; - QVector<RunnableInterface *> *freedList; - explicit DependeeEquals(const RunnableInterface *dependee, QVector<RunnableInterface *> *freedList) - : dependee(qMove(dependee)), freedList(qMove(freedList)) {} - bool operator()(const Dependency &candidate) const - { - if (dependee == candidate.dependee) { - if (!candidate.depender->reserved()) - freedList->append(candidate.depender); - return true; - } - return false; - } - }; - - struct DependerEquals : std::unary_function<Dependency, bool> - { - const RunnableInterface *depender; - explicit DependerEquals(const RunnableInterface *depender) - : depender(qMove(depender)) {} - bool operator()(const Dependency &candidate) const - { - return depender == candidate.depender; - } - }; - - struct ByDependerThenDependee : std::binary_function<Dependency, Dependency, bool> - { - // Defines a lexicographical order (depender first). - bool operator()(const Dependency &lhs, const Dependency &rhs) - { - if (lhs.depender < rhs.depender) return true; - if (rhs.depender < lhs.depender) return false; - return lhs.dependee < rhs.dependee; - } - }; -} - -DependencyHandler::DependencyHandler() - : m_mutex() -{ -} - -void DependencyHandler::addDependencies(QVector<Dependency> dependencies) -{ - std::sort(dependencies.begin(), dependencies.end(), ByDependerThenDependee()); - - const QMutexLocker locker(m_mutex); - - QVector<Dependency> newDependencyMap; - newDependencyMap.reserve(dependencies.size() + m_dependencyMap.size()); - std::set_union(m_dependencyMap.begin(), m_dependencyMap.end(), - dependencies.begin(), dependencies.end(), - std::back_inserter(newDependencyMap), ByDependerThenDependee()); - m_dependencyMap.swap(newDependencyMap); // commit -} - -bool DependencyHandler::hasDependency(const RunnableInterface *depender) -{ - // The caller has to set the mutex, which is QThreadPooler::enqueueTasks - - return std::binary_search(m_dependencyMap.begin(), m_dependencyMap.end(), - depender, ByDepender<std::less>()); -} - -/* - * Removes all the entries on the m_dependencyMap that have given task as a dependee, - * i.e. entries where the dependency is on the given task. - */ -QVector<RunnableInterface *> DependencyHandler::freeDependencies(const RunnableInterface *task) -{ - // The caller has to set the mutex, which is QThreadPooler::taskFinished - - m_dependencyMap.erase(std::remove_if(m_dependencyMap.begin(), - m_dependencyMap.end(), - DependerEquals(task)), - m_dependencyMap.end()); - - QVector<RunnableInterface *> freedList; - m_dependencyMap.erase(std::remove_if(m_dependencyMap.begin(), - m_dependencyMap.end(), - DependeeEquals(task, &freedList)), - m_dependencyMap.end()); - - return freedList; -} - -} // namespace Qt3DCore - -QT_END_NAMESPACE diff --git a/src/core/jobs/dependencyhandler_p.h b/src/core/jobs/dependencyhandler_p.h deleted file mode 100644 index a5a023139..000000000 --- a/src/core/jobs/dependencyhandler_p.h +++ /dev/null @@ -1,116 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DCORE_DEPENDENCYHANDLER_P_H -#define QT3DCORE_DEPENDENCYHANDLER_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCore/QMutex> -#include <QtCore/QVector> - -#include <Qt3DCore/private/task_p.h> - -QT_BEGIN_NAMESPACE - -namespace Qt3DCore { - -struct Dependency -{ - Dependency() - : depender(nullptr) - , dependee(nullptr) - {} - Dependency(RunnableInterface *depender, RunnableInterface *dependee) - : depender(qMove(depender)), - dependee(qMove(dependee)) {} - - RunnableInterface *depender; - RunnableInterface *dependee; -}; - -} // namespace Qt3DCore - -template <> -class QTypeInfo<Qt3DCore::Dependency> : public QTypeInfoMerger<Qt3DCore::Dependency, Qt3DCore::RunnableInterface *> {}; - -namespace Qt3DCore { - -inline bool operator==(const Dependency &left, const Dependency &right) -{ - return left.depender == right.depender && left.dependee == right.dependee; -} - -inline bool operator!=(const Dependency &left, const Dependency &right) -{ - return !operator==(left, right); -} - -class DependencyHandler -{ -public: - DependencyHandler(); - - void addDependencies(QVector<Dependency> dependencies); - bool hasDependency(const RunnableInterface *depender); - QVector<RunnableInterface *> freeDependencies(const RunnableInterface *task); - void setMutex(QMutex *mutex) { m_mutex = mutex; } - -private: - Q_DISABLE_COPY(DependencyHandler) - - QVector<Dependency> m_dependencyMap; - QMutex *m_mutex; -}; - -} // namespace Qt3DCore - -QT_END_NAMESPACE - -#endif // QT3DCORE_DEPENDENCYHANDLER_P_H - diff --git a/src/core/jobs/jobs.pri b/src/core/jobs/jobs.pri index d12c42237..5d262f5c7 100644 --- a/src/core/jobs/jobs.pri +++ b/src/core/jobs/jobs.pri @@ -4,8 +4,7 @@ SOURCES += \ $$PWD/qaspectjobmanager.cpp \ $$PWD/qabstractaspectjobmanager.cpp \ $$PWD/qthreadpooler.cpp \ - $$PWD/task.cpp \ - $$PWD/dependencyhandler.cpp + $$PWD/task.cpp HEADERS += \ $$PWD/qaspectjob.h \ @@ -13,7 +12,6 @@ HEADERS += \ $$PWD/qaspectjobproviderinterface_p.h \ $$PWD/qaspectjobmanager_p.h \ $$PWD/qabstractaspectjobmanager_p.h \ - $$PWD/dependencyhandler_p.h \ $$PWD/task_p.h \ $$PWD/qthreadpooler_p.h diff --git a/src/core/jobs/qaspectjobmanager.cpp b/src/core/jobs/qaspectjobmanager.cpp index e543b60a2..328899433 100644 --- a/src/core/jobs/qaspectjobmanager.cpp +++ b/src/core/jobs/qaspectjobmanager.cpp @@ -45,7 +45,6 @@ #include <QtCore/QThread> #include <QtCore/QFuture> -#include <Qt3DCore/private/dependencyhandler_p.h> #include <Qt3DCore/private/qthreadpooler_p.h> #include <Qt3DCore/private/task_p.h> @@ -56,9 +55,7 @@ namespace Qt3DCore { QAspectJobManager::QAspectJobManager(QObject *parent) : QAbstractAspectJobManager(parent) , m_threadPooler(new QThreadPooler(this)) - , m_dependencyHandler(new DependencyHandler) { - m_threadPooler->setDependencyHandler(m_dependencyHandler.data()); } QAspectJobManager::~QAspectJobManager() @@ -84,24 +81,24 @@ void QAspectJobManager::enqueueJobs(const QVector<QAspectJobPtr> &jobQueue) taskList << task; } - // Resolve dependencies - QVector<Dependency> dependencyList; - for (const QSharedPointer<QAspectJob> &job : jobQueue) { const QVector<QWeakPointer<QAspectJob> > &deps = job->dependencies(); + AspectTaskRunnable *taskDepender = tasksMap.value(job.data()); + int dependerCount = 0; for (const QWeakPointer<QAspectJob> &dep : deps) { AspectTaskRunnable *taskDependee = tasksMap.value(dep.data()); - + // The dependencies here are not hard requirements, i.e., the dependencies + // not in the jobQueue should already have their data ready. if (taskDependee) { - AspectTaskRunnable *taskDepender = tasksMap.value(job.data()); - dependencyList.append(Dependency(taskDepender, taskDependee)); - taskDepender->setDependencyHandler(m_dependencyHandler.data()); - taskDependee->setDependencyHandler(m_dependencyHandler.data()); + taskDependee->m_dependers.append(taskDepender); + ++dependerCount; } } + + taskDepender->m_dependerCount += dependerCount; } - m_dependencyHandler->addDependencies(qMove(dependencyList)); + #if QT_CONFIG(qt3d_profile_jobs) QThreadPooler::writeFrameJobLogStats(); #endif diff --git a/src/core/jobs/qaspectjobmanager_p.h b/src/core/jobs/qaspectjobmanager_p.h index 6fbf03d22..fac71f057 100644 --- a/src/core/jobs/qaspectjobmanager_p.h +++ b/src/core/jobs/qaspectjobmanager_p.h @@ -81,7 +81,6 @@ public: private: QThreadPooler *m_threadPooler; - QScopedPointer<DependencyHandler> m_dependencyHandler; }; } // namespace Qt3DCore diff --git a/src/core/jobs/qthreadpooler.cpp b/src/core/jobs/qthreadpooler.cpp index 57a1b09a6..6819faca7 100644 --- a/src/core/jobs/qthreadpooler.cpp +++ b/src/core/jobs/qthreadpooler.cpp @@ -48,8 +48,6 @@ #include <QtCore/QCoreApplication> #endif -#include <Qt3DCore/private/dependencyhandler_p.h> - QT_BEGIN_NAMESPACE namespace Qt3DCore { @@ -62,7 +60,6 @@ QThreadPooler::QThreadPooler(QObject *parent) : QObject(parent) , m_futureInterface(nullptr) , m_mutex() - , m_dependencyHandler(nullptr) , m_taskCount(0) { const QByteArray maxThreadCount = qgetenv("QT3D_MAX_THREAD_COUNT"); @@ -86,12 +83,6 @@ QThreadPooler::~QThreadPooler() locker.unlock(); } -void QThreadPooler::setDependencyHandler(DependencyHandler *handler) -{ - m_dependencyHandler = handler; - m_dependencyHandler->setMutex(&m_mutex); -} - void QThreadPooler::enqueueTasks(const QVector<RunnableInterface *> &tasks) { // The caller have to set the mutex @@ -99,7 +90,14 @@ void QThreadPooler::enqueueTasks(const QVector<RunnableInterface *> &tasks) for (QVector<RunnableInterface *>::const_iterator it = tasks.cbegin(); it != end; ++it) { - if (!m_dependencyHandler->hasDependency((*it)) && !(*it)->reserved()) { + + // Only AspectTaskRunnables are checked for dependencies. + static const auto hasDependencies = [](RunnableInterface *task) -> bool { + return (task->type() == RunnableInterface::RunnableType::AspectTask) + && (static_cast<AspectTaskRunnable *>(task)->m_dependerCount > 0); + }; + + if (!hasDependencies(*it) && !(*it)->reserved()) { (*it)->setReserved(true); (*it)->setPooler(this); m_threadPool.start((*it)); @@ -113,10 +111,19 @@ void QThreadPooler::taskFinished(RunnableInterface *task) release(); - if (task->dependencyHandler()) { - const QVector<RunnableInterface *> freedTasks = m_dependencyHandler->freeDependencies(task); - if (!freedTasks.empty()) - enqueueTasks(freedTasks); + if (task->type() == RunnableInterface::RunnableType::AspectTask) { + AspectTaskRunnable *aspectTask = static_cast<AspectTaskRunnable *>(task); + const auto &dependers = aspectTask->m_dependers; + for (auto it = dependers.begin(); it != dependers.end(); ++it) { + aspectTask = static_cast<AspectTaskRunnable *>(*it); + if (--aspectTask->m_dependerCount == 0) { + if (!aspectTask->reserved()) { + aspectTask->setReserved(true); + aspectTask->setPooler(this); + m_threadPool.start(aspectTask); + } + } + } } if (currentCount() == 0) { diff --git a/src/core/jobs/qthreadpooler_p.h b/src/core/jobs/qthreadpooler_p.h index 5a2104cdd..00742f8fc 100644 --- a/src/core/jobs/qthreadpooler_p.h +++ b/src/core/jobs/qthreadpooler_p.h @@ -57,7 +57,6 @@ #include <QtCore/QSharedPointer> #include <QtCore/QThreadPool> -#include <Qt3DCore/private/dependencyhandler_p.h> #include <Qt3DCore/private/qaspectjob_p.h> #include <Qt3DCore/private/task_p.h> @@ -81,8 +80,6 @@ public: void taskFinished(RunnableInterface *task); QFuture<void> future(); - void setDependencyHandler(DependencyHandler *handler); - int maxThreadCount() const; #if QT_CONFIG(qt3d_profile_jobs) static QElapsedTimer m_jobsStatTimer; @@ -105,7 +102,6 @@ private: private: QFutureInterface<void> *m_futureInterface; QMutex m_mutex; - DependencyHandler *m_dependencyHandler; QAtomicInt m_taskCount; QThreadPool m_threadPool; }; diff --git a/src/core/jobs/task.cpp b/src/core/jobs/task.cpp index cbaa993b1..4291a4779 100644 --- a/src/core/jobs/task.cpp +++ b/src/core/jobs/task.cpp @@ -43,7 +43,6 @@ #include <QtCore/QElapsedTimer> #include <QtCore/QMutexLocker> -#include <Qt3DCore/private/dependencyhandler_p.h> #include <Qt3DCore/private/qthreadpooler_p.h> QT_BEGIN_NAMESPACE @@ -57,8 +56,7 @@ RunnableInterface::~RunnableInterface() // Aspect task AspectTaskRunnable::AspectTaskRunnable() - : m_dependencyHandler(nullptr) - , m_pooler(nullptr) + : m_pooler(nullptr) , m_reserved(false) { } @@ -94,16 +92,6 @@ void AspectTaskRunnable::run() m_pooler->taskFinished(this); } -void AspectTaskRunnable::setDependencyHandler(DependencyHandler *handler) -{ - m_dependencyHandler = handler; -} - -DependencyHandler *AspectTaskRunnable::dependencyHandler() -{ - return m_dependencyHandler; -} - // Synchronized task SyncTaskRunnable::SyncTaskRunnable(QAbstractAspectJobManager::JobFunction func, @@ -137,16 +125,6 @@ void SyncTaskRunnable::run() m_pooler->taskFinished(this); } -void SyncTaskRunnable::setDependencyHandler(DependencyHandler *handler) -{ - Q_UNUSED(handler); -} - -DependencyHandler *SyncTaskRunnable::dependencyHandler() -{ - return nullptr; -} - } // namespace Qt3DCore { QT_END_NAMESPACE diff --git a/src/core/jobs/task_p.h b/src/core/jobs/task_p.h index 8193abaf6..91e3f5f3d 100644 --- a/src/core/jobs/task_p.h +++ b/src/core/jobs/task_p.h @@ -69,13 +69,15 @@ class QThreadPooler; class RunnableInterface : public QRunnable { public: + enum class RunnableType { + AspectTask, + SyncTask + }; + virtual ~RunnableInterface(); virtual void run() = 0; - virtual void setDependencyHandler(DependencyHandler *) = 0; - virtual DependencyHandler *dependencyHandler() = 0; - virtual int id() = 0; virtual void setId(int id) = 0; @@ -83,6 +85,8 @@ public: virtual bool reserved() = 0; virtual void setPooler(QThreadPooler *pooler) = 0; + + virtual RunnableType type() const = 0; }; class AspectTaskRunnable : public RunnableInterface @@ -93,9 +97,6 @@ public: void run() Q_DECL_OVERRIDE; - void setDependencyHandler(DependencyHandler *handler) Q_DECL_OVERRIDE; - DependencyHandler *dependencyHandler() Q_DECL_OVERRIDE; - void setPooler(QThreadPooler *pooler) Q_DECL_OVERRIDE { m_pooler = pooler; } void setReserved(bool reserved) Q_DECL_OVERRIDE { m_reserved = reserved; } @@ -104,15 +105,17 @@ public: int id() Q_DECL_OVERRIDE { return m_id; } void setId(int id) Q_DECL_OVERRIDE { m_id = id; } + RunnableType type() const Q_DECL_OVERRIDE { return RunnableType::AspectTask; } + public: QSharedPointer<QAspectJob> m_job; + QVector<AspectTaskRunnable *> m_dependers; + int m_dependerCount = 0; private: - DependencyHandler *m_dependencyHandler; QThreadPooler *m_pooler; - bool m_reserved; - int m_id; // For testing purposes for now + bool m_reserved; }; class SyncTaskRunnable : public RunnableInterface @@ -124,9 +127,6 @@ public: void run() Q_DECL_OVERRIDE; - void setDependencyHandler(DependencyHandler *handler) Q_DECL_OVERRIDE; - DependencyHandler *dependencyHandler() Q_DECL_OVERRIDE; - void setPooler(QThreadPooler *pooler) Q_DECL_OVERRIDE { m_pooler = pooler; } void setReserved(bool reserved) Q_DECL_OVERRIDE { m_reserved = reserved; } @@ -135,6 +135,8 @@ public: int id() Q_DECL_OVERRIDE { return m_id; } void setId(int id) Q_DECL_OVERRIDE { m_id = id; } + RunnableType type() const Q_DECL_OVERRIDE { return RunnableType::SyncTask; } + private: QAbstractAspectJobManager::JobFunction m_func; void *m_arg; diff --git a/src/core/resources/qhandle_p.h b/src/core/resources/qhandle_p.h index 94dc7ca45..c4b53ec21 100644 --- a/src/core/resources/qhandle_p.h +++ b/src/core/resources/qhandle_p.h @@ -53,6 +53,7 @@ #include <Qt3DCore/qt3dcore_global.h> #include <QtCore/QDebug> +#include <limits.h> class tst_Handle; // needed for friend class declaration below @@ -60,9 +61,6 @@ QT_BEGIN_NAMESPACE namespace Qt3DCore { -template <typename T, uint INDEXBITS> -class QHandleManager; - template <typename T, uint INDEXBITS = 16> class QHandle { @@ -82,18 +80,6 @@ public: static quint32 maxIndex() { return MaxIndex; } static quint32 maxCounter() { return MaxCounter; } - -private: - enum { - // Sizes to use for bit fields - IndexBits = INDEXBITS, - CounterBits = 32 - INDEXBITS - 2, // We use 2 bits for book-keeping in QHandleManager - - // Sizes to compare against for asserting dereferences - MaxIndex = (1 << IndexBits) - 1, - MaxCounter = (1 << CounterBits) - 1 - }; - QHandle(quint32 i, quint32 count) { d.m_index = i; @@ -103,10 +89,17 @@ private: Q_ASSERT(count < MaxCounter); } + enum { + // Sizes to use for bit fields + IndexBits = INDEXBITS, + CounterBits = 32 - INDEXBITS - 2, // We use 2 bits for book-keeping in QHandleManager - friend class QHandleManager<T, INDEXBITS>; - friend class ::tst_Handle; + // Sizes to compare against for asserting dereferences + MaxIndex = (1 << IndexBits) - 1, + MaxCounter = ((1 << CounterBits) - 1 > SHRT_MAX) ? SHRT_MAX - 1 : (1 << CounterBits) - 1 + }; +private: struct Data { quint32 m_index : IndexBits; quint32 m_counter : CounterBits; diff --git a/src/core/resources/qhandlemanager_p.h b/src/core/resources/qhandlemanager_p.h deleted file mode 100644 index 0c3609bb9..000000000 --- a/src/core/resources/qhandlemanager_p.h +++ /dev/null @@ -1,263 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DCORE_QHANDLEMANAGER_P_H -#define QT3DCORE_QHANDLEMANAGER_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <Qt3DCore/qt3dcore_global.h> -#include <QtCore/QtGlobal> -#include <QtCore/QVector> - -#include <Qt3DCore/private/qhandle_p.h> - -QT_BEGIN_NAMESPACE - -namespace Qt3DCore { - -#ifndef QT_NO_DEBUG_STREAM -template <typename T, uint INDEXBITS> -class QHandleManager; - -template <typename T, uint INDEXBITS = 16> -QDebug operator<<(QDebug dbg, const QHandleManager<T, INDEXBITS> &manager); -#endif - -template <typename T, uint INDEXBITS = 16> -class QHandleManager -{ -public: - QHandleManager() - : m_firstFreeEntry(0) - , m_activeEntryCount(0) - , m_entries(1 << INDEXBITS) - { - reset(); - } - - quint32 activeEntries() const { return m_activeEntryCount; } - - void reset(); - QHandle<T, INDEXBITS> acquire(T *d); - void release(const QHandle<T, INDEXBITS> &handle); - void update(const QHandle<T, INDEXBITS> &, T *d); - T *data(const QHandle<T, INDEXBITS> &handle, bool *ok = 0); - const T *constData(const QHandle<T, INDEXBITS> &handle, bool *ok = 0) const; - QVector<T *> entries() const; - -private: - Q_DISABLE_COPY(QHandleManager) - - friend QDebug operator<< <>(QDebug dbg, const QHandleManager<T, INDEXBITS> &manager); - - template <typename U> - struct HandleEntry - { - HandleEntry() - : m_data(nullptr) - , m_nextFreeIndex(0) - , m_counter(0) - , m_active(false) - , m_endOfFreeList(false) - {} - - explicit HandleEntry(quint32 nextFreeIndex) - : m_data(nullptr) - , m_nextFreeIndex(nextFreeIndex) - , m_counter(0) - , m_active(false) - , m_endOfFreeList(false) - {} - - U *m_data; - unsigned int m_nextFreeIndex : QHandle<U, INDEXBITS>::IndexBits; - unsigned int m_counter : QHandle<U, INDEXBITS>::CounterBits; - unsigned int m_active : 1; - unsigned int m_endOfFreeList : 1; - }; - - quint32 m_firstFreeEntry; - int m_activeEntryCount; - QVector<HandleEntry<T> > m_entries; -}; - -template <typename T, uint INDEXBITS> -void QHandleManager<T, INDEXBITS>::reset() -{ - m_activeEntryCount = 0; - m_firstFreeEntry = 0; - - for (int i = 0; i < QHandle<T, INDEXBITS >::MaxIndex; ++i) - m_entries[i] = HandleEntry<T>(i + 1); - m_entries[QHandle<T, INDEXBITS>::MaxIndex] = HandleEntry<T>(); - m_entries[QHandle<T, INDEXBITS>::MaxIndex].m_endOfFreeList = true; -} - -template <typename T, uint INDEXBITS> -QHandle<T, INDEXBITS> QHandleManager<T, INDEXBITS>::acquire(T *d) -{ - typedef QHandle<T, INDEXBITS> qHandle; - Q_ASSERT(m_activeEntryCount < qHandle::MaxIndex); - - const quint32 newIndex = m_firstFreeEntry; - Q_ASSERT(newIndex < qHandle::MaxIndex); - Q_ASSERT(m_entries[newIndex].m_active == false); - Q_ASSERT(!m_entries[newIndex].m_endOfFreeList); - - m_firstFreeEntry = m_entries[newIndex].m_nextFreeIndex; - m_entries[newIndex].m_nextFreeIndex = 0; - ++m_entries[newIndex].m_counter; - // Check if the counter is about to overflow and reset if necessary - if (m_entries[newIndex].m_counter == qHandle::MaxCounter) - m_entries[newIndex].m_counter = 0; - if (m_entries[newIndex].m_counter == 0) - m_entries[newIndex].m_counter = 1; - m_entries[newIndex].m_active = true; - m_entries[newIndex].m_data = d; - - ++m_activeEntryCount; - - return qHandle(newIndex, m_entries[newIndex].m_counter); -} - -template <typename T, uint INDEXBITS> -void QHandleManager<T, INDEXBITS>::release(const QHandle<T, INDEXBITS> &handle) -{ - const quint32 index = handle.index(); - Q_ASSERT(m_entries[index].m_counter == handle.counter()); - Q_ASSERT(m_entries[index].m_active == true); - - m_entries[index].m_nextFreeIndex = m_firstFreeEntry; - m_entries[index].m_active = false; - m_firstFreeEntry = index; - - --m_activeEntryCount; -} - -// Needed in case the QResourceManager has reordered -// memory so that the handle still points to valid data -template <typename T, uint INDEXBITS> -void QHandleManager<T, INDEXBITS>::update(const QHandle<T, INDEXBITS> &handle, T *d) -{ - const quint32 index = handle.index(); - Q_ASSERT(m_entries[index].m_counter == handle.counter()); - Q_ASSERT(m_entries[index].m_active == true); - m_entries[index].m_data = d; -} - -template <typename T, uint INDEXBITS> -T *QHandleManager<T, INDEXBITS>::data(const QHandle<T, INDEXBITS> &handle, bool *ok) -{ - const quint32 index = handle.index(); - if (m_entries[index].m_counter != handle.counter() || - m_entries[index].m_active == false) { - if (ok) - *ok = false; - return nullptr; - } - - T *d = m_entries[index].m_data; - if (ok) - *ok = true; - return d; -} - -template <typename T, uint INDEXBITS> -const T *QHandleManager<T, INDEXBITS>::constData(const QHandle<T, INDEXBITS> &handle, bool *ok) const -{ - const quint32 index = handle.index(); - if (m_entries[index].m_counter != handle.counter() || - m_entries[index].m_active == false) { - if (ok) - *ok = false; - return nullptr; - } - - const T *d = m_entries[index].m_data; - if (ok) - *ok = true; - return d; -} - -#ifndef QT_NO_DEBUG_STREAM -template <typename T, uint INDEXBITS> -QDebug operator<<(QDebug dbg, const QHandleManager<T, INDEXBITS> &manager) -{ - QDebugStateSaver saver(dbg); - dbg << "First free entry =" << manager.m_firstFreeEntry << endl; - - const auto end = manager.m_entries.cend(); - const auto max = manager.m_activeEntryCount; - auto i = 0; - for (auto it = manager.m_entries.cbegin(); it != end && i < max; ++it) { - const auto isActive = it->m_active; - if (isActive) { - dbg << *(it->m_data); - ++i; - } - } - - return dbg; -} -#endif - -template <typename T, uint INDEXBITS> -QVector<T *> QHandleManager<T, INDEXBITS>::entries() const -{ - QVector<T *> entries; - for (auto handle : qAsConst(m_entries)) - entries.append(handle.m_data); - return entries; -} - -} // Qt3D - -QT_END_NAMESPACE - -#endif // QT3DCORE_QHANDLEMANAGER_H diff --git a/src/core/resources/qresourcemanager_p.h b/src/core/resources/qresourcemanager_p.h index 8ddc1c0a4..4cb2a38af 100644 --- a/src/core/resources/qresourcemanager_p.h +++ b/src/core/resources/qresourcemanager_p.h @@ -57,9 +57,9 @@ #include <QtCore/QReadLocker> #include <QtCore/QReadWriteLock> #include <QtCore/QtGlobal> +#include <limits> #include <Qt3DCore/private/qhandle_p.h> -#include <Qt3DCore/private/qhandlemanager_p.h> // Silence complaints about unreferenced local variables in // ArrayAllocatingPolicy::deallocateBuckets() when the compiler @@ -220,15 +220,16 @@ struct Int2Type }; }; -template <typename T, uint INDEXBITS> +template <typename T, uint INDEXBITS = 16> class ArrayAllocatingPolicy { public: + typedef QHandle<T, INDEXBITS> Handle; ArrayAllocatingPolicy() - : m_numBuckets(0) - , m_numConstructed(0) { - reset(); + m_freeList.resize(MaxSize); + for (int i = 0; i < MaxSize; i++) + m_freeList[i] = MaxSize - (i + 1); } ~ArrayAllocatingPolicy() @@ -236,7 +237,7 @@ public: deallocateBuckets(); } - T* allocateResource() + Handle allocateResource() { Q_ASSERT(!m_freeList.isEmpty()); int idx = m_freeList.takeLast(); @@ -245,9 +246,11 @@ public: Q_ASSERT(bucketIdx <= m_numBuckets); if (bucketIdx == m_numBuckets) { m_bucketDataPtrs[bucketIdx] = static_cast<T*>(malloc(sizeof(T) * BucketSize)); + m_counters[bucketIdx] = static_cast<short *>(malloc(sizeof(short) * BucketSize)); // ### memset is only needed as long as we also use this for primitive types (see FrameGraphManager) // ### remove once this is fixed, add a static_assert on T instead - memset((void*) m_bucketDataPtrs[bucketIdx], 0, sizeof(T) * BucketSize); + memset((void *)m_bucketDataPtrs[bucketIdx], 0, sizeof(T) * BucketSize); + memset(m_counters[bucketIdx], 0, sizeof(short) * BucketSize); ++m_numBuckets; } @@ -256,39 +259,47 @@ public: new (m_bucketDataPtrs[bucketIdx] + localIdx) T; ++m_numConstructed; } - - return m_bucketDataPtrs[bucketIdx] + localIdx; + Q_STATIC_ASSERT(Handle::MaxCounter < USHRT_MAX); + Q_ASSERT(m_counters[bucketIdx][localIdx] <= 0); + m_counters[bucketIdx][localIdx] *= -1; + ++m_counters[bucketIdx][localIdx]; + if (m_counters[bucketIdx][localIdx] >= Handle::MaxCounter) + m_counters[bucketIdx][localIdx] = 1; + + return Handle(idx, m_counters[bucketIdx][localIdx]); } - void releaseResource(T *r) + void releaseResource(Handle h) { - // search linearly over buckets to find the index of the resource - // and put it into the free list - for (int bucketIdx = 0; bucketIdx < m_numBuckets; ++bucketIdx) { - const T* firstItem = m_bucketDataPtrs[bucketIdx]; - if (firstItem > r || r >= firstItem + BucketSize) { - // resource is not in this bucket when its pointer address - // is outside the address range spanned by the addresses of - // the first and last items in a bucket - continue; - } + int idx = h.index(); + int bucketIdx = idx / BucketSize; + int localIdx = idx % BucketSize; - // now we found the bucket we can reconstruct the global index - // and put it back into the free list - const int localIdx = static_cast<int>(r - firstItem); - const int idx = bucketIdx * BucketSize + localIdx; - m_freeList.append(idx); - performCleanup(r, Int2Type<QResourceInfo<T>::needsCleanup>()); - break; + Q_ASSERT(h.counter() == static_cast<quint32>(m_counters[bucketIdx][localIdx])); + T *r = m_bucketDataPtrs[bucketIdx] + localIdx; + + m_freeList.append(idx); + m_counters[bucketIdx][localIdx] *= -1; + performCleanup(r, Int2Type<QResourceInfo<T>::needsCleanup>()); + } + + T *data(Handle h/*, bool *ok = 0*/) { + int bucketIdx = h.index() / BucketSize; + int localIdx = h.index() % BucketSize; + + if (h.counter() != static_cast<quint32>(m_counters[bucketIdx][localIdx])) { + return nullptr; } + return m_bucketDataPtrs[bucketIdx] + localIdx; } - void reset() - { - deallocateBuckets(); - m_freeList.resize(MaxSize); - for (int i = 0; i < MaxSize; i++) - m_freeList[i] = MaxSize - (i + 1); + void for_each(std::function<void(T*)> f) { + for (int idx = 0; idx < m_numConstructed; ++idx) { + int bucketIdx = idx / BucketSize; + int localIdx = idx % BucketSize; + T * t = m_bucketDataPtrs[bucketIdx] + localIdx; + f(t); + } } private: @@ -313,66 +324,15 @@ private: while (m_numBuckets > 0) { --m_numBuckets; free(m_bucketDataPtrs[m_numBuckets]); + free(m_counters[m_numBuckets]); } } T* m_bucketDataPtrs[MaxSize / BucketSize]; + short *m_counters[MaxSize / BucketSize]; QVector<int> m_freeList; - int m_numBuckets; - int m_numConstructed; - - void performCleanup(T *r, Int2Type<true>) - { - r->cleanup(); - } - - void performCleanup(T *, Int2Type<false>) - {} - -}; - -template <typename T, uint INDEXBITS> -class ArrayPreallocationPolicy -{ -public: - ArrayPreallocationPolicy() - { - reset(); - } - - T* allocateResource() - { - Q_ASSERT(!m_freeList.isEmpty()); - int idx = m_freeList.last(); - m_freeList.pop_back(); - return m_bucket.data() + idx; - } - - void releaseResource(T *r) - { - Q_ASSERT(m_bucket.data() <= r && r < m_bucket.data() + MaxSize); - int idx = r - m_bucket.data(); - m_freeList.append(idx); - performCleanup(r, Int2Type<QResourceInfo<T>::needsCleanup>()); - *r = T(); - } - - void reset() - { - m_bucket.clear(); - m_bucket.resize(MaxSize); - m_freeList.resize(MaxSize); - for (int i = 0; i < MaxSize; i++) - m_freeList[i] = MaxSize - (i + 1); - } - -private: - enum { - MaxSize = 1 << INDEXBITS - }; - - QVector<T> m_bucket; - QVector<int> m_freeList; + int m_numBuckets = 0; + int m_numConstructed = 0; void performCleanup(T *r, Int2Type<true>) { @@ -386,29 +346,29 @@ private: #ifndef QT_NO_DEBUG_STREAM template <typename ValueType, typename KeyType, uint INDEXBITS, - template <typename, uint> class AllocatingPolicy, template <class> class LockingPolicy > class QResourceManager; template <typename ValueType, typename KeyType, uint INDEXBITS = 16, - template <typename, uint> class AllocatingPolicy = ArrayAllocatingPolicy, template <class> class LockingPolicy = NonLockingPolicy > -QDebug operator<<(QDebug dbg, const QResourceManager<ValueType, KeyType, INDEXBITS, AllocatingPolicy, LockingPolicy> &manager); +QDebug operator<<(QDebug dbg, const QResourceManager<ValueType, KeyType, INDEXBITS, LockingPolicy> &manager); #endif template <typename ValueType, typename KeyType, uint INDEXBITS = 16, - template <typename, uint> class AllocatingPolicy = ArrayAllocatingPolicy, template <class> class LockingPolicy = NonLockingPolicy > class QResourceManager - : public AllocatingPolicy<ValueType, INDEXBITS> - , public LockingPolicy< QResourceManager<ValueType, KeyType, INDEXBITS, AllocatingPolicy, LockingPolicy> > + : public ArrayAllocatingPolicy<ValueType, INDEXBITS> + , public LockingPolicy< QResourceManager<ValueType, KeyType, INDEXBITS, LockingPolicy> > { public: + typedef ArrayAllocatingPolicy<ValueType, INDEXBITS> Allocator; + typedef QHandle<ValueType, INDEXBITS> Handle; + QResourceManager() : - AllocatingPolicy<ValueType, INDEXBITS>(), + Allocator(), m_maxSize((1 << INDEXBITS) - 1) { } @@ -416,52 +376,43 @@ public: ~QResourceManager() {} - QHandle<ValueType, INDEXBITS> acquire() + Handle acquire() { typename LockingPolicy<QResourceManager>::WriteLocker lock(this); - QHandle<ValueType, INDEXBITS> handle = m_handleManager.acquire(AllocatingPolicy<ValueType, INDEXBITS>::allocateResource()); + Handle handle = Allocator::allocateResource(); m_activeHandles.push_back(handle); return handle; } - ValueType* data(const QHandle<ValueType, INDEXBITS> &handle) + ValueType* data(const Handle &handle) { typename LockingPolicy<QResourceManager>::ReadLocker lock(this); - ValueType* d = m_handleManager.data(handle); - return d; + return Allocator::data(handle); } - void release(const QHandle<ValueType, INDEXBITS> &handle) + void release(const Handle &handle) { typename LockingPolicy<QResourceManager>::WriteLocker lock(this); releaseLocked(handle); } - void reset() - { - typename LockingPolicy<QResourceManager>::WriteLocker lock(this); - m_handleManager.reset(); - m_activeHandles.clear(); - AllocatingPolicy<ValueType, INDEXBITS>::reset(); - } - bool contains(const KeyType &id) const { typename LockingPolicy<QResourceManager>::ReadLocker lock(this); return m_keyToHandleMap.contains(id); } - QHandle<ValueType, INDEXBITS> getOrAcquireHandle(const KeyType &id) + Handle getOrAcquireHandle(const KeyType &id) { typename LockingPolicy<QResourceManager>::ReadLocker lock(this); - QHandle<ValueType, INDEXBITS> handle = m_keyToHandleMap.value(id); + Handle handle = m_keyToHandleMap.value(id); if (handle.isNull()) { lock.unlock(); typename LockingPolicy<QResourceManager>::WriteLocker writeLock(this); // Test that the handle hasn't been set (in the meantime between the read unlock and the write lock) - QHandle<ValueType, INDEXBITS> &handleToSet = m_keyToHandleMap[id]; + Handle &handleToSet = m_keyToHandleMap[id]; if (handleToSet.isNull()) { - handleToSet = m_handleManager.acquire(AllocatingPolicy<ValueType, INDEXBITS>::allocateResource()); + handleToSet = Allocator::allocateResource(); m_activeHandles.push_back(handleToSet); } return handleToSet; @@ -469,7 +420,7 @@ public: return handle; } - QHandle<ValueType, INDEXBITS> lookupHandle(const KeyType &id) + Handle lookupHandle(const KeyType &id) { typename LockingPolicy<QResourceManager>::ReadLocker lock(this); return m_keyToHandleMap.value(id); @@ -480,58 +431,54 @@ public: ValueType* ret = nullptr; { typename LockingPolicy<QResourceManager>::ReadLocker lock(this); - QHandle<ValueType, INDEXBITS> handle = m_keyToHandleMap.value(id); + Handle handle = m_keyToHandleMap.value(id); if (!handle.isNull()) - ret = m_handleManager.data(handle); + ret = Allocator::data(handle); } return ret; } ValueType *getOrCreateResource(const KeyType &id) { - const QHandle<ValueType, INDEXBITS> handle = getOrAcquireHandle(id); + const Handle handle = getOrAcquireHandle(id); typename LockingPolicy<QResourceManager>::ReadLocker lock(this); - return m_handleManager.data(handle); + return Allocator::data(handle); } void releaseResource(const KeyType &id) { typename LockingPolicy<QResourceManager>::WriteLocker lock(this); - QHandle<ValueType, INDEXBITS> handle = m_keyToHandleMap.take(id); + Handle handle = m_keyToHandleMap.take(id); if (!handle.isNull()) releaseLocked(handle); } int maximumSize() const { return m_maxSize; } - int count() const Q_DECL_NOEXCEPT { return m_handleManager.activeEntries(); } + int count() const Q_DECL_NOEXCEPT { return m_activeHandles.size(); } - inline QVector<QHandle<ValueType, INDEXBITS> > activeHandles() const Q_DECL_NOEXCEPT { return m_activeHandles; } + inline QVector<Handle > activeHandles() const Q_DECL_NOEXCEPT { return m_activeHandles; } protected: - QHandleManager<ValueType, INDEXBITS> m_handleManager; - QHash<KeyType, QHandle<ValueType, INDEXBITS> > m_keyToHandleMap; - QVector<QHandle<ValueType, INDEXBITS> > m_activeHandles; + QHash<KeyType, Handle > m_keyToHandleMap; + QVector<Handle > m_activeHandles; const int m_maxSize; private: - void releaseLocked(const QHandle<ValueType, INDEXBITS> &handle) + void releaseLocked(const Handle &handle) { - ValueType *val = m_handleManager.data(handle); - m_handleManager.release(handle); m_activeHandles.removeOne(handle); - AllocatingPolicy<ValueType, INDEXBITS>::releaseResource(val); + Allocator::releaseResource(handle); } - friend QDebug operator<< <>(QDebug dbg, const QResourceManager<ValueType, KeyType, INDEXBITS, AllocatingPolicy, LockingPolicy> &manager); + friend QDebug operator<< <>(QDebug dbg, const QResourceManager<ValueType, KeyType, INDEXBITS, LockingPolicy> &manager); }; #ifndef QT_NO_DEBUG_STREAM template <typename ValueType, typename KeyType, uint INDEXBITS, - template <typename, uint> class AllocatingPolicy, template <class> class LockingPolicy > -QDebug operator<<(QDebug dbg, const QResourceManager<ValueType, KeyType, INDEXBITS, AllocatingPolicy, LockingPolicy> &manager) +QDebug operator<<(QDebug dbg, const QResourceManager<ValueType, KeyType, INDEXBITS, LockingPolicy> &manager) { QDebugStateSaver saver(dbg); dbg << "Contains" << manager.count() << "items" << "of a maximum" << manager.maximumSize() << endl; @@ -541,8 +488,8 @@ QDebug operator<<(QDebug dbg, const QResourceManager<ValueType, KeyType, INDEXBI for (auto it = manager.m_keyToHandleMap.cbegin(); it != end; ++it) dbg << "QNodeId =" << it.key() << "Handle =" << it.value() << endl; - dbg << "Resources:" << endl; - dbg << manager.m_handleManager; +// dbg << "Resources:" << endl; +// dbg << manager.m_handleManager; return dbg; } #endif diff --git a/src/core/resources/resources.pri b/src/core/resources/resources.pri index 855d73b79..96ea21e93 100644 --- a/src/core/resources/resources.pri +++ b/src/core/resources/resources.pri @@ -1,5 +1,4 @@ HEADERS += \ - $$PWD/qhandlemanager_p.h \ $$PWD/qresourcemanager_p.h \ $$PWD/qcircularbuffer_p.h \ $$PWD/qboundedcircularbuffer_p.h \ diff --git a/src/input/backend/inputmanagers_p.h b/src/input/backend/inputmanagers_p.h index a0cb127b1..956b0ab8b 100644 --- a/src/input/backend/inputmanagers_p.h +++ b/src/input/backend/inputmanagers_p.h @@ -80,8 +80,7 @@ namespace Input { class KeyboardInputManager : public Qt3DCore::QResourceManager< KeyboardHandler, Qt3DCore::QNodeId, - 16, - Qt3DCore::ArrayAllocatingPolicy> + 16> { public: KeyboardInputManager() {} @@ -90,8 +89,7 @@ public: class KeyboardDeviceManager : public Qt3DCore::QResourceManager< KeyboardDevice, Qt3DCore::QNodeId, - 8, - Qt3DCore::ArrayAllocatingPolicy> + 8> { public: KeyboardDeviceManager() {} @@ -100,8 +98,7 @@ public: class MouseDeviceManager : public Qt3DCore::QResourceManager< MouseDevice, Qt3DCore::QNodeId, - 8, - Qt3DCore::ArrayAllocatingPolicy> + 8> { public: MouseDeviceManager() {} @@ -110,8 +107,7 @@ public: class MouseInputManager : public Qt3DCore::QResourceManager< MouseHandler, Qt3DCore::QNodeId, - 16, - Qt3DCore::ArrayAllocatingPolicy> + 16> { public: MouseInputManager() {} @@ -120,8 +116,7 @@ public: class AxisManager : public Qt3DCore::QResourceManager< Axis, Qt3DCore::QNodeId, - 16, - Qt3DCore::ArrayAllocatingPolicy> + 16> { public: AxisManager() {} @@ -130,8 +125,7 @@ public: class AxisSettingManager : public Qt3DCore::QResourceManager< AxisSetting, Qt3DCore::QNodeId, - 16, - Qt3DCore::ArrayAllocatingPolicy> + 16> { public: AxisSettingManager() {} @@ -140,8 +134,7 @@ public: class ActionManager : public Qt3DCore::QResourceManager< Action, Qt3DCore::QNodeId, - 16, - Qt3DCore::ArrayAllocatingPolicy> + 16> { public: ActionManager() {} @@ -150,8 +143,7 @@ public: class ActionInputManager : public Qt3DCore::QResourceManager< ActionInput, Qt3DCore::QNodeId, - 16, - Qt3DCore::ArrayAllocatingPolicy> + 16> { public: ActionInputManager() {} @@ -160,8 +152,7 @@ public: class AnalogAxisInputManager : public Qt3DCore::QResourceManager< AnalogAxisInput, Qt3DCore::QNodeId, - 16, - Qt3DCore::ArrayAllocatingPolicy> + 16> { public: AnalogAxisInputManager() {} @@ -170,8 +161,7 @@ public: class ButtonAxisInputManager : public Qt3DCore::QResourceManager< ButtonAxisInput, Qt3DCore::QNodeId, - 16, - Qt3DCore::ArrayAllocatingPolicy> + 16> { public: ButtonAxisInputManager() {} @@ -180,8 +170,7 @@ public: class InputChordManager : public Qt3DCore::QResourceManager< InputChord, Qt3DCore::QNodeId, - 16, - Qt3DCore::ArrayAllocatingPolicy> + 16> { public: InputChordManager() {} @@ -190,8 +179,7 @@ public: class InputSequenceManager : public Qt3DCore::QResourceManager< InputSequence, Qt3DCore::QNodeId, - 16, - Qt3DCore::ArrayAllocatingPolicy> + 16> { public: InputSequenceManager() {} @@ -200,8 +188,7 @@ public: class LogicalDeviceManager : public Qt3DCore::QResourceManager< LogicalDevice, Qt3DCore::QNodeId, - 16, - Qt3DCore::ArrayAllocatingPolicy> + 16> { public: LogicalDeviceManager() {} @@ -217,8 +204,7 @@ private: class GenericDeviceBackendNodeManager : public Qt3DCore::QResourceManager< GenericDeviceBackendNode, Qt3DCore::QNodeId, - 8, - Qt3DCore::ArrayAllocatingPolicy> + 8> { public: GenericDeviceBackendNodeManager() {} @@ -227,8 +213,7 @@ public: class Q_AUTOTEST_EXPORT PhysicalDeviceProxyManager : public Qt3DCore::QResourceManager< PhysicalDeviceProxy, Qt3DCore::QNodeId, - 16, - Qt3DCore::ArrayAllocatingPolicy> + 16> { public: PhysicalDeviceProxyManager() {} @@ -243,8 +228,7 @@ private: class AxisAccumulatorManager : public Qt3DCore::QResourceManager< AxisAccumulator, Qt3DCore::QNodeId, - 16, - Qt3DCore::ArrayAllocatingPolicy> + 16> { public: AxisAccumulatorManager() {} diff --git a/src/logic/managers_p.h b/src/logic/managers_p.h index 6194d260a..3d48aab24 100644 --- a/src/logic/managers_p.h +++ b/src/logic/managers_p.h @@ -65,8 +65,7 @@ namespace Logic { class HandlerManager : public Qt3DCore::QResourceManager< Handler, Qt3DCore::QNodeId, - 16, - Qt3DCore::ArrayAllocatingPolicy> + 16> { public: HandlerManager() {} diff --git a/src/plugins/renderplugins/scene2d/scene2dplugin.h b/src/plugins/renderplugins/scene2d/scene2dplugin.h index f19093c7e..3b4471d55 100644 --- a/src/plugins/renderplugins/scene2d/scene2dplugin.h +++ b/src/plugins/renderplugins/scene2d/scene2dplugin.h @@ -68,7 +68,6 @@ class Scene2DNodeManager : public Qt3DCore::QResourceManager< Render::Quick::Scene2D, Qt3DCore::QNodeId, 16, - Qt3DCore::ArrayAllocatingPolicy, Qt3DCore::ObjectLevelLockingPolicy> { }; diff --git a/src/quick3d/quick3dextras/qt3dquickwindow.cpp b/src/quick3d/quick3dextras/qt3dquickwindow.cpp index 91773bb66..e41754f42 100644 --- a/src/quick3d/quick3dextras/qt3dquickwindow.cpp +++ b/src/quick3d/quick3dextras/qt3dquickwindow.cpp @@ -131,10 +131,10 @@ Qt3DQuickWindow::Qt3DQuickWindow(QWindow *parent) setFormat(format); QSurfaceFormat::setDefaultFormat(format); - d->m_engine = new Qt3DCore::Quick::QQmlAspectEngine; d->m_renderAspect = new Qt3DRender::QRenderAspect; d->m_inputAspect = new Qt3DInput::QInputAspect; d->m_logicAspect = new Qt3DLogic::QLogicAspect; + d->m_engine = new Qt3DCore::Quick::QQmlAspectEngine; d->m_engine->aspectEngine()->registerAspect(d->m_renderAspect); d->m_engine->aspectEngine()->registerAspect(d->m_inputAspect); diff --git a/src/render/backend/entity.cpp b/src/render/backend/entity.cpp index 34568c1a7..95304007a 100644 --- a/src/render/backend/entity.cpp +++ b/src/render/backend/entity.cpp @@ -136,7 +136,7 @@ void Entity::setParentHandle(HEntity parentHandle) // Remove ourselves from previous parent children list Entity *parent = m_nodeManagers->renderNodesManager()->data(parentHandle); if (parent != nullptr && parent->m_childrenHandles.contains(m_handle)) - parent->m_childrenHandles.remove(m_handle); + parent->m_childrenHandles.removeAll(m_handle); m_parentHandle = parentHandle; parent = m_nodeManagers->renderNodesManager()->data(parentHandle); if (parent != nullptr && !parent->m_childrenHandles.contains(m_handle)) diff --git a/src/render/backend/managers_p.h b/src/render/backend/managers_p.h index c76f5b315..f19b9261a 100644 --- a/src/render/backend/managers_p.h +++ b/src/render/backend/managers_p.h @@ -94,7 +94,6 @@ class AttachmentManager : public Qt3DCore::QResourceManager< RenderTargetOutput, Qt3DCore::QNodeId, 16, - Qt3DCore::ArrayAllocatingPolicy, Qt3DCore::NonLockingPolicy> { public: @@ -105,7 +104,6 @@ class CameraManager : public Qt3DCore::QResourceManager< CameraLens, Qt3DCore::QNodeId, 8, - Qt3DCore::ArrayAllocatingPolicy, Qt3DCore::NonLockingPolicy> { public: @@ -116,7 +114,6 @@ class FilterKeyManager : public Qt3DCore::QResourceManager< FilterKey, Qt3DCore::QNodeId, 16, - Qt3DCore::ArrayAllocatingPolicy, Qt3DCore::NonLockingPolicy> { @@ -128,7 +125,6 @@ class EffectManager : public Qt3DCore::QResourceManager< Effect, Qt3DCore::QNodeId, 16, - Qt3DCore::ArrayAllocatingPolicy, Qt3DCore::NonLockingPolicy> { public: @@ -139,18 +135,16 @@ class Q_AUTOTEST_EXPORT EntityManager : public Qt3DCore::QResourceManager< Entity, Qt3DCore::QNodeId, 16, - Qt3DCore::ArrayAllocatingPolicy, Qt3DCore::NonLockingPolicy> { public: EntityManager() {} ~EntityManager() { - const auto entries = m_handleManager.entries(); - for (Entity *e : entries) { + Allocator::for_each([](Entity *e) { if (e) e->setNodeManagers(nullptr); - } + }); } }; @@ -175,7 +169,6 @@ class LayerManager : public Qt3DCore::QResourceManager< Layer, Qt3DCore::QNodeId, 16, - Qt3DCore::ArrayAllocatingPolicy, Qt3DCore::NonLockingPolicy> { public: @@ -186,7 +179,6 @@ class LevelOfDetailManager : public Qt3DCore::QResourceManager< LevelOfDetail, Qt3DCore::QNodeId, 16, - Qt3DCore::ArrayAllocatingPolicy, Qt3DCore::NonLockingPolicy> { public: @@ -197,7 +189,6 @@ class MaterialManager : public Qt3DCore::QResourceManager< Material, Qt3DCore::QNodeId, 16, - Qt3DCore::ArrayAllocatingPolicy, Qt3DCore::NonLockingPolicy> { public: @@ -208,7 +199,6 @@ class MatrixManager : public Qt3DCore::QResourceManager< QMatrix4x4, Qt3DCore::QNodeId, 16, - Qt3DCore::ArrayAllocatingPolicy, Qt3DCore::NonLockingPolicy> { public: @@ -219,7 +209,6 @@ class ShaderManager : public Qt3DCore::QResourceManager< Shader, Qt3DCore::QNodeId, 16, - Qt3DCore::ArrayAllocatingPolicy, Qt3DCore::NonLockingPolicy> { public: @@ -230,7 +219,6 @@ class ShaderBuilderManager : public Qt3DCore::QResourceManager< ShaderBuilder, Qt3DCore::QNodeId, 16, - Qt3DCore::ArrayAllocatingPolicy, Qt3DCore::NonLockingPolicy> { public: @@ -241,7 +229,6 @@ class TextureManager : public Qt3DCore::QResourceManager< Texture, Qt3DCore::QNodeId, 16, - Qt3DCore::ArrayAllocatingPolicy, Qt3DCore::NonLockingPolicy> { public: @@ -267,7 +254,6 @@ class TransformManager : public Qt3DCore::QResourceManager< Transform, Qt3DCore::QNodeId, 16, - Qt3DCore::ArrayAllocatingPolicy, Qt3DCore::NonLockingPolicy> { public: @@ -278,7 +264,6 @@ class VAOManager : public Qt3DCore::QResourceManager< OpenGLVertexArrayObject, VAOIdentifier, 16, - Qt3DCore::ArrayAllocatingPolicy, Qt3DCore::NonLockingPolicy> { public: @@ -289,7 +274,6 @@ class RenderTargetManager : public Qt3DCore::QResourceManager< RenderTarget, Qt3DCore::QNodeId, 8, - Qt3DCore::ArrayAllocatingPolicy, Qt3DCore::NonLockingPolicy> { public: @@ -300,7 +284,6 @@ class RenderPassManager : public Qt3DCore::QResourceManager< RenderPass, Qt3DCore::QNodeId, 16, - Qt3DCore::ArrayAllocatingPolicy, Qt3DCore::NonLockingPolicy> { public: @@ -312,7 +295,6 @@ class ParameterManager : public Qt3DCore::QResourceManager< Parameter, Qt3DCore::QNodeId, 16, - Qt3DCore::ArrayAllocatingPolicy, Qt3DCore::NonLockingPolicy> { public: @@ -323,7 +305,6 @@ class ShaderDataManager : public Qt3DCore::QResourceManager< ShaderData, Qt3DCore::QNodeId, 16, - Qt3DCore::ArrayAllocatingPolicy, Qt3DCore::NonLockingPolicy> { public: @@ -334,7 +315,6 @@ class GLBufferManager : public Qt3DCore::QResourceManager< GLBuffer, Qt3DCore::QNodeId, 16, - Qt3DCore::ArrayAllocatingPolicy, Qt3DCore::NonLockingPolicy> { }; @@ -343,7 +323,6 @@ class TextureImageManager : public Qt3DCore::QResourceManager< TextureImage, Qt3DCore::QNodeId, 16, - Qt3DCore::ArrayAllocatingPolicy, Qt3DCore::NonLockingPolicy> { }; @@ -352,7 +331,6 @@ class AttributeManager : public Qt3DCore::QResourceManager< Attribute, Qt3DCore::QNodeId, 20, - Qt3DCore::ArrayAllocatingPolicy, Qt3DCore::NonLockingPolicy> { }; @@ -361,7 +339,6 @@ class GeometryManager : public Qt3DCore::QResourceManager< Geometry, Qt3DCore::QNodeId, 16, - Qt3DCore::ArrayAllocatingPolicy, Qt3DCore::NonLockingPolicy> { }; @@ -370,7 +347,6 @@ class ObjectPickerManager : public Qt3DCore::QResourceManager< ObjectPicker, Qt3DCore::QNodeId, 16, - Qt3DCore::ArrayAllocatingPolicy, Qt3DCore::NonLockingPolicy> { }; @@ -380,7 +356,6 @@ class BoundingVolumeDebugManager : public Qt3DCore::QResourceManager< BoundingVolumeDebug, Qt3DCore::QNodeId, 16, - Qt3DCore::ArrayAllocatingPolicy, Qt3DCore::ObjectLevelLockingPolicy> { }; @@ -390,7 +365,6 @@ class LightManager : public Qt3DCore::QResourceManager< Light, Qt3DCore::QNodeId, 16, - Qt3DCore::ArrayAllocatingPolicy, Qt3DCore::NonLockingPolicy> { public: @@ -401,7 +375,6 @@ class EnvironmentLightManager : public Qt3DCore::QResourceManager< EnvironmentLight, Qt3DCore::QNodeId, 16, - Qt3DCore::ArrayAllocatingPolicy, Qt3DCore::NonLockingPolicy> { public: @@ -412,7 +385,6 @@ class ComputeCommandManager : public Qt3DCore::QResourceManager< ComputeCommand, Qt3DCore::QNodeId, 16, - Qt3DCore::ArrayAllocatingPolicy, Qt3DCore::NonLockingPolicy> { public: @@ -423,7 +395,6 @@ class RenderStateManager : public Qt3DCore::QResourceManager< RenderStateNode, Qt3DCore::QNodeId, 16, - Qt3DCore::ArrayAllocatingPolicy, Qt3DCore::NonLockingPolicy> { }; @@ -432,7 +403,6 @@ class ArmatureManager : public Qt3DCore::QResourceManager< Armature, Qt3DCore::QNodeId, 16, - Qt3DCore::ArrayAllocatingPolicy, Qt3DCore::NonLockingPolicy> { }; @@ -441,7 +411,6 @@ class SkeletonManager : public Qt3DCore::QResourceManager< Skeleton, Qt3DCore::QNodeId, 16, - Qt3DCore::ArrayAllocatingPolicy, Qt3DCore::NonLockingPolicy> { public: @@ -462,7 +431,6 @@ class JointManager : public Qt3DCore::QResourceManager< Joint, Qt3DCore::QNodeId, 16, - Qt3DCore::ArrayAllocatingPolicy, Qt3DCore::NonLockingPolicy> { public: diff --git a/src/render/backend/stringtoint.cpp b/src/render/backend/stringtoint.cpp index 4ae49fc30..5659da394 100644 --- a/src/render/backend/stringtoint.cpp +++ b/src/render/backend/stringtoint.cpp @@ -40,6 +40,7 @@ #include "stringtoint_p.h" #include <QMutex> #include <QReadWriteLock> +#include <QHash> QT_BEGIN_NAMESPACE @@ -49,15 +50,12 @@ namespace Render { namespace { -QMutex mutex; -QReadWriteLock readLock; +QReadWriteLock lock; +QHash<QString, int> map = QHash<QString, int>(); +QVector<QString> reverseMap = QVector<QString>(); } // anonymous -QVector<QString> StringToInt::m_stringsArray = QVector<QString>(); -QVector<QString> StringToInt::m_pendingStringsArray = QVector<QString>(); -int StringToInt::m_calls = 0; - int StringToInt::lookupId(QLatin1String str) { // ### optimize me @@ -66,36 +64,20 @@ int StringToInt::lookupId(QLatin1String str) int StringToInt::lookupId(const QString &str) { - // Note: how do we protect against the case where - // we are synching the two arrays ? - QReadLocker readLocker(&readLock); - int idx = StringToInt::m_stringsArray.indexOf(str); + int idx; + { + QReadLocker readLocker(&lock); + idx = map.value(str, -1); + } if (Q_UNLIKELY(idx < 0)) { - QMutexLocker lock(&mutex); - - // If not found in m_stringsArray, maybe it's in the pending array - if ((idx = StringToInt::m_pendingStringsArray.indexOf(str)) >= 0) { - idx += StringToInt::m_stringsArray.size(); - } else { - // If not, we add it to the m_pendingStringArray - StringToInt::m_pendingStringsArray.push_back(str); - idx = StringToInt::m_stringsArray.size() + m_pendingStringsArray.size() - 1; - } - - // We sync the two arrays every 20 calls - if (StringToInt::m_calls % 20 == 0 && StringToInt::m_pendingStringsArray.size() > 0) { - // Unlock reader to writeLock - // since a read lock cannot be locked for writing - lock.unlock(); - readLocker.unlock(); - - QWriteLocker writeLock(&readLock); - lock.relock(); - - StringToInt::m_stringsArray += StringToInt::m_pendingStringsArray; - StringToInt::m_pendingStringsArray.clear(); - StringToInt::m_calls = 0; + QWriteLocker writeLocker(&lock); + idx = map.value(str, -1); + if (idx < 0) { + idx = reverseMap.size(); + Q_ASSERT(map.size() == reverseMap.size()); + map.insert(str, idx); + reverseMap.append(str); } } return idx; @@ -103,14 +85,9 @@ int StringToInt::lookupId(const QString &str) QString StringToInt::lookupString(int idx) { - QReadLocker readLocker(&readLock); - if (Q_LIKELY(StringToInt::m_stringsArray.size() > idx)) - return StringToInt::m_stringsArray.at(idx); - - // Maybe it's in the pending array then - QMutexLocker lock(&mutex); - if (StringToInt::m_stringsArray.size() + StringToInt::m_pendingStringsArray.size() > idx) - return StringToInt::m_pendingStringsArray.at(idx - StringToInt::m_stringsArray.size()); + QReadLocker readLocker(&lock); + if (Q_LIKELY(reverseMap.size() > idx)) + return reverseMap.at(idx); return QString(); } diff --git a/src/render/backend/stringtoint_p.h b/src/render/backend/stringtoint_p.h index 2d9e566fb..996cecf33 100644 --- a/src/render/backend/stringtoint_p.h +++ b/src/render/backend/stringtoint_p.h @@ -67,11 +67,6 @@ public: static int lookupId(const QString &str); static int lookupId(QLatin1String str); static QString lookupString(int idx); - -private: - static QVector<QString> m_stringsArray; - static QVector<QString> m_pendingStringsArray; - static int m_calls; }; } // Render diff --git a/src/render/geometry/buffermanager_p.h b/src/render/geometry/buffermanager_p.h index 3eecb3664..ed3563876 100644 --- a/src/render/geometry/buffermanager_p.h +++ b/src/render/geometry/buffermanager_p.h @@ -64,7 +64,6 @@ class Q_AUTOTEST_EXPORT BufferManager : public Qt3DCore::QResourceManager< Buffer, Qt3DCore::QNodeId, 16, - Qt3DCore::ArrayAllocatingPolicy, Qt3DCore::ObjectLevelLockingPolicy> { public: diff --git a/src/render/geometry/geometryrenderermanager_p.h b/src/render/geometry/geometryrenderermanager_p.h index 4dea63862..e3b313569 100644 --- a/src/render/geometry/geometryrenderermanager_p.h +++ b/src/render/geometry/geometryrenderermanager_p.h @@ -64,7 +64,6 @@ class Q_AUTOTEST_EXPORT GeometryRendererManager : public Qt3DCore::QResourceMana GeometryRenderer, Qt3DCore::QNodeId, 16, - Qt3DCore::ArrayAllocatingPolicy, Qt3DCore::ObjectLevelLockingPolicy> { public: diff --git a/src/render/graphicshelpers/graphicscontext.cpp b/src/render/graphicshelpers/graphicscontext.cpp index 37182a0ba..11132c5ed 100644 --- a/src/render/graphicshelpers/graphicscontext.cpp +++ b/src/render/graphicshelpers/graphicscontext.cpp @@ -1462,7 +1462,7 @@ void GraphicsContext::specifyAttribute(const Attribute *attribute, attr.dataType = attributeDataType; attr.byteOffset = attribute->byteOffset() + (i * attrCount * typeSize); attr.vertexSize = attribute->vertexSize() / attrCount; - attr.byteStride = attribute->byteStride() + (attrCount * attrCount * typeSize); + attr.byteStride = (attribute->byteStride() != 0) ? attribute->byteStride() : (attrCount * attrCount * typeSize); attr.divisor = attribute->divisor(); attr.shaderDataType = attributeDescription->m_type; diff --git a/src/render/graphicshelpers/graphicshelpergl2.cpp b/src/render/graphicshelpers/graphicshelpergl2.cpp index 5444ce749..60d3b49ba 100644 --- a/src/render/graphicshelpers/graphicshelpergl2.cpp +++ b/src/render/graphicshelpers/graphicshelpergl2.cpp @@ -178,6 +178,7 @@ QVector<ShaderUniform> GraphicsHelperGL2::programUniformsAndLocations(GLuint pro uniformName[sizeof(uniformName) - 1] = '\0'; uniform.m_location = m_funcs->glGetUniformLocation(programId, uniformName); uniform.m_name = QString::fromUtf8(uniformName, uniformNameLength); + uniform.m_rawByteSize = uniformByteSize(uniform); uniforms.append(uniform); } return uniforms; @@ -514,14 +515,38 @@ uint GraphicsHelperGL2::uniformByteSize(const ShaderUniform &description) rawByteSize = matrixStride ? 2 * matrixStride : 16; break; + case GL_FLOAT_MAT2x4: + rawByteSize = matrixStride ? 2 * matrixStride : 32; + break; + + case GL_FLOAT_MAT4x2: + rawByteSize = matrixStride ? 4 * matrixStride : 32; + break; + case GL_FLOAT_MAT3: rawByteSize = matrixStride ? 3 * matrixStride : 36; break; + case GL_FLOAT_MAT2x3: + rawByteSize = matrixStride ? 2 * matrixStride : 24; + break; + + case GL_FLOAT_MAT3x2: + rawByteSize = matrixStride ? 3 * matrixStride : 24; + break; + case GL_FLOAT_MAT4: rawByteSize = matrixStride ? 4 * matrixStride : 64; break; + case GL_FLOAT_MAT4x3: + rawByteSize = matrixStride ? 4 * matrixStride : 48; + break; + + case GL_FLOAT_MAT3x4: + rawByteSize = matrixStride ? 3 * matrixStride : 48; + break; + case GL_BOOL: rawByteSize = 1; break; diff --git a/src/render/io/scenemanager.cpp b/src/render/io/scenemanager.cpp index b0a595905..784751857 100644 --- a/src/render/io/scenemanager.cpp +++ b/src/render/io/scenemanager.cpp @@ -44,12 +44,10 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { namespace Render { -SceneManager::SceneManager() - : Qt3DCore::QResourceManager<Scene, - Qt3DCore::QNodeId, - 8, - Qt3DCore::ArrayAllocatingPolicy, - Qt3DCore::ObjectLevelLockingPolicy>() +SceneManager::SceneManager() : Qt3DCore::QResourceManager<Scene, + Qt3DCore::QNodeId, + 8, + Qt3DCore::ObjectLevelLockingPolicy>() , m_service(nullptr) { } diff --git a/src/render/io/scenemanager_p.h b/src/render/io/scenemanager_p.h index 9993c85fc..d7dd8c752 100644 --- a/src/render/io/scenemanager_p.h +++ b/src/render/io/scenemanager_p.h @@ -86,7 +86,6 @@ class Q_AUTOTEST_EXPORT SceneManager : public Qt3DCore::QResourceManager< Scene, Qt3DCore::QNodeId, 8, - Qt3DCore::ArrayAllocatingPolicy, Qt3DCore::ObjectLevelLockingPolicy> { public: diff --git a/src/render/jobs/pickboundingvolumeutils.cpp b/src/render/jobs/pickboundingvolumeutils.cpp index 22b92a3f2..5a32f0203 100644 --- a/src/render/jobs/pickboundingvolumeutils.cpp +++ b/src/render/jobs/pickboundingvolumeutils.cpp @@ -52,6 +52,8 @@ #include <Qt3DRender/private/segmentsvisitor_p.h> #include <Qt3DRender/private/pointsvisitor_p.h> +#include <vector> + QT_BEGIN_NAMESPACE namespace Qt3DRender { @@ -565,27 +567,29 @@ bool HierarchicalEntityPicker::collectHits(Entity *root) m_entities.clear(); QRayCastingService rayCasting; - QVector<Entity *> worklist; - worklist << root; + std::vector<std::pair<Entity *, bool>> worklist; + worklist.push_back({root, !root->componentHandle<ObjectPicker, 16>().isNull()}); while (!worklist.empty()) { - Entity *current = worklist.takeLast(); + auto current = worklist.back(); + worklist.pop_back(); // first pick entry sub-scene-graph QCollisionQueryResult::Hit queryResult = - rayCasting.query(m_ray, current->worldBoundingVolumeWithChildren()); + rayCasting.query(m_ray, current.first->worldBoundingVolumeWithChildren()); if (queryResult.m_distance < 0.f) continue; // if we get a hit, we check again for this specific entity - queryResult = rayCasting.query(m_ray, current->worldBoundingVolume()); - if (queryResult.m_distance >= 0.f) { - m_entities.push_back(current); + queryResult = rayCasting.query(m_ray, current.first->worldBoundingVolume()); + if (queryResult.m_distance >= 0.f && current.second) { + m_entities.push_back(current.first); m_hits.push_back(queryResult); } // and pick children - worklist << current->children(); + for (auto child: current.first->children()) + worklist.push_back({child, current.second || !child->componentHandle<ObjectPicker, 16>().isNull()}); } return !m_hits.empty(); diff --git a/src/render/materialsystem/filterkey.cpp b/src/render/materialsystem/filterkey.cpp index fd911c419..167413451 100644 --- a/src/render/materialsystem/filterkey.cpp +++ b/src/render/materialsystem/filterkey.cpp @@ -73,16 +73,6 @@ void FilterKey::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &ch m_value = data.value; } -QVariant FilterKey::value() const -{ - return m_value; -} - -QString FilterKey::name() const -{ - return m_name; -} - void FilterKey::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) { switch (e->type()) { @@ -106,8 +96,14 @@ bool FilterKey::operator ==(const FilterKey &other) { if (&other == this) return true; - return ((other.name() == name()) && - (other.value() == value())); + // TODO create a QVaraint::fastCompare function that returns false + // if types are not equal. For now, applying + // https://codereview.qt-project.org/#/c/204484/ + // and adding the following early comparison of the types should give + // an equivalent performance gain: + return (other.value().type() == value().type() && + other.name() == name() && + other.value() == value()); } bool FilterKey::operator !=(const FilterKey &other) diff --git a/src/render/materialsystem/filterkey_p.h b/src/render/materialsystem/filterkey_p.h index 4aea3d78a..6a098861c 100644 --- a/src/render/materialsystem/filterkey_p.h +++ b/src/render/materialsystem/filterkey_p.h @@ -69,8 +69,8 @@ public: ~FilterKey(); void cleanup(); - QVariant value() const; - QString name() const; + const QVariant &value() const { return m_value; } + const QString &name() const { return m_name; } void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) Q_DECL_OVERRIDE; bool operator ==(const FilterKey &other); bool operator !=(const FilterKey &other); diff --git a/src/render/materialsystem/parameter.cpp b/src/render/materialsystem/parameter.cpp index 9c40c199a..6671e4943 100644 --- a/src/render/materialsystem/parameter.cpp +++ b/src/render/materialsystem/parameter.cpp @@ -101,16 +101,6 @@ QString Parameter::name() const return m_name; } -int Parameter::nameId() const Q_DECL_NOTHROW -{ - return m_nameId; -} - -UniformValue Parameter::uniformValue() const -{ - return m_uniformValue; -} - } // namespace Render } // namespace Qt3DRender diff --git a/src/render/materialsystem/parameter_p.h b/src/render/materialsystem/parameter_p.h index 6830ef07d..21c88b56e 100644 --- a/src/render/materialsystem/parameter_p.h +++ b/src/render/materialsystem/parameter_p.h @@ -74,8 +74,8 @@ public: void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) Q_DECL_OVERRIDE; QString name() const; - int nameId() const Q_DECL_NOTHROW; - UniformValue uniformValue() const; + int nameId() const Q_DECL_NOTHROW { return m_nameId; } + const UniformValue &uniformValue() const { return m_uniformValue; } private: void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) Q_DECL_FINAL; diff --git a/src/render/materialsystem/techniquemanager_p.h b/src/render/materialsystem/techniquemanager_p.h index 5c86741c3..5b390f94b 100644 --- a/src/render/materialsystem/techniquemanager_p.h +++ b/src/render/materialsystem/techniquemanager_p.h @@ -64,7 +64,6 @@ class Q_AUTOTEST_EXPORT TechniqueManager : public Qt3DCore::QResourceManager< Technique, Qt3DCore::QNodeId, 16, - Qt3DCore::ArrayAllocatingPolicy, Qt3DCore::NonLockingPolicy> { public: diff --git a/src/render/texture/gltexture.cpp b/src/render/texture/gltexture.cpp index fae7fb487..2a35a6f7e 100644 --- a/src/render/texture/gltexture.cpp +++ b/src/render/texture/gltexture.cpp @@ -102,15 +102,14 @@ void GLTexture::destroyGLTexture() delete m_renderBuffer; m_renderBuffer = nullptr; - QMutexLocker locker(&m_dirtyFlagMutex); - m_dirty = 0; + m_dirtyFlags.store(0); destroyResources(); } QOpenGLTexture* GLTexture::getOrCreateGLTexture() { - QMutexLocker locker(&m_dirtyFlagMutex); + QMutexLocker locker(&m_textureMutex); bool needUpload = false; bool texturedDataInvalid = false; @@ -140,7 +139,7 @@ QOpenGLTexture* GLTexture::getOrCreateGLTexture() m_properties.mipLevels = imageData.first()->mipLevels(); } - m_dirty |= Properties; + setDirtyFlag(Properties, true); needUpload = true; } else { qWarning() << "[Qt3DRender::GLTexture] No QTextureData generated from Texture Generator yet. Texture will be invalid for this frame"; @@ -149,7 +148,7 @@ QOpenGLTexture* GLTexture::getOrCreateGLTexture() } // additional texture images may be defined through image data generators - if (m_dirty.testFlag(TextureData)) { + if (testDirtyFlag(TextureData)) { m_imageData.clear(); needUpload = true; @@ -173,7 +172,7 @@ QOpenGLTexture* GLTexture::getOrCreateGLTexture() m_properties.format = static_cast<QAbstractTexture::TextureFormat>(imgData->format()); } - m_dirty |= Properties; + setDirtyFlag(Properties, true); } } else { qWarning() << "[Qt3DRender::GLTexture] No QTextureImageData generated from functor yet, texture will be invalid for this frame"; @@ -190,7 +189,7 @@ QOpenGLTexture* GLTexture::getOrCreateGLTexture() return nullptr; // if the properties changed, we need to re-allocate the texture - if (m_dirty.testFlag(Properties)) { + if (testDirtyFlag(Properties)) { delete m_gl; m_gl = nullptr; } @@ -212,18 +211,21 @@ QOpenGLTexture* GLTexture::getOrCreateGLTexture() } // need to set texture parameters? - if (m_dirty.testFlag(Properties) || m_dirty.testFlag(Parameters)) { + if (testDirtyFlag(Properties) || testDirtyFlag(Parameters)) { updateGLTextureParameters(); } - m_dirty = 0; + // un-set properties and parameters. The TextureData flag might have been set by another thread + // in the meantime, so don't clear that. + setDirtyFlag(Properties, false); + setDirtyFlag(Parameters, false); return m_gl; } RenderBuffer *GLTexture::getOrCreateRenderBuffer() { - QMutexLocker locker(&m_dirtyFlagMutex); + QMutexLocker locker(&m_textureMutex); if (m_dataFunctor && !m_textureData) { m_textureData = m_textureDataManager->getData(m_dataFunctor); @@ -235,14 +237,14 @@ RenderBuffer *GLTexture::getOrCreateRenderBuffer() m_properties.height = m_textureData->height(); m_properties.format = m_textureData->format(); - m_dirty |= Properties; + setDirtyFlag(Properties); } else { qWarning() << "[Qt3DRender::GLTexture] [renderbuffer] No QTextureData generated from Texture Generator yet. Texture will be invalid for this frame"; return nullptr; } } - if (m_dirty.testFlag(Properties)) { + if (testDirtyFlag(Properties)) { delete m_renderBuffer; m_renderBuffer = nullptr; } @@ -250,27 +252,28 @@ RenderBuffer *GLTexture::getOrCreateRenderBuffer() if (!m_renderBuffer) m_renderBuffer = new RenderBuffer(m_properties.width, m_properties.height, m_properties.format); - m_dirty = 0; + setDirtyFlag(Properties, false); + setDirtyFlag(Parameters, false); return m_renderBuffer; } void GLTexture::setParameters(const TextureParameters ¶ms) { + QMutexLocker locker(&m_textureMutex); if (m_parameters != params) { m_parameters = params; - QMutexLocker locker(&m_dirtyFlagMutex); - m_dirty |= Parameters; + setDirtyFlag(Parameters); } } void GLTexture::setProperties(const TextureProperties &props) { + QMutexLocker locker(&m_textureMutex); if (m_properties != props) { m_properties = props; - QMutexLocker locker(&m_dirtyFlagMutex); m_actualTarget = props.target; - m_dirty |= Properties; + setDirtyFlag(Properties); } } diff --git a/src/render/texture/gltexture_p.h b/src/render/texture/gltexture_p.h index 30e9209e0..a8f5705e8 100644 --- a/src/render/texture/gltexture_p.h +++ b/src/render/texture/gltexture_p.h @@ -158,19 +158,17 @@ public: // a generator that needs to be uploaded. void requestUpload() { - QMutexLocker locker(&m_dirtyFlagMutex); - m_dirty |= TextureData; + setDirtyFlag(TextureData, true); } bool isDirty() { - QMutexLocker locker(&m_dirtyFlagMutex); - return m_dirty == 0 ? false : true; + return m_dirtyFlags.load() != 0; } QMutex *textureLock() { - return &m_dirtyFlagMutex; + return &m_textureMutex; } protected: @@ -198,7 +196,19 @@ private: Parameters = 0x04 // texture parameters need to be (re-)set }; - Q_DECLARE_FLAGS(DirtyFlags, DirtyFlag) + + bool testDirtyFlag(DirtyFlag flag) + { + return m_dirtyFlags.load() & flag; + } + + void setDirtyFlag(DirtyFlag flag, bool value = true) + { + if (value) + m_dirtyFlags |= flag; + else + m_dirtyFlags &= ~static_cast<int>(flag); + } QOpenGLTexture *buildGLTexture(); void uploadGLTextureData(); @@ -206,8 +216,8 @@ private: void destroyResources(); bool m_unique; - DirtyFlags m_dirty; - QMutex m_dirtyFlagMutex; + QAtomicInt m_dirtyFlags; + QMutex m_textureMutex; QOpenGLTexture *m_gl; RenderBuffer *m_renderBuffer; diff --git a/tests/auto/core/arrayresourcesmanager/arrayresourcesmanager.pro b/tests/auto/core/arrayresourcesmanager/arrayresourcesmanager.pro deleted file mode 100644 index cc929575f..000000000 --- a/tests/auto/core/arrayresourcesmanager/arrayresourcesmanager.pro +++ /dev/null @@ -1,5 +0,0 @@ -TEMPLATE = subdirs - -SUBDIRS = \ - dynamicarraypolicy \ - preallocatedarraypolicy diff --git a/tests/auto/core/arrayresourcesmanager/dynamicarraypolicy/dynamicarraypolicy.pro b/tests/auto/core/arrayresourcesmanager/dynamicarraypolicy/dynamicarraypolicy.pro deleted file mode 100644 index ee2a73e03..000000000 --- a/tests/auto/core/arrayresourcesmanager/dynamicarraypolicy/dynamicarraypolicy.pro +++ /dev/null @@ -1,7 +0,0 @@ -TARGET = tst_dynamicarraypolicy -CONFIG += testcase -TEMPLATE = app - -SOURCES += tst_dynamicarraypolicy.cpp - -QT += testlib 3dcore 3dcore-private diff --git a/tests/auto/core/arrayresourcesmanager/preallocatedarraypolicy/preallocatedarraypolicy.pro b/tests/auto/core/arrayresourcesmanager/preallocatedarraypolicy/preallocatedarraypolicy.pro deleted file mode 100644 index 636c155b2..000000000 --- a/tests/auto/core/arrayresourcesmanager/preallocatedarraypolicy/preallocatedarraypolicy.pro +++ /dev/null @@ -1,7 +0,0 @@ -TARGET = tst_preallocatedarraypolicy -CONFIG += testcase -TEMPLATE = app - -SOURCES += tst_preallocatedarraypolicy.cpp - -QT += testlib 3dcore 3dcore-private diff --git a/tests/auto/core/arrayresourcesmanager/preallocatedarraypolicy/tst_preallocatedarraypolicy.cpp b/tests/auto/core/arrayresourcesmanager/preallocatedarraypolicy/tst_preallocatedarraypolicy.cpp deleted file mode 100644 index dbed2abfb..000000000 --- a/tests/auto/core/arrayresourcesmanager/preallocatedarraypolicy/tst_preallocatedarraypolicy.cpp +++ /dev/null @@ -1,426 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtTest/QtTest> -#include <QList> -#include <Qt3DCore/private/qresourcemanager_p.h> -#include <Qt3DCore/private/qhandle_p.h> - -class tst_PreallocatedArrayPolicy : public QObject -{ - Q_OBJECT -public: - tst_PreallocatedArrayPolicy() {} - ~tst_PreallocatedArrayPolicy() {} - -private slots: - void createResourcesManager(); - void acquireResources(); - void getResources(); - void registerResourcesResize(); - void removeResource(); - void resetResource(); - void lookupResource(); - void releaseResource(); - void heavyDutyMultiThreadedAccess(); - void heavyDutyMultiThreadedAccessRelease(); - void maximumNumberOfResources(); -}; - -class tst_ArrayResource -{ -public: - tst_ArrayResource() : m_value(0) - {} - - QAtomicInt m_value; -}; - -typedef Qt3DCore::QHandle<tst_ArrayResource> tHandle; -typedef Qt3DCore::QHandle<tst_ArrayResource, 4> tHandle4; -typedef Qt3DCore::QHandle<tst_ArrayResource, 8> tHandle8; -typedef Qt3DCore::QHandle<tst_ArrayResource, 16> tHandle16; - -void tst_PreallocatedArrayPolicy::createResourcesManager() -{ - Qt3DCore::QResourceManager<tst_ArrayResource, int, 16, Qt3DCore::ArrayPreallocationPolicy> manager16; - Qt3DCore::QResourceManager<tst_ArrayResource, int, 4, Qt3DCore::ArrayPreallocationPolicy> manager4; - Qt3DCore::QResourceManager<tst_ArrayResource, int, 8, Qt3DCore::ArrayPreallocationPolicy> manager8; - QVERIFY(manager16.maximumSize() == 65535); - QVERIFY(manager8.maximumSize() == 255); - QVERIFY(manager4.maximumSize() == 15); -} - -/*! - * Check that the handles returned when a registering resources - * have a correct index and counter. - */ -void tst_PreallocatedArrayPolicy::acquireResources() -{ - Qt3DCore::QResourceManager<tst_ArrayResource, uint, 4, Qt3DCore::ArrayPreallocationPolicy> manager; - - QList<tHandle4> handles; - - for (int i = 0; i < 5; i++) { - handles << manager.acquire(); - } - - for (uint i = 0; i < 5; i++) { - QVERIFY(handles.at(i).index() == i); - QVERIFY(handles.at(i).counter() == 1); - } -} - -/*! - * Test that values can be properly retrieved. - */ -void tst_PreallocatedArrayPolicy::getResources() -{ - - Qt3DCore::QResourceManager<tst_ArrayResource, int, 8, Qt3DCore::ArrayPreallocationPolicy> manager; - QList<tst_ArrayResource *> resources; - QList<tHandle8> handles; - - for (int i = 0; i < 5; i++) { - handles << manager.acquire(); - } - - for (uint i = 0; i < 5; i++) { - QVERIFY(handles.at(i).index() == i); - QVERIFY(handles.at(i).counter() == 1); - resources << manager.data(handles.at(i)); - QVERIFY(resources.at(i) != nullptr); - resources.at(i)->m_value = i; - } - - for (int i = 0; i < 5; i++) - QVERIFY(manager.data(handles.at(i))->m_value == i); - - // Check that an invalid resource returns NULL - tHandle8 iHandle; - QVERIFY(manager.data(iHandle) == nullptr); - -} - -/*! - * Test that when a resize of the data vectors in the manager occurs, - * everything behaves correctly. - */ -void tst_PreallocatedArrayPolicy::registerResourcesResize() -{ - Qt3DCore::QResourceManager<tst_ArrayResource, uint, 16, Qt3DCore::ArrayPreallocationPolicy> manager; - QList<tHandle16> handles; - - for (uint i = 0; i < 2; i++) { - handles << manager.acquire(); - manager.data(handles.at(i))->m_value = i + 2; - } - - for (uint i = 0; i < 5; i++) { - handles << manager.acquire(); - manager.data(handles.at(i + 2))->m_value = i + 2 + 5; - } - - for (int i = 0; i < 7; i++) { - QVERIFY(handles.at(i).index() == static_cast<uint>(i)); - QVERIFY(handles.at(i).counter() == 1); - if (i < 2) - QVERIFY(manager.data(handles.at(i))->m_value == i + 2); - else - QVERIFY(manager.data(handles.at(i))->m_value == i + 5); - } -} - -/*! - * Checks for the removal of resources. - */ -void tst_PreallocatedArrayPolicy::removeResource() -{ - Qt3DCore::QResourceManager<tst_ArrayResource, int, 16, Qt3DCore::ArrayPreallocationPolicy> manager; - - QList<tst_ArrayResource *> resources; - QList<tHandle> handles; - - for (int i = 0; i < 32; i++) { - handles << manager.acquire(); - resources << manager.data(handles.at(i)); - } - - manager.release(handles.at(2)); - QVERIFY(manager.data(handles.at(2)) == nullptr); - // Triggers QASSERT so commented - // manager.release(handles.at(2)); - - tHandle nHandle = manager.acquire(); - QVERIFY(manager.data(nHandle) != nullptr); -} - -/*! - * Checks that reset behaves correctly. - */ -void tst_PreallocatedArrayPolicy::resetResource() -{ - Qt3DCore::QResourceManager<tst_ArrayResource, uint, 16, Qt3DCore::ArrayPreallocationPolicy> manager; - - QList<tst_ArrayResource *> resources; - QList<tHandle16> handles; - - for (int i = 0; i < 5; i++) { - handles << manager.acquire(); - resources << manager.data(handles.at(i)); - resources.at(i)->m_value = 4; - } - manager.reset(); - for (uint i = 0; i < 5; i++) { - QVERIFY(manager.data(handles.at(i)) == nullptr); - } - handles.clear(); - for (uint i = 0; i < 5; i++) - handles << manager.acquire(); - - for (uint i = 0; i < 5; i++) { - QVERIFY(handles.at(i).index() == i); - QVERIFY(handles.at(i).counter() == 1); - QVERIFY(manager.data(handles.at(i))->m_value != 4); - } -} - -void tst_PreallocatedArrayPolicy::lookupResource() -{ - Qt3DCore::QResourceManager<tst_ArrayResource, uint, 16, Qt3DCore::ArrayPreallocationPolicy> manager; - - QList<tst_ArrayResource *> resources; - QList<tHandle16> handles; - - for (int i = 0; i < 5; i++) { - handles << manager.acquire(); - resources << manager.data(handles.at(i)); - resources.at(i)->m_value = 4; - } - - tHandle16 t = manager.lookupHandle(2); - QVERIFY(t.handle() == 0); - QVERIFY(manager.data(t) == nullptr); - tst_ArrayResource *resource = manager.getOrCreateResource(2); - QVERIFY(resource != nullptr); - t = manager.lookupHandle(2); - QVERIFY(manager.data(t) == manager.lookupResource(2)); - QVERIFY(t == manager.getOrAcquireHandle(2)); - QVERIFY(resource == manager.getOrCreateResource(2)); - QVERIFY(manager.data(t) == resource); -} - -void tst_PreallocatedArrayPolicy::releaseResource() -{ - Qt3DCore::QResourceManager<tst_ArrayResource, uint, 16, Qt3DCore::ArrayPreallocationPolicy> manager; - QList<tst_ArrayResource *> resources; - - for (int i = 0; i < 5; i++) { - resources << manager.getOrCreateResource(i); - } - - for (int i = 0; i < 5; i++) { - QVERIFY(resources.at(i) == manager.lookupResource(i)); - } - - for (int i = 0; i < 5; i++) { - manager.releaseResource(i); - QVERIFY(manager.lookupResource(i) == nullptr); - } -} - -class tst_Thread : public QThread -{ - Q_OBJECT -public: - - typedef Qt3DCore::QResourceManager<tst_ArrayResource, - int, - 16, - Qt3DCore::ArrayPreallocationPolicy, - Qt3DCore::ObjectLevelLockingPolicy> Manager; - - tst_Thread() - : QThread() - { - } - - void setManager(Manager *manager) - { - m_manager = manager; - } - - // QThread interface -protected: - void run() - { - int i = 0; - int max = tHandle::maxIndex(); - while (i < max) { - tst_ArrayResource *r = m_manager->getOrCreateResource(i); - i++; - QVERIFY(r != nullptr); - Manager::Locker lock(m_manager); - r->m_value++; - } - qDebug() << QThread::currentThread() << "Done"; - } - - Manager *m_manager; -}; - -void tst_PreallocatedArrayPolicy::heavyDutyMultiThreadedAccess() -{ - tst_Thread::Manager *manager = new tst_Thread::Manager(); - - QList<tst_Thread *> threads; - - int iterations = 8; - int max = tHandle16::maxIndex(); - - for (int i = 0; i < iterations; i++) { - tst_Thread *thread = new tst_Thread(); - thread->setManager(manager); - threads << thread; - } - - for (int i = 0; i < iterations; i++) { - threads[i]->start(); - } - - for (int i = 0; i < iterations; i++) { - threads[i]->wait(); - } - - for (int i = 0; i < max; i++) { - QVERIFY(manager->lookupResource(i) != nullptr); - QVERIFY(manager->lookupResource(i)->m_value = iterations); - } - - qDeleteAll(threads); - delete manager; -} - -class tst_Thread2 : public QThread -{ - Q_OBJECT -public: - - typedef Qt3DCore::QResourceManager<tst_ArrayResource, - int, - 16, - Qt3DCore::ArrayPreallocationPolicy, - Qt3DCore::ObjectLevelLockingPolicy> Manager; - - tst_Thread2(int releaseAbove = 7) - : QThread() - , m_releaseAbove(releaseAbove) - { - } - - void setManager(Manager *manager) - { - m_manager = manager; - } - - // QThread interface -protected: - void run() - { - int i = 0; - int max = tHandle::maxIndex(); - while (i < max) { - tst_ArrayResource *r = m_manager->getOrCreateResource(i); - QVERIFY(r != nullptr); - int oldValue = r->m_value.fetchAndAddOrdered(+1); - if (oldValue == m_releaseAbove) - m_manager->releaseResource(i); - i++; - } - qDebug() << QThread::currentThread() << "Done"; - } - - Manager *m_manager; - int m_releaseAbove; -}; - -void tst_PreallocatedArrayPolicy::heavyDutyMultiThreadedAccessRelease() -{ - tst_Thread2::Manager *manager = new tst_Thread2::Manager(); - - QList<tst_Thread2 *> threads; - - int iterations = 8; - int max = tHandle16::maxIndex(); - - for (int u = 0; u < 2; u++) { - - for (int i = 0; i < iterations; i++) { - tst_Thread2 *thread = new tst_Thread2(); - thread->setManager(manager); - threads << thread; - } - - for (int i = 0; i < iterations; i++) { - threads[i]->start(); - } - - for (int i = 0; i < iterations; i++) { - threads[i]->wait(); - } - - for (int i = 0; i < max; i++) { - QVERIFY(manager->lookupResource(i) == nullptr); - } - - qDeleteAll(threads); - threads.clear(); - } - - delete manager; -} - -void tst_PreallocatedArrayPolicy::maximumNumberOfResources() -{ - Qt3DCore::QResourceManager<tst_ArrayResource, uint, 16, Qt3DCore::ArrayPreallocationPolicy> manager; - - QList<tst_ArrayResource *> resources; - QList<tHandle16> handles; - - QCOMPARE(tHandle16::maxIndex(), (uint)manager.maximumSize()); - - for (int i = 0; i < manager.maximumSize(); i++) { - handles << manager.acquire(); - resources << manager.data(handles.at(i)); - resources.at(i)->m_value = 4; - } -} - -QTEST_APPLESS_MAIN(tst_PreallocatedArrayPolicy) - -#include "tst_preallocatedarraypolicy.moc" diff --git a/tests/auto/core/core.pro b/tests/auto/core/core.pro index 4ac74471e..25440ce0e 100644 --- a/tests/auto/core/core.pro +++ b/tests/auto/core/core.pro @@ -2,8 +2,7 @@ TEMPLATE = subdirs SUBDIRS = \ handle \ - handlemanager \ - arrayresourcesmanager \ + qresourcemanager \ qcircularbuffer \ qboundedcircularbuffer \ nodes \ diff --git a/tests/auto/core/handlemanager/tst_handlemanager.cpp b/tests/auto/core/handlemanager/tst_handlemanager.cpp deleted file mode 100644 index f4879a3df..000000000 --- a/tests/auto/core/handlemanager/tst_handlemanager.cpp +++ /dev/null @@ -1,306 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtTest/QtTest> -#include <Qt3DCore/private/qhandlemanager_p.h> -#include <Qt3DCore/private/qhandle_p.h> - -class tst_HandleManager : public QObject -{ - Q_OBJECT -public: - tst_HandleManager() {} - ~tst_HandleManager() {} - -private slots: - void construction(); - void correctPointer(); - void correctPointers(); - void correctConstPointer(); - void nullForRemovedEntry(); - void validHandleForReplacementEntry(); - void updateChangesValue(); - void resetRemovesAllEntries(); - void maximumEntries(); - void checkNoCounterOverflow(); -}; - -class SimpleResource -{ -public: - SimpleResource() - : m_value(0) - {} - - int m_value; -}; - -typedef Qt3DCore::QHandle<SimpleResource> Handle; - -void tst_HandleManager::construction() -{ - // GIVEN - Qt3DCore::QHandleManager<SimpleResource> manager; - - // THEN - QVERIFY(manager.activeEntries() == 0); -} - -void tst_HandleManager::correctPointer() -{ - // GIVEN - Qt3DCore::QHandleManager<SimpleResource> manager; - SimpleResource *p1 = (SimpleResource *)(quintptr)0xdeadbeef; - - // WHEN - const Handle h = manager.acquire(p1); - - bool ok = false; - SimpleResource *p2 = manager.data(h, &ok); - - // THEN - QVERIFY(ok == true); - QVERIFY(p1 == p2); -} - -void tst_HandleManager::correctPointers() -{ - // GIVEN - Qt3DCore::QHandleManager<SimpleResource> manager; - SimpleResource *p[3]; - p[0] = (SimpleResource *)(quintptr)0xdeadbeef; - p[1] = (SimpleResource *)(quintptr)0x11111111; - p[2] = (SimpleResource *)(quintptr)0x22222222; - - // WHEN - for (int i = 0; i < 3; ++i) { - // WHEN - const Handle h = manager.acquire(p[i]); - - bool ok = false; - SimpleResource *q = manager.data(h, &ok); - - // THEN - QVERIFY(ok == true); - QVERIFY(p[i] == q); - } - - // THEN - QVERIFY(manager.activeEntries() == 3); -} - -void tst_HandleManager::correctConstPointer() -{ - // GIVEN - Qt3DCore::QHandleManager<SimpleResource> manager; - QSharedPointer<SimpleResource> p1(new SimpleResource); - const Handle h = manager.acquire(p1.data()); - - // WHEN - bool ok = false; - const SimpleResource *p2 = manager.constData(h, &ok); - - // THEN - QVERIFY(ok == true); - QVERIFY(p1.data() == p2); -} - -void tst_HandleManager::nullForRemovedEntry() -{ - // GIVEN - Qt3DCore::QHandleManager<SimpleResource> manager; - QSharedPointer<SimpleResource> p1(new SimpleResource); - const Handle h = manager.acquire(p1.data()); - - // WHEN - manager.release(h); - - // THEN - bool ok = false; - SimpleResource *p2 = manager.data(h, &ok); - QVERIFY(ok == false); - QVERIFY(p2 == nullptr); -} - -void tst_HandleManager::validHandleForReplacementEntry() -{ - // GIVEN - Qt3DCore::QHandleManager<SimpleResource> manager; - QSharedPointer<SimpleResource> p1(new SimpleResource); - const Handle h = manager.acquire(p1.data()); - - // THEN - QVERIFY(manager.activeEntries() == 1); - - // WHEN - manager.release(h); - - // THEN - QVERIFY(manager.activeEntries() == 0); - - // WHEN - QSharedPointer<SimpleResource> p2(new SimpleResource); - const Handle h2 = manager.acquire(p2.data()); - - // THEN - QVERIFY(h2.isNull() == false); - QVERIFY(h2.counter() == 2); - QVERIFY(manager.activeEntries() == 1); - - // WHEN - bool ok = false; - SimpleResource *p3 = manager.data(h2, &ok); - - // THEN - QVERIFY(ok == true); - QVERIFY(p3 == p2); -} - -void tst_HandleManager::updateChangesValue() -{ - // GIVEN - Qt3DCore::QHandleManager<SimpleResource> manager; - QSharedPointer<SimpleResource> p1(new SimpleResource); - const Handle h = manager.acquire(p1.data()); - - // WHEN - QSharedPointer<SimpleResource> p2(new SimpleResource); - manager.update(h, p2.data()); - - // THEN - QVERIFY(manager.activeEntries() == 1); - - // WHEN - bool ok = false; - SimpleResource *p3 = manager.data(h, &ok); - - // THEN - QVERIFY(ok == true); - QVERIFY(p3 == p2); -} - -void tst_HandleManager::resetRemovesAllEntries() -{ - // GIVEN - Qt3DCore::QHandleManager<SimpleResource> manager; - - // WHEN - for (int i = 0; i < 100; ++i) { - SimpleResource *p = (SimpleResource *)(quintptr)(0xdead0000 + i); - const Handle h = manager.acquire(p); - - bool ok = false; - SimpleResource *q = manager.data(h, &ok); - QVERIFY(ok == true); - QVERIFY(p == q); - } - - // THEN - QVERIFY(manager.activeEntries() == 100); - - // WHEN - manager.reset(); - - // THEN - QVERIFY(manager.activeEntries() == 0); -} - -void tst_HandleManager::maximumEntries() -{ - // GIVEN - Qt3DCore::QHandleManager<SimpleResource> manager; - - // THEN - QCOMPARE(Handle::maxIndex(), (uint)((1 << 16) - 1)); - - // WHEN - for (int i = 0; i < (int)Handle::maxIndex(); ++i) { - SimpleResource *p = (SimpleResource *)(quintptr)(0xdead0000 + i); - const Handle h = manager.acquire(p); - - bool ok = false; - SimpleResource *q = manager.data(h, &ok); - QVERIFY(ok == true); - QVERIFY(p == q); - } - - // THEN - QVERIFY(manager.activeEntries() == Handle::maxIndex());\ - - // WHEN - manager.reset(); - - // THEN - QVERIFY(manager.activeEntries() == 0); -} - -void tst_HandleManager::checkNoCounterOverflow() -{ - // GIVEN - const int indexBits = 16; - Qt3DCore::QHandleManager<SimpleResource, indexBits> manager; - SimpleResource *p = (SimpleResource *)(quintptr)0xdead0000; - Qt3DCore::QHandle<SimpleResource, indexBits> h = manager.acquire(p); - - // THEN - QCOMPARE(h.maxCounter(), (quint32)((1 << (32 - indexBits - 2)) - 1)); - QCOMPARE(h.counter(), (quint32)1); - - // WHEN - const quint32 maxIterations = h.maxCounter() - 2; - const quint32 handleIndex = h.index(); - - qDebug() << maxIterations << handleIndex; - - // Acquire and release maxIteration time to increase counter - for (quint32 i = 0; i < maxIterations; ++i) { - // WHEN - manager.release(h); - h = manager.acquire(p); - - // THEN - QCOMPARE(h.index(), handleIndex); - QCOMPARE(h.counter(), i + 2); - } - - // THEN - QCOMPARE(h.counter(), h.maxCounter() - 1); - - // WHEN - manager.release(h); - h = manager.acquire(p); - - // THEN - QCOMPARE(h.counter(), (quint32)1); -} - - - -QTEST_APPLESS_MAIN(tst_HandleManager) - -#include "tst_handlemanager.moc" diff --git a/tests/auto/core/handlemanager/handlemanager.pro b/tests/auto/core/qresourcemanager/qresourcemanager.pro index ad18d5b9b..8fdf9b569 100644 --- a/tests/auto/core/handlemanager/handlemanager.pro +++ b/tests/auto/core/qresourcemanager/qresourcemanager.pro @@ -1,7 +1,7 @@ -TARGET = tst_handlemanager +TARGET = tst_qresourcemanager CONFIG += testcase TEMPLATE = app -SOURCES += tst_handlemanager.cpp +SOURCES += tst_qresourcemanager.cpp QT += testlib 3dcore 3dcore-private diff --git a/tests/auto/core/arrayresourcesmanager/dynamicarraypolicy/tst_dynamicarraypolicy.cpp b/tests/auto/core/qresourcemanager/tst_qresourcemanager.cpp index 874ac42ca..c3238fc8f 100644 --- a/tests/auto/core/arrayresourcesmanager/dynamicarraypolicy/tst_dynamicarraypolicy.cpp +++ b/tests/auto/core/qresourcemanager/tst_qresourcemanager.cpp @@ -44,7 +44,6 @@ private slots: void getResources(); void registerResourcesResize(); void removeResource(); - void resetResource(); void lookupResource(); void releaseResource(); void heavyDutyMultiThreadedAccess(); @@ -187,36 +186,6 @@ void tst_DynamicArrayPolicy::removeResource() QVERIFY(manager.data(nHandle) != nullptr); } -/*! - * Checks that reset behaves correctly. - */ -void tst_DynamicArrayPolicy::resetResource() -{ - Qt3DCore::QResourceManager<tst_ArrayResource, uint> manager; - - QList<tst_ArrayResource *> resources; - QList<tHandle16> handles; - - for (int i = 0; i < 5; i++) { - handles << manager.acquire(); - resources << manager.data(handles.at(i)); - resources.at(i)->m_value = 4; - } - manager.reset(); - for (uint i = 0; i < 5; i++) { - QVERIFY(manager.data(handles.at(i)) == nullptr); - } - handles.clear(); - for (uint i = 0; i < 5; i++) - handles << manager.acquire(); - - for (uint i = 0; i < 5; i++) { - QVERIFY(handles.at(i).index() == i); - QVERIFY(handles.at(i).counter() == 1); - QVERIFY(manager.data(handles.at(i))->m_value != 4); - } -} - void tst_DynamicArrayPolicy::lookupResource() { Qt3DCore::QResourceManager<tst_ArrayResource, uint> manager; @@ -269,7 +238,6 @@ public: typedef Qt3DCore::QResourceManager<tst_ArrayResource, int, 16, - Qt3DCore::ArrayAllocatingPolicy, Qt3DCore::ObjectLevelLockingPolicy> Manager; tst_Thread() @@ -340,7 +308,6 @@ public: typedef Qt3DCore::QResourceManager<tst_ArrayResource, int, 16, - Qt3DCore::ArrayAllocatingPolicy, Qt3DCore::ObjectLevelLockingPolicy> Manager; tst_Thread2(int releaseAbove = 7) @@ -466,4 +433,4 @@ void tst_DynamicArrayPolicy::activeHandles() QTEST_APPLESS_MAIN(tst_DynamicArrayPolicy) -#include "tst_dynamicarraypolicy.moc" +#include "tst_qresourcemanager.moc" diff --git a/tests/auto/render/graphicshelpergl2/tst_graphicshelpergl2.cpp b/tests/auto/render/graphicshelpergl2/tst_graphicshelpergl2.cpp index 292bcfba3..584b675ee 100644 --- a/tests/auto/render/graphicshelpergl2/tst_graphicshelpergl2.cpp +++ b/tests/auto/render/graphicshelpergl2/tst_graphicshelpergl2.cpp @@ -951,7 +951,13 @@ private Q_SLOTS: ADD_UNIFORM_ENTRY(fragCodeUniformsInt, "multiplierVec4", GL_INT_VEC4, 1, 4 * 4); ADD_UNIFORM_ENTRY(fragCodeUniformsFloatMatrices, "m2", GL_FLOAT_MAT2, 1, 4 * 2 * 2); + ADD_UNIFORM_ENTRY(fragCodeUniformsFloatMatrices, "m23", GL_FLOAT_MAT2x3, 1, 4 * 2 * 3); + ADD_UNIFORM_ENTRY(fragCodeUniformsFloatMatrices, "m32", GL_FLOAT_MAT3x2, 1, 4 * 3 * 2); + ADD_UNIFORM_ENTRY(fragCodeUniformsFloatMatrices, "m24", GL_FLOAT_MAT2x4, 1, 4 * 2 * 4); + ADD_UNIFORM_ENTRY(fragCodeUniformsFloatMatrices, "m42", GL_FLOAT_MAT4x2, 1, 4 * 4 * 2); ADD_UNIFORM_ENTRY(fragCodeUniformsFloatMatrices, "m3", GL_FLOAT_MAT3, 1, 4 * 3 * 3); + ADD_UNIFORM_ENTRY(fragCodeUniformsFloatMatrices, "m34", GL_FLOAT_MAT3x4, 1, 4 * 3 * 4); + ADD_UNIFORM_ENTRY(fragCodeUniformsFloatMatrices, "m43", GL_FLOAT_MAT4x3, 1, 4 * 4 * 3); ADD_UNIFORM_ENTRY(fragCodeUniformsFloatMatrices, "m4", GL_FLOAT_MAT4, 1, 4 * 4 * 4); ADD_UNIFORM_ENTRY(fragCodeSamplers, "s1", GL_SAMPLER_1D, 1, 4); diff --git a/tests/auto/render/pickboundingvolumejob/pickboundingvolumejob.qrc b/tests/auto/render/pickboundingvolumejob/pickboundingvolumejob.qrc index fbd6a0a05..c2b0c7fff 100644 --- a/tests/auto/render/pickboundingvolumejob/pickboundingvolumejob.qrc +++ b/tests/auto/render/pickboundingvolumejob/pickboundingvolumejob.qrc @@ -7,5 +7,6 @@ <file>testscene_dragenabledhoverenabled.qml</file> <file>testscene_pickersdisabled.qml</file> <file>testscene_dragenabledoverlapping.qml</file> + <file>testscene_parententity.qml</file> </qresource> </RCC> diff --git a/tests/auto/render/pickboundingvolumejob/testscene_parententity.qml b/tests/auto/render/pickboundingvolumejob/testscene_parententity.qml new file mode 100644 index 000000000..759544bb9 --- /dev/null +++ b/tests/auto/render/pickboundingvolumejob/testscene_parententity.qml @@ -0,0 +1,132 @@ +/**************************************************************************** +** +** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import Qt3D.Core 2.0 +import Qt3D.Render 2.0 +import Qt3D.Extras 2.0 +import QtQuick.Window 2.0 + +Entity { + id: sceneRoot + + Window { + id: win + width: 600 + height: 600 + visible: true + } + + Camera { + id: camera + projectionType: CameraLens.PerspectiveProjection + fieldOfView: 45 + nearPlane : 0.1 + farPlane : 1000.0 + position: Qt.vector3d( 0.0, 0.0, -40.0 ) + upVector: Qt.vector3d( 0.0, 1.0, 0.0 ) + viewCenter: Qt.vector3d( 0.0, 0.0, 0.0 ) + } + + components: [ + RenderSettings { + Viewport { + normalizedRect: Qt.rect(0.0, 0.0, 1.0, 1.0) + + RenderSurfaceSelector { + + surface: win + + ClearBuffers { + buffers : ClearBuffers.ColorDepthBuffer + NoDraw {} + } + + CameraSelector { + camera: camera + } + } + } + } + ] + + CuboidMesh { id: cubeMesh } + PhongMaterial { id: material } + + // Parent Entity + Entity { + + Entity { + components: [ + PlaneMesh { + width: 100 + height: 100 + }, + PhongMaterial { + } + ] + } + + // Child Entity + Entity { + property Transform transform: Transform { + translation: Qt.vector3d(-5, 0, 0) + scale: 2.0 + } + + property ObjectPicker picker: ObjectPicker { + objectName: "Picker" + dragEnabled: true + } + + components: [cubeMesh, material, transform, picker] + } + } + +} diff --git a/tests/auto/render/pickboundingvolumejob/tst_pickboundingvolumejob.cpp b/tests/auto/render/pickboundingvolumejob/tst_pickboundingvolumejob.cpp index e2cc190df..d9d90a03d 100644 --- a/tests/auto/render/pickboundingvolumejob/tst_pickboundingvolumejob.cpp +++ b/tests/auto/render/pickboundingvolumejob/tst_pickboundingvolumejob.cpp @@ -1156,6 +1156,56 @@ private Q_SLOTS: arbiter1.events.clear(); arbiter2.events.clear(); } + + void checkParentNoPickerChildPicker() + { + // GIVEN + QmlSceneReader sceneReader(QUrl("qrc:/testscene_parententity.qml")); + QScopedPointer<Qt3DCore::QNode> root(qobject_cast<Qt3DCore::QNode *>(sceneReader.root())); + QVERIFY(root); + + QList<Qt3DRender::QRenderSettings *> renderSettings = root->findChildren<Qt3DRender::QRenderSettings *>(); + QCOMPARE(renderSettings.size(), 1); + Qt3DRender::QPickingSettings *settings = renderSettings.first()->pickingSettings(); + + settings->setPickMethod(Qt3DRender::QPickingSettings::BoundingVolumePicking); + settings->setPickResultMode(Qt3DRender::QPickingSettings::NearestPick); + settings->setFaceOrientationPickingMode(Qt3DRender::QPickingSettings::FrontFace); + + QScopedPointer<Qt3DRender::TestAspect> test(new Qt3DRender::TestAspect(root.data())); + TestArbiter arbiter; + + // Runs Required jobs + runRequiredJobs(test.data()); + + // THEN + // large no pickable object encapsing child and camera should not interfere with smaller picking object + QList<Qt3DRender::QObjectPicker *> pickers = root->findChildren<Qt3DRender::QObjectPicker *>(); + QCOMPARE(pickers.size(), 1); + + Qt3DRender::QObjectPicker *picker = pickers.first(); + QCOMPARE(pickers.first()->objectName(), QLatin1String("Picker")); + + Qt3DRender::Render::ObjectPicker *backendPicker = test->nodeManagers()->objectPickerManager()->lookupResource(picker->id()); + QVERIFY(backendPicker); + Qt3DCore::QBackendNodePrivate::get(backendPicker)->setArbiter(&arbiter); + + // WHEN -> Pressed on object + Qt3DRender::Render::PickBoundingVolumeJob pickBVJob; + initializePickBoundingVolumeJob(&pickBVJob, test.data()); + + QList<QMouseEvent> events; + events.push_back(QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(400.0f, 300.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)); + pickBVJob.setMouseEvents(events); + bool earlyReturn = !pickBVJob.runHelper(); + + // THEN -> Pressed + QVERIFY(!earlyReturn); + QVERIFY(backendPicker->isPressed()); + QCOMPARE(arbiter.events.count(), 1); + Qt3DCore::QPropertyUpdatedChangePtr change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>(); + QCOMPARE(change->propertyName(), "pressed"); + } }; QTEST_MAIN(tst_PickBoundingVolumeJob) diff --git a/tests/auto/render/qrendersurfaceselector/tst_qrendersurfaceselector.cpp b/tests/auto/render/qrendersurfaceselector/tst_qrendersurfaceselector.cpp index 1e003e6b8..982a58b2b 100644 --- a/tests/auto/render/qrendersurfaceselector/tst_qrendersurfaceselector.cpp +++ b/tests/auto/render/qrendersurfaceselector/tst_qrendersurfaceselector.cpp @@ -188,8 +188,8 @@ private Q_SLOTS: void checkCreationData() { // GIVEN - Qt3DRender::QRenderSurfaceSelector renderSurfaceSelector; QWindow newValue; + Qt3DRender::QRenderSurfaceSelector renderSurfaceSelector; renderSurfaceSelector.setSurface(&newValue); renderSurfaceSelector.setExternalRenderTargetSize(QSize(128, 128)); @@ -250,10 +250,10 @@ private Q_SLOTS: void checkSurfaceUpdate() { // GIVEN + QWindow newWindow; TestArbiter arbiter; Qt3DRender::QRenderSurfaceSelector renderSurfaceSelector; arbiter.setArbiterOnNode(&renderSurfaceSelector); - QWindow newWindow; { // WHEN diff --git a/tests/benchmarks/core/qresourcesmanager/arraypolicy/tst_bench_arraypolicy.cpp b/tests/benchmarks/core/qresourcesmanager/arraypolicy/tst_bench_arraypolicy.cpp index 0d89bd8c4..0813fff91 100644 --- a/tests/benchmarks/core/qresourcesmanager/arraypolicy/tst_bench_arraypolicy.cpp +++ b/tests/benchmarks/core/qresourcesmanager/arraypolicy/tst_bench_arraypolicy.cpp @@ -38,11 +38,6 @@ private Q_SLOTS: void benchmarkDynamicReleaseSmallResources(); void benchmarkDynamicAllocateBigResources(); void benchmarkDynamicReleaseBigResources(); - - void benchmarkPreallocatedAllocateSmallResources(); - void benchmarkPreallocatedReleaseSmallResources(); - void benchmarkPreallocatedAllocateBigResources(); - void benchmarkPreallocatedReleaseBigResources(); }; struct SmallType @@ -55,33 +50,32 @@ struct BigType QMatrix4x4 a; }; -template<typename C, typename T> +template<typename T> void benchmarkAllocateResources() { - C allocator; + Qt3DCore::ArrayAllocatingPolicy<T> allocator; const int max = (1 << 16) - 1; QBENCHMARK_ONCE { for (int i = 0; i < max; i++) { - T* ptr = allocator.allocateResource(); - Q_UNUSED(ptr); + (void) allocator.allocateResource(); } } } -template<typename C, typename T> +template<typename T> void benchmarkReleaseResources() { - C allocator; + Qt3DCore::ArrayAllocatingPolicy<T> allocator; const int max = (1 << 16) - 1; - QVector<T*> resources(max); + QVector<Qt3DCore::QHandle<T>> resources(max); for (int i = 0; i < max; i++) { resources[i] = allocator.allocateResource(); } QBENCHMARK_ONCE { - foreach (T* ptr, resources) { + foreach (auto ptr, resources) { allocator.releaseResource(ptr); } } @@ -89,42 +83,22 @@ void benchmarkReleaseResources() void tst_ArrayPolicy::benchmarkDynamicAllocateSmallResources() { - benchmarkAllocateResources<Qt3DCore::ArrayAllocatingPolicy<SmallType, 16>, SmallType>(); + benchmarkAllocateResources<SmallType>(); } void tst_ArrayPolicy::benchmarkDynamicReleaseSmallResources() { - benchmarkReleaseResources<Qt3DCore::ArrayAllocatingPolicy<SmallType, 16>, SmallType>(); + benchmarkReleaseResources<SmallType>(); } void tst_ArrayPolicy::benchmarkDynamicAllocateBigResources() { - benchmarkAllocateResources<Qt3DCore::ArrayAllocatingPolicy<BigType, 16>, BigType>(); + benchmarkAllocateResources<BigType>(); } void tst_ArrayPolicy::benchmarkDynamicReleaseBigResources() { - benchmarkReleaseResources<Qt3DCore::ArrayAllocatingPolicy<BigType, 16>, BigType>(); -} - -void tst_ArrayPolicy::benchmarkPreallocatedAllocateSmallResources() -{ - benchmarkAllocateResources<Qt3DCore::ArrayPreallocationPolicy<SmallType, 16>, SmallType>(); -} - -void tst_ArrayPolicy::benchmarkPreallocatedReleaseSmallResources() -{ - benchmarkReleaseResources<Qt3DCore::ArrayPreallocationPolicy<SmallType, 16>, SmallType>(); -} - -void tst_ArrayPolicy::benchmarkPreallocatedAllocateBigResources() -{ - benchmarkAllocateResources<Qt3DCore::ArrayPreallocationPolicy<BigType, 16>, BigType>(); -} - -void tst_ArrayPolicy::benchmarkPreallocatedReleaseBigResources() -{ - benchmarkReleaseResources<Qt3DCore::ArrayPreallocationPolicy<BigType, 16>, BigType>(); + benchmarkReleaseResources<BigType>(); } QTEST_APPLESS_MAIN(tst_ArrayPolicy) diff --git a/tests/benchmarks/core/qresourcesmanager/qresourcesmanager/tst_bench_qresourcesmanager.cpp b/tests/benchmarks/core/qresourcesmanager/qresourcesmanager/tst_bench_qresourcesmanager.cpp index 48b12b5f2..6ddb058a1 100644 --- a/tests/benchmarks/core/qresourcesmanager/qresourcesmanager/tst_bench_qresourcesmanager.cpp +++ b/tests/benchmarks/core/qresourcesmanager/qresourcesmanager/tst_bench_qresourcesmanager.cpp @@ -161,7 +161,7 @@ void benchmarkReleaseResources() handles[i] = manager.acquire(); QBENCHMARK_ONCE { - manager.reset(); + /*manager.reset()*/; } } |